WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 11 Sep 2007 15:30:30 -0700
Delivery-date: Tue, 11 Sep 2007 15:32:43 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1189101915 21600
# Node ID 4ffca478e2f70a3f6674462cbe395560613ff5f2
# Parent  12be90e2f831f1ffabb5a568e5426263079f90ef
# Parent  32f331858d751f29b5970dd208c91e9dedea1182
merge with xen-unstable.hg (staging)
---
 tools/python/xen/util/security.py                                 | 1299 
-------
 xen/acm/Makefile                                                  |    5 
 xen/acm/acm_chinesewall_hooks.c                                   |  724 ----
 xen/acm/acm_core.c                                                |  392 --
 xen/acm/acm_null_hooks.c                                          |   95 
 xen/acm/acm_policy.c                                              |  876 ----
 xen/acm/acm_simple_type_enforcement_hooks.c                       |  914 -----
 xen/arch/x86/cpu/mtrr/centaur.c                                   |  223 -
 xen/arch/x86/cpu/rise.c                                           |   54 
 xen/common/acm_ops.c                                              |  212 -
 xen/include/acm/acm_core.h                                        |  196 -
 xen/include/acm/acm_endian.h                                      |   69 
 xen/include/acm/acm_hooks.h                                       |  353 -
 xen/include/public/acm.h                                          |  229 -
 xen/include/public/acm_ops.h                                      |  159 
 .hgignore                                                         |    3 
 Config.mk                                                         |   11 
 buildconfigs/mk.linux-2.6-xen                                     |   15 
 buildconfigs/src.hg-clone                                         |   14 
 buildconfigs/src.tarball                                          |    4 
 config/FreeBSD.mk                                                 |    1 
 config/x86_32.mk                                                  |    8 
 docs/misc/dump-core-format.txt                                    |   10 
 tools/Makefile                                                    |    1 
 tools/Rules.mk                                                    |    2 
 tools/blktap/drivers/tapdisk.c                                    |    4 
 tools/examples/blktap                                             |   65 
 tools/examples/block                                              |   42 
 tools/examples/block-common.sh                                    |   43 
 tools/examples/network-bridge                                     |    3 
 tools/firmware/hvmloader/smbios.c                                 |    4 
 tools/firmware/hvmloader/util.h                                   |    1 
 tools/firmware/rombios/rombios.c                                  |   11 
 tools/flask/Makefile                                              |   26 
 tools/flask/libflask/Makefile                                     |   65 
 tools/flask/libflask/flask_op.c                                   |  100 
 tools/flask/libflask/include/flask_op.h                           |   46 
 tools/flask/loadpolicy/Makefile                                   |   61 
 tools/flask/loadpolicy/loadpolicy.c                               |  130 
 tools/ioemu/Makefile.target                                       |    1 
 tools/ioemu/hw/cirrus_vga.c                                       |    7 
 tools/ioemu/hw/ide.c                                              |   12 
 tools/ioemu/hw/tpm_tis.c                                          |   24 
 tools/ioemu/target-i386-dm/exec-dm.c                              |   21 
 tools/ioemu/vl.h                                                  |   12 
 tools/libxc/xc_acm.c                                              |    2 
 tools/libxc/xc_core.c                                             |  467 +-
 tools/libxc/xc_core.h                                             |    8 
 tools/libxc/xc_core_ia64.c                                        |    4 
 tools/libxc/xc_core_ia64.h                                        |    1 
 tools/libxc/xc_core_powerpc.c                                     |    4 
 tools/libxc/xc_core_powerpc.h                                     |    1 
 tools/libxc/xc_core_x86.c                                         |    4 
 tools/libxc/xc_core_x86.h                                         |    1 
 tools/libxc/xc_domain.c                                           |    6 
 tools/libxc/xenctrl.h                                             |    4 
 tools/misc/xenperf.c                                              |    2 
 tools/python/Makefile                                             |   26 
 tools/python/setup.py                                             |   14 
 tools/python/xen/lowlevel/acm/acm.c                               |    5 
 tools/python/xen/lowlevel/flask/flask.c                           |  139 
 tools/python/xen/lowlevel/xc/xc.c                                 |    2 
 tools/python/xen/util/acmpolicy.py                                |    9 
 tools/python/xen/util/xsm/__init__.py                             |    2 
 tools/python/xen/util/xsm/acm/__init__.py                         |    1 
 tools/python/xen/util/xsm/acm/acm.py                              | 1319 
+++++++
 tools/python/xen/util/xsm/dummy/__init__.py                       |    1 
 tools/python/xen/util/xsm/dummy/dummy.py                          |   53 
 tools/python/xen/util/xsm/flask/__init__.py                       |    1 
 tools/python/xen/util/xsm/flask/flask.py                          |   37 
 tools/python/xen/util/xsm/xsm_core.py                             |    7 
 tools/python/xen/xend/XendCheckpoint.py                           |   31 
 tools/python/xen/xend/XendConfig.py                               |   18 
 tools/python/xen/xend/XendDomainInfo.py                           |   10 
 tools/python/xen/xend/XendVDI.py                                  |    3 
 tools/python/xen/xend/XendXSPolicy.py                             |    3 
 tools/python/xen/xend/XendXSPolicyAdmin.py                        |    3 
 tools/python/xen/xend/server/BlktapController.py                  |    8 
 tools/python/xen/xend/server/blkif.py                             |    2 
 tools/python/xen/xend/server/netif.py                             |    2 
 tools/python/xen/xm/addlabel.py                                   |    2 
 tools/python/xen/xm/cfgbootpolicy.py                              |   10 
 tools/python/xen/xm/create.py                                     |   11 
 tools/python/xen/xm/dry-run.py                                    |    2 
 tools/python/xen/xm/dumppolicy.py                                 |    2 
 tools/python/xen/xm/getlabel.py                                   |    6 
 tools/python/xen/xm/labels.py                                     |    6 
 tools/python/xen/xm/loadpolicy.py                                 |    2 
 tools/python/xen/xm/main.py                                       |   28 
 tools/python/xen/xm/makepolicy.py                                 |    2 
 tools/python/xen/xm/resources.py                                  |    2 
 tools/python/xen/xm/rmlabel.py                                    |    4 
 tools/python/xen/xm/setpolicy.py                                  |    2 
 tools/security/secpol_tool.c                                      |    4 
 tools/security/secpol_xml2bin.c                                   |    3 
 tools/xm-test/lib/XmTestLib/acm.py                                |    2 
 tools/xm-test/tests/security-acm/01_security-acm_basic.py         |    2 
 tools/xm-test/tests/security-acm/07_security-acm_pol_update.py    |    3 
 tools/xm-test/tests/security-acm/08_security-acm_xapi.py          |    3 
 tools/xm-test/tests/security-acm/09_security-acm_pol_update.py    |    3 
 unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h |   13 
 xen/Makefile                                                      |    6 
 xen/Rules.mk                                                      |    7 
 xen/arch/ia64/xen/domain.c                                        |   12 
 xen/arch/ia64/xen/mm.c                                            |   77 
 xen/arch/ia64/xen/xensetup.c                                      |    2 
 xen/arch/powerpc/domain.c                                         |    4 
 xen/arch/powerpc/setup.c                                          |    2 
 xen/arch/x86/cpu/Makefile                                         |    1 
 xen/arch/x86/cpu/centaur.c                                        |  380 --
 xen/arch/x86/cpu/common.c                                         |    2 
 xen/arch/x86/cpu/mtrr/Makefile                                    |    1 
 xen/arch/x86/cpu/mtrr/main.c                                      |    9 
 xen/arch/x86/domain.c                                             |  122 
 xen/arch/x86/domain_build.c                                       |   11 
 xen/arch/x86/domctl.c                                             |   74 
 xen/arch/x86/e820.c                                               |    9 
 xen/arch/x86/hvm/hvm.c                                            |   31 
 xen/arch/x86/hvm/irq.c                                            |   11 
 xen/arch/x86/hvm/svm/svm.c                                        |    1 
 xen/arch/x86/hvm/vioapic.c                                        |    2 
 xen/arch/x86/hvm/vlapic.c                                         |    2 
 xen/arch/x86/hvm/vmx/vmcs.c                                       |   12 
 xen/arch/x86/hvm/vmx/vmx.c                                        |    1 
 xen/arch/x86/mm.c                                                 |   39 
 xen/arch/x86/mm/hap/hap.c                                         |    2 
 xen/arch/x86/mm/paging.c                                          |   10 
 xen/arch/x86/mm/shadow/common.c                                   |  101 
 xen/arch/x86/mm/shadow/multi.c                                    |  114 
 xen/arch/x86/mm/shadow/private.h                                  |   10 
 xen/arch/x86/mm/shadow/types.h                                    |   21 
 xen/arch/x86/physdev.c                                            |   11 
 xen/arch/x86/platform_hypercall.c                                 |   32 
 xen/arch/x86/setup.c                                              |   82 
 xen/arch/x86/sysctl.c                                             |    5 
 xen/arch/x86/traps.c                                              |   11 
 xen/arch/x86/x86_32/entry.S                                       |    4 
 xen/arch/x86/x86_32/mm.c                                          |   15 
 xen/arch/x86/x86_32/xen.lds.S                                     |    2 
 xen/arch/x86/x86_64/compat/entry.S                                |    4 
 xen/arch/x86/x86_64/entry.S                                       |    5 
 xen/arch/x86/x86_64/mm.c                                          |    8 
 xen/common/Makefile                                               |    1 
 xen/common/domain.c                                               |   78 
 xen/common/domctl.c                                               |  112 
 xen/common/event_channel.c                                        |   53 
 xen/common/grant_table.c                                          |   54 
 xen/common/kernel.c                                               |    6 
 xen/common/kexec.c                                                |    5 
 xen/common/memory.c                                               |   25 
 xen/common/schedule.c                                             |    8 
 xen/common/sysctl.c                                               |   21 
 xen/common/vsprintf.c                                             |  236 +
 xen/common/xencomm.c                                              |  386 +-
 xen/common/xenoprof.c                                             |    5 
 xen/drivers/char/console.c                                        |    5 
 xen/include/asm-ia64/domain.h                                     |    4 
 xen/include/asm-ia64/mm.h                                         |    2 
 xen/include/asm-x86/cpufeature.h                                  |    1 
 xen/include/asm-x86/domain.h                                      |   18 
 xen/include/asm-x86/e820.h                                        |    1 
 xen/include/asm-x86/hvm/vcpu.h                                    |    3 
 xen/include/asm-x86/msr.h                                         |    7 
 xen/include/asm-x86/p2m.h                                         |    3 
 xen/include/asm-x86/paging.h                                      |   16 
 xen/include/asm-x86/processor.h                                   |    1 
 xen/include/asm-x86/spinlock.h                                    |    8 
 xen/include/asm-x86/system.h                                      |   28 
 xen/include/public/arch-x86/xen.h                                 |    3 
 xen/include/public/hvm/hvm_op.h                                   |    3 
 xen/include/public/xen.h                                          |    2 
 xen/include/public/xsm/acm.h                                      |  229 +
 xen/include/public/xsm/acm_ops.h                                  |  159 
 xen/include/public/xsm/flask_op.h                                 |   45 
 xen/include/xen/domain.h                                          |    2 
 xen/include/xen/hypercall.h                                       |   10 
 xen/include/xen/lib.h                                             |    4 
 xen/include/xen/sched.h                                           |    9 
 xen/include/xsm/acm/acm_core.h                                    |  196 +
 xen/include/xsm/acm/acm_endian.h                                  |   69 
 xen/include/xsm/acm/acm_hooks.h                                   |  349 +
 xen/include/xsm/xsm.h                                             |  537 ++
 xen/xsm/Makefile                                                  |    8 
 xen/xsm/acm/Makefile                                              |    7 
 xen/xsm/acm/acm_chinesewall_hooks.c                               |  723 ++++
 xen/xsm/acm/acm_core.c                                            |  402 ++
 xen/xsm/acm/acm_null_hooks.c                                      |   95 
 xen/xsm/acm/acm_ops.c                                             |  212 +
 xen/xsm/acm/acm_policy.c                                          |  876 ++++
 xen/xsm/acm/acm_simple_type_enforcement_hooks.c                   |  914 +++++
 xen/xsm/acm/acm_xsm_hooks.c                                       |   74 
 xen/xsm/dummy.c                                                   |  488 ++
 xen/xsm/flask/Makefile                                            |    7 
 xen/xsm/flask/avc.c                                               |  817 ++++
 xen/xsm/flask/flask_op.c                                          | 1079 ++++++
 xen/xsm/flask/hooks.c                                             | 1159 ++++++
 xen/xsm/flask/include/av_inherit.h                                |    1 
 xen/xsm/flask/include/av_perm_to_string.h                         |   99 
 xen/xsm/flask/include/av_permissions.h                            |  108 
 xen/xsm/flask/include/avc.h                                       |  106 
 xen/xsm/flask/include/avc_ss.h                                    |   14 
 xen/xsm/flask/include/class_to_string.h                           |   14 
 xen/xsm/flask/include/common_perm_to_string.h                     |    1 
 xen/xsm/flask/include/conditional.h                               |   22 
 xen/xsm/flask/include/flask.h                                     |   36 
 xen/xsm/flask/include/initial_sid_to_string.h                     |   18 
 xen/xsm/flask/include/objsec.h                                    |   33 
 xen/xsm/flask/include/security.h                                  |   83 
 xen/xsm/flask/ss/Makefile                                         |   11 
 xen/xsm/flask/ss/avtab.c                                          |  471 ++
 xen/xsm/flask/ss/avtab.h                                          |   85 
 xen/xsm/flask/ss/conditional.c                                    |  546 +++
 xen/xsm/flask/ss/conditional.h                                    |   77 
 xen/xsm/flask/ss/constraint.h                                     |   61 
 xen/xsm/flask/ss/context.h                                        |  110 
 xen/xsm/flask/ss/ebitmap.c                                        |  328 +
 xen/xsm/flask/ss/ebitmap.h                                        |   79 
 xen/xsm/flask/ss/hashtab.c                                        |  181 +
 xen/xsm/flask/ss/hashtab.h                                        |   85 
 xen/xsm/flask/ss/mls.c                                            |  612 +++
 xen/xsm/flask/ss/mls.h                                            |   37 
 xen/xsm/flask/ss/mls_types.h                                      |   58 
 xen/xsm/flask/ss/policydb.c                                       | 1798 
++++++++++
 xen/xsm/flask/ss/policydb.h                                       |  257 +
 xen/xsm/flask/ss/services.c                                       | 1657 
+++++++++
 xen/xsm/flask/ss/services.h                                       |   15 
 xen/xsm/flask/ss/sidtab.c                                         |  327 +
 xen/xsm/flask/ss/sidtab.h                                         |   53 
 xen/xsm/flask/ss/symtab.c                                         |   47 
 xen/xsm/flask/ss/symtab.h                                         |   23 
 xen/xsm/xsm_core.c                                                |  118 
 xen/xsm/xsm_policy.c                                              |   67 
 232 files changed, 20168 insertions(+), 7149 deletions(-)

diff -r 12be90e2f831 -r 4ffca478e2f7 .hgignore
--- a/.hgignore Thu Sep 06 09:05:26 2007 -0600
+++ b/.hgignore Thu Sep 06 12:05:15 2007 -0600
@@ -114,6 +114,7 @@
 ^tools/firmware/vmxassist/gen$
 ^tools/firmware/vmxassist/offsets\.h$
 ^tools/firmware/vmxassist/vmxassist$
+^tools/flask/loadpolicy/flask-loadpolicy$
 ^tools/ioemu/\.pc/.*$
 ^tools/ioemu/config-host\.h$
 ^tools/ioemu/config-host\.mak$
@@ -149,8 +150,10 @@
 ^tools/misc/xenperf$
 ^tools/pygrub/build/.*$
 ^tools/python/build/.*$
+^tools/python/xen/util/xsm/xsm\.py$
 ^tools/security/secpol_tool$
 ^tools/security/xen/.*$
+^tools/security/xensec_tool$
 ^tools/tests/blowfish\.bin$
 ^tools/tests/blowfish\.h$
 ^tools/tests/test_x86_emulator$
diff -r 12be90e2f831 -r 4ffca478e2f7 Config.mk
--- a/Config.mk Thu Sep 06 09:05:26 2007 -0600
+++ b/Config.mk Thu Sep 06 12:05:15 2007 -0600
@@ -20,6 +20,9 @@ HOSTCC      = gcc
 HOSTCC      = gcc
 HOSTCFLAGS  = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
 HOSTCFLAGS += -fno-strict-aliasing
+HOSTCFLAGS_x86_32 = -m32
+HOSTCFLAGS_x86_64 = -m64
+HOSTCFLAGS += $(HOSTCFLAGS_$(XEN_COMPILE_ARCH))
 
 DISTDIR     ?= $(XEN_ROOT)/dist
 DESTDIR     ?= /
@@ -75,10 +78,10 @@ LDFLAGS += $(foreach i, $(EXTRA_LIB), -L
 LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i)) 
 CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
 
-# If ACM_SECURITY = y, then the access control module is compiled
-# into Xen and the policy type can be set by the boot policy file
-#        y - Build the Xen ACM framework
-#        n - Do not build the Xen ACM framework
+# Enable XSM security module.  Enabling XSM requires selection of an 
+# XSM security module (FLASK_ENABLE or ACM_SECURITY).
+XSM_ENABLE ?= n
+FLASK_ENABLE ?= n
 ACM_SECURITY ?= n
 
 # Optional components
diff -r 12be90e2f831 -r 4ffca478e2f7 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Thu Sep 06 09:05:26 2007 -0600
+++ b/buildconfigs/mk.linux-2.6-xen     Thu Sep 06 12:05:15 2007 -0600
@@ -6,6 +6,16 @@ EXTRAVERSION ?= -xen
 # Linux search path, will be searched for tarballs and mercurial
 # repositories.
 LINUX_SRC_PATH ?= .:..
+
+# The source directory is not automatically updated to avoid blowing
+# away developer's changes. If you want to automatically pull a new
+# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
+# command line.
+ifeq ($(XEN_LINUX_UPDATE),y)
+__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
+else
+__XEN_LINUX_UPDATE =
+endif
 
 XEN_LINUX_SOURCE ?= hg-clone
 
@@ -115,6 +125,7 @@ endif
              echo "    \$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT) \$$@"; \
            ) > $(LINUX_DIR)/Makefile ; \
        fi
+       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) prepare
 
 .PHONY: prep
 prep: $(LINUX_DIR)/include/linux/autoconf.h
@@ -137,3 +148,7 @@ mrproper:
 mrproper:
        rm -rf $(LINUX_SRCDIR)
        rm -f linux-$(LINUX_VER).tar.bz2
+
+.PHONY: $(LINUX_SRCDIR)/.force-update
+$(LINUX_SRCDIR)/.force-update:
+       @ :
diff -r 12be90e2f831 -r 4ffca478e2f7 buildconfigs/src.hg-clone
--- a/buildconfigs/src.hg-clone Thu Sep 06 09:05:26 2007 -0600
+++ b/buildconfigs/src.hg-clone Thu Sep 06 12:05:15 2007 -0600
@@ -5,16 +5,6 @@ LINUX_SRCDIR ?= linux-$(LINUX_VER)-xen.h
 
 # Repository to clone.
 XEN_LINUX_HGREPO ?= $$(sh buildconfigs/select-repository $(LINUX_SRCDIR) 
$(LINUX_SRC_PATH))
-
-# The source directory is not automatically updated to avoid blowing
-# away developer's changes. If you want to automatically pull a new
-# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
-# command line.
-ifeq ($(XEN_LINUX_UPDATE),y)
-__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
-else
-__XEN_LINUX_UPDATE =
-endif
 
 # Set XEN_LINUX_HGREV to update to a particlar revision.
 XEN_LINUX_HGREV  ?= tip
@@ -40,7 +30,3 @@ XEN_LINUX_HGREV  ?= tip
            ( cd $(LINUX_SRCDIR) && $(HG) update $(XEN_LINUX_HGREV) ); \
        fi
        touch $@
-
-.PHONY: $(LINUX_SRCDIR)/.force-update
-$(LINUX_SRCDIR)/.force-update:
-       @ :
diff -r 12be90e2f831 -r 4ffca478e2f7 buildconfigs/src.tarball
--- a/buildconfigs/src.tarball  Thu Sep 06 09:05:26 2007 -0600
+++ b/buildconfigs/src.tarball  Thu Sep 06 12:05:15 2007 -0600
@@ -18,11 +18,11 @@ linux-%.tar.bz2:
 # XXX create a pristine tree for diff -Nurp convenience
 
 ifeq ($(XEN_LINUX_TARBALL_KETCHUP),y)
-%/.valid-src:
+%/.valid-src: $(__XEN_LINUX_UPDATE)
        $(KETCHUP) -d $(@D) $(LINUX_VER)
        touch $@ # update timestamp to avoid rebuild
 else
-%/.valid-src: %.tar.bz2
+%/.valid-src: $(__XEN_LINUX_UPDATE) %.tar.bz2
        rm -rf tmp-linux-$* $(@D)
        mkdir -p tmp-linux-$*
        tar -C tmp-linux-$* -jxf $<
diff -r 12be90e2f831 -r 4ffca478e2f7 config/FreeBSD.mk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/config/FreeBSD.mk Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,1 @@
+include $(XEN_ROOT)/config/StdGNU.mk
diff -r 12be90e2f831 -r 4ffca478e2f7 config/x86_32.mk
--- a/config/x86_32.mk  Thu Sep 06 09:05:26 2007 -0600
+++ b/config/x86_32.mk  Thu Sep 06 12:05:15 2007 -0600
@@ -11,8 +11,6 @@ LIBDIR := lib
 LIBDIR := lib
 
 # Use only if calling $(LD) directly.
-ifeq ($(XEN_OS),OpenBSD)
-LDFLAGS_DIRECT += -melf_i386_obsd
-else
-LDFLAGS_DIRECT += -melf_i386
-endif
+LDFLAGS_DIRECT_OpenBSD = _obsd
+LDFLAGS_DIRECT_FreeBSD = _fbsd
+LDFLAGS_DIRECT += -melf_i386$(LDFLAGS_DIRECT_$(XEN_OS))
diff -r 12be90e2f831 -r 4ffca478e2f7 docs/misc/dump-core-format.txt
--- a/docs/misc/dump-core-format.txt    Thu Sep 06 09:05:26 2007 -0600
+++ b/docs/misc/dump-core-format.txt    Thu Sep 06 12:05:15 2007 -0600
@@ -80,7 +80,10 @@ Currently the following sections are def
                         gmfn:   machine physical frame number
                 The size of arrays is stored in xch_nr_pages member of header
                 note descriptor in .note.Xen note section.
-                The entryies are stored in pfn-ascending order.
+                The entries are stored in pfn-ascending order.
+                The value, {~(uint64_t)0, ~(uint64_t)0}, means invalid
+                (pfn, gmfn) and the corresponding page has zero. There might
+                exist invalid (pfn, gmfn)'s at the end part of this array.
                 This section must exist when the domain is non auto
                 translated physmap mode. Currently x86 paravirtualized domain.
 
@@ -94,6 +97,9 @@ Currently the following sections are def
                 The size of arrays is stored in xch_nr_pages member of header
                 note descriptor in .note.Xen note section.
                 The entries are stored in ascending order.
+                The value, ~(uint64_t)0, means invalid pfn and the
+                corresponding page has zero. There might exist invalid
+                pfn's at the end part of this array.
                 This section must exist when the domain is auto translated
                 physmap mode. Currently x86 full virtualized domain and
                 ia64 domain.
@@ -225,6 +231,8 @@ Currently only (major, minor) = (0, 1) i
 
 (0, 1) update
 - .xen_p2m, .xen_pfn section
+  Invalid pfn/gmfn.
+- .xen_p2m, .xen_pfn section
   Arrays must be in pfn ascending order for efficient looking up.
 - EI_CLASS member of elf header was changed to ELFCLASS64 independent of
   architecture. This is mainly for x86_32pae.
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/Makefile
--- a/tools/Makefile    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/Makefile    Thu Sep 06 12:05:15 2007 -0600
@@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 SUBDIRS-y :=
 SUBDIRS-y += libxc
+SUBDIRS-y += flask
 SUBDIRS-y += xenstore
 SUBDIRS-y += misc
 SUBDIRS-y += examples
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/Rules.mk
--- a/tools/Rules.mk    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/Rules.mk    Thu Sep 06 12:05:15 2007 -0600
@@ -49,6 +49,8 @@ mk-symlinks:
        ( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
        mkdir -p xen/io
        ( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+       mkdir -p xen/xsm
+       ( cd xen/xsm && ln -sf ../../$(XEN_ROOT)/xen/include/public/xsm/*.h . )
        mkdir -p xen/arch-x86
        ( cd xen/arch-x86 && ln -sf 
../../$(XEN_ROOT)/xen/include/public/arch-x86/*.h . )
        mkdir -p xen/foreign
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/blktap/drivers/tapdisk.c    Thu Sep 06 12:05:15 2007 -0600
@@ -863,11 +863,7 @@ int main(int argc, char *argv[])
        ptr = fd_start;
        while (ptr != NULL) {
                s = ptr->s;
-
                unmap_disk(s);
-               free(s->blkif);
-               free(s->ring_info);
-               free(s);
                close(ptr->tap_fd);
                ptr = ptr->next;
        }
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/examples/blktap
--- a/tools/examples/blktap     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/examples/blktap     Thu Sep 06 12:05:15 2007 -0600
@@ -7,6 +7,57 @@ dir=$(dirname "$0")
 . "$dir/block-common.sh"
 
 findCommand "$@"
+
+##
+# check_blktap_sharing file mode
+#
+# Perform the sharing check for the given blktap and mode.
+#
+check_blktap_sharing()
+{
+    local file="$1"
+    local mode="$2"
+
+    local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE"
+    for dom in $(xenstore-list "$base_path")
+    do
+        for dev in $(xenstore-list "$base_path/$dom")
+        do
+            params=$(xenstore_read "$base_path/$dom/$dev/params" | cut -d: -f2)
+            if [ "$file" = "$params" ]
+            then
+
+                if [ "$mode" = 'w' ]
+                then
+                    if ! same_vm "$dom" 
+                    then
+                        echo 'guest'
+                        return
+                    fi
+                else 
+                    local m=$(xenstore_read "$base_path/$dom/$dev/mode")
+                    m=$(canonicalise_mode "$m")
+
+                    if [ "$m" = 'w' ] 
+                    then
+                        if ! same_vm "$dom"
+                        then
+                            echo 'guest'
+                            return
+                        fi
+                    fi
+                fi
+            fi
+        done
+    done
+
+    echo 'ok'
+}
+
+FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
+FRONTEND_UUID=$(xenstore_read "/local/domain/$FRONTEND_ID/vm")
+mode=$(xenstore_read "$XENBUS_PATH/mode")
+mode=$(canonicalise_mode "$mode")
 
 t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
 if [ -n "$t" ]
@@ -18,7 +69,19 @@ then
         p=${p#*:}
     fi
 fi
-file=$(readlink -f "$p") || ebusy "$p does not exist."
+# some versions of readlink cannot be passed a regular file
+if [ -L "$p" ]; then
+    file=$(readlink -f "$p") || ebusy "$p link does not exist."
+else
+    [ -f "$p" ] || { ebusy "$p file does not exist." }
+    file="$p"
+fi
+
+if [ "$mode" != '!' ] 
+then
+    result=$(check_blktap_sharing "$file" "$mode")
+    [ "$result" = 'ok' ] || ebusy "$file already in use by other domain"
+fi
 
 if [ "$command" = 'add' ]
 then
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/examples/block
--- a/tools/examples/block      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/examples/block      Thu Sep 06 12:05:15 2007 -0600
@@ -14,32 +14,6 @@ expand_dev() {
     ;;
   esac
   echo -n $dev
-}
-
-
-##
-# canonicalise_mode mode
-#
-# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
-# thereof, and canonicalises them to one of
-#
-#   'r': perform checks for a new read-only mount;
-#   'w': perform checks for a read-write mount; or
-#   '!': perform no checks at all.
-#
-canonicalise_mode()
-{
-  local mode="$1"
-
-  if ! expr index "$mode" 'w' >/dev/null
-  then
-    echo 'r'
-  elif ! expr index "$mode" '!' >/dev/null
-  then
-    echo 'w'
-  else
-    echo '!'
-  fi
 }
 
 
@@ -123,22 +97,6 @@ check_sharing()
   done
 
   echo 'ok'
-}
-
-
-same_vm()
-{
-  local otherdom="$1"
-  # Note that othervm can be MISSING here, because Xend will be racing with
-  # the hotplug scripts -- the entries in /local/domain can be removed by
-  # Xend before the hotplug scripts have removed the entry in
-  # /local/domain/0/backend/.  In this case, we want to pretend that the
-  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
-  # allowed.
-  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
-                  "$FRONTEND_UUID")
-
-  [ "$FRONTEND_UUID" = "$othervm" ]
 }
 
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/examples/block-common.sh
--- a/tools/examples/block-common.sh    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/examples/block-common.sh    Thu Sep 06 12:05:15 2007 -0600
@@ -71,3 +71,46 @@ write_dev() {
 
   success
 }
+
+
+##
+# canonicalise_mode mode
+#
+# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
+# thereof, and canonicalises them to one of
+#
+#   'r': perform checks for a new read-only mount;
+#   'w': perform checks for a read-write mount; or
+#   '!': perform no checks at all.
+#
+canonicalise_mode()
+{
+  local mode="$1"
+
+  if ! expr index "$mode" 'w' >/dev/null
+  then
+    echo 'r'
+  elif ! expr index "$mode" '!' >/dev/null
+  then
+    echo 'w'
+  else
+    echo '!'
+  fi
+}
+
+
+same_vm()
+{
+  local otherdom="$1"
+  # Note that othervm can be MISSING here, because Xend will be racing with
+  # the hotplug scripts -- the entries in /local/domain can be removed by
+  # Xend before the hotplug scripts have removed the entry in
+  # /local/domain/0/backend/.  In this case, we want to pretend that the
+  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
+  # allowed.
+  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
+                  "$FRONTEND_UUID")
+
+  [ "$FRONTEND_UUID" = "$othervm" ]
+}
+
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/examples/network-bridge
--- a/tools/examples/network-bridge     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/examples/network-bridge     Thu Sep 06 12:05:15 2007 -0600
@@ -259,7 +259,8 @@ add_to_bridge2() {
        fi
     done
 
-    if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi
+    if [ ${i} -eq ${maxtries} ] ; then echo -n '(link isnt in running state)' 
; fi
+    echo
 
     add_to_bridge ${bridge} ${dev}
 }
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/firmware/hvmloader/smbios.c Thu Sep 06 12:05:15 2007 -0600
@@ -159,8 +159,7 @@ int
 int
 hvm_write_smbios_tables(void)
 {
-    uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
-                         not uint8_t[16]. ** */
+    xen_domain_handle_t uuid;
     uint16_t xen_major_version, xen_minor_version;
     uint32_t xen_version;
     char xen_extra_version[XEN_EXTRAVERSION_LEN];
@@ -173,6 +172,7 @@ hvm_write_smbios_tables(void)
     unsigned tmp_len; /* length of next string to add */
 
     hypercall_xen_version(XENVER_guest_handle, uuid);
+    BUILD_BUG_ON(sizeof(xen_domain_handle_t) != 16);
 
     /* xen_version major and minor */
     xen_version = hypercall_xen_version(XENVER_version, NULL);
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/firmware/hvmloader/util.h   Thu Sep 06 12:05:15 2007 -0600
@@ -17,6 +17,7 @@ extern void __bug(char *file, int line) 
 extern void __bug(char *file, int line) __attribute__((noreturn));
 #define BUG() __bug(__FILE__, __LINE__)
 #define BUG_ON(p) do { if (p) BUG(); } while (0)
+#define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
 
 /* I/O output */
 void outb(uint16_t addr, uint8_t  val);
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/firmware/rombios/rombios.c  Thu Sep 06 12:05:15 2007 -0600
@@ -1057,7 +1057,7 @@ static char CVSID[] = "$Id: rombios.c,v 
 #define UNSUPPORTED_FUNCTION 0x86
 
 #define none 0
-#define MAX_SCAN_CODE 0x53
+#define MAX_SCAN_CODE 0x58
 
 static struct {
   Bit16u normal;
@@ -1149,7 +1149,12 @@ static struct {
       { 0x5000, 0x5032,   none,   none, 0x20 }, /* 2 Down */
       { 0x5100, 0x5133, 0x7600,   none, 0x20 }, /* 3 PgDn */
       { 0x5200, 0x5230,   none,   none, 0x20 }, /* 0 Ins */
-      { 0x5300, 0x532e,   none,   none, 0x20 }  /* Del */
+      { 0x5300, 0x532e,   none,   none, 0x20 }, /* Del */
+      {   none,   none,   none,   none, none }, /* ??? */
+      {   none,   none,   none,   none, none }, /* ??? */
+      {   none,   none,   none,   none, none }, /* ??? */
+      { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */
+      { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */
       };
 
   Bit8u
@@ -4682,7 +4687,7 @@ int09_function(DI, SI, BP, SP, BX, DX, C
     default:
       if (scancode & 0x80) return; /* toss key releases ... */
       if (scancode > MAX_SCAN_CODE) {
-        BX_INFO("KBD: int09h_handler(): unknown scancode read!\n");
+        BX_INFO("KBD: int09h_handler(): unknown scancode (%x) read!\n", 
scancode);
         return;
         }
       if (shift_flags & 0x08) { /* ALT */
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/Makefile      Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,26 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+SUBDIRS :=
+SUBDIRS += libflask
+SUBDIRS += loadpolicy
+
+.PHONY: all
+all:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+.PHONY: install
+install:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+.PHONY: clean
+clean:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/libflask/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/libflask/Makefile     Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,65 @@
+MAJOR    = 1.0
+MINOR    = 0
+
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+XEN_LIBXC = $(XEN_ROOT)/tools/libxc
+
+SRCS       :=
+SRCS       += flask_op.c
+
+CFLAGS   += -Werror
+CFLAGS   += -fno-strict-aliasing
+CFLAGS   += $(INCLUDES) -I./include -I$(XEN_LIBXC) 
+
+# Get gcc to generate the dependencies for us.
+CFLAGS   += -Wp,-MD,.$(@F).d
+LDFLAGS  += -L.
+DEPS     = .*.d
+
+LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
+PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
+
+LIB := libflask.a
+LIB += libflask.so libflask.so.$(MAJOR) libflask.so.$(MAJOR).$(MINOR)
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+       $(MAKE) $(LIB)
+
+.PHONY: install
+install: build
+       [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) 
$(DESTDIR)/usr/$(LIBDIR)
+       [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include
+       $(INSTALL_PROG) libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
+       $(INSTALL_DATA) libflask.a $(DESTDIR)/usr/$(LIBDIR)
+       ln -sf libflask.so.$(MAJOR).$(MINOR) 
$(DESTDIR)/usr/$(LIBDIR)/libflask.so.$(MAJOR)
+       ln -sf libflask.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so
+       $(INSTALL_DATA) include/flask_op.h $(DESTDIR)/usr/include
+
+.PHONY: TAGS
+TAGS:
+       etags -t *.c *.h
+
+.PHONY: clean
+clean:
+       rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen
+
+# libflask
+
+libflask.a: $(LIB_OBJS)
+       $(AR) rc $@ $^
+
+libflask.so: libflask.so.$(MAJOR)
+       ln -sf $< $@
+libflask.so.$(MAJOR): libflask.so.$(MAJOR).$(MINOR)
+       ln -sf $< $@
+
+libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libflask.so.$(MAJOR) -shared 
-o $@ $^
+
+-include $(DEPS)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/libflask/flask_op.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/libflask/flask_op.c   Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,100 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
+ *            George Coker, <gscoker@xxxxxxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2,
+ *  as published by the Free Software Foundation.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+
+#include <xc_private.h>
+
+#include <flask_op.h>
+
+int flask_load(int xc_handle, char *buf, int size)
+{
+    int err;
+    flask_op_t op;
+    
+    op.cmd = FLASK_LOAD;
+    op.buf = buf;
+    op.size = size;
+    
+    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
+        return err;
+
+    return 0;
+}
+
+int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid)
+{
+    int err;
+    flask_op_t op;
+    
+    op.cmd = FLASK_CONTEXT_TO_SID;
+    op.buf = buf;
+    op.size = size;
+    
+    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
+        return err;
+    
+    sscanf(buf, "%u", sid);
+
+    return 0;
+}
+
+int flask_sid_to_context(int xc_handle, int sid, char *buf, int size)
+{
+    int err;
+    flask_op_t op;
+    
+    op.cmd = FLASK_SID_TO_CONTEXT;
+    op.buf = buf;
+    op.size = size;
+    
+    snprintf(buf, size, "%u", sid);
+
+    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
+        return err;
+
+    return 0;
+}
+
+int do_flask_op(int xc_handle, flask_op_t *op)
+{
+    int ret = -1;
+    DECLARE_HYPERCALL;
+
+    hypercall.op     = __HYPERVISOR_xsm_op;
+    hypercall.arg[0] = (unsigned long)op;
+
+    if ( mlock(op, sizeof(*op)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+        if ( errno == EACCES )
+            fprintf(stderr, "XSM operation failed!\n");
+    }
+
+    safe_munlock(op, sizeof(*op));
+
+ out:
+    return ret;
+}
+
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/libflask/include/flask_op.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/libflask/include/flask_op.h   Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,46 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
+ *            George Coker, <gscoker@xxxxxxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2,
+ *  as published by the Free Software Foundation.
+ */
+
+#ifndef __FLASK_OP_H
+#define __FLASK_OP_H
+
+#define FLASK_LOAD              1
+#define FLASK_GETENFORCE        2
+#define FLASK_SETENFORCE        3
+#define FLASK_CONTEXT_TO_SID    4
+#define FLASK_SID_TO_CONTEXT    5
+#define FLASK_ACCESS            6
+#define FLASK_CREATE            7
+#define FLASK_RELABEL           8
+#define FLASK_USER              9
+#define FLASK_POLICYVERS        10
+#define FLASK_GETBOOL           11
+#define FLASK_SETBOOL           12
+#define FLASK_COMMITBOOLS       13
+#define FLASK_MLS               14
+#define FLASK_DISABLE           15
+#define FLASK_GETAVC_THRESHOLD  16
+#define FLASK_SETAVC_THRESHOLD  17
+#define FLASK_AVC_HASHSTATS     18
+#define FLASK_AVC_CACHESTATS    19
+#define FLASK_MEMBER            20
+
+typedef struct flask_op {
+    int   cmd;
+    int   size;
+    char *buf;
+} flask_op_t;
+
+int flask_load(int xc_handle, char *buf, int size);
+int flask_context_to_sid(int xc_handle, char *buf, int size, u_int32_t *sid);
+int flask_sid_to_context(int xc_handle, int sid, char *buf, int size);
+int do_flask_op(int xc_handle, flask_op_t *op);
+
+#endif
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/loadpolicy/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/loadpolicy/Makefile   Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,61 @@
+XEN_ROOT=../../..
+include $(XEN_ROOT)/tools/Rules.mk
+XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
+
+INSTALL         = install
+INSTALL_DATA    = $(INSTALL) -m0644
+INSTALL_PROG    = $(INSTALL) -m0755
+INSTALL_DIR     = $(INSTALL) -d -m0755
+
+LIBXC_ROOT = $(XEN_ROOT)/tools/libxc
+LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask
+
+PROFILE=#-pg
+BASECFLAGS=-Wall -g -Werror
+# Make gcc generate dependencies.
+BASECFLAGS += -Wp,-MD,.$(@F).d
+PROG_DEP = .*.d
+BASECFLAGS+= $(PROFILE)
+#BASECFLAGS+= -I$(XEN_ROOT)/tools
+BASECFLAGS+= -I$(LIBXC_ROOT)
+BASECFLAGS+= -I$(LIBFLASK_ROOT)/include
+BASECFLAGS+= -I.
+
+CFLAGS  += $(BASECFLAGS)
+LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT)
+TESTDIR  = testsuite/tmp
+TESTFLAGS= -DTESTING
+TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
+
+CLIENTS := flask-loadpolicy
+CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS))
+
+.PHONY: all
+all: $(CLIENTS)
+
+$(CLIENTS): flask-%: %.o
+       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lflask -lxenctrl -o $@
+
+.PHONY: clean
+clean: 
+       rm -f *.o *.opic *.so
+       rm -f $(CLIENTS)
+       $(RM) $(PROG_DEP)
+
+.PHONY: print-dir
+print-dir:
+       @echo -n tools/flask/loadpolicy: 
+
+.PHONY: print-end
+print-end:
+       @echo
+
+.PHONY: install
+install: all
+       $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
+       $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/sbin
+
+-include $(PROG_DEP)
+
+# never delete any intermediate files.
+.SECONDARY:
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/flask/loadpolicy/loadpolicy.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/flask/loadpolicy/loadpolicy.c       Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,130 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
+ *            George Coker, <gscoker@xxxxxxxxxxxxxx>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License version 2,
+ *      as published by the Free Software Foundation.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <xenctrl.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <flask_op.h>
+
+#define USE_MMAP
+
+static void usage (int argCnt, const char *args[])
+{
+    fprintf(stderr, "Usage: %s <policy.file>\n", args[0]);
+    exit(1);
+}
+
+int main (int argCnt, const char *args[])
+{
+    const char *polFName;
+    int polFd = 0;
+    void *polMem = NULL;
+    void *polMemCp = NULL;
+    struct stat info;
+    int ret;
+    int xch = 0;
+
+    if (argCnt != 2)
+        usage(argCnt, args);
+
+    polFName = args[1];
+    polFd = open(polFName, O_RDONLY);
+    if ( polFd < 0 )
+    {
+        fprintf(stderr, "Error occurred opening policy file '%s': %s\n",
+                polFName, strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+    
+    ret = stat(polFName, &info);
+    if ( ret < 0 )
+    {
+        fprintf(stderr, "Error occurred retrieving information about"
+                "policy file '%s': %s\n", polFName, strerror(errno));
+        goto cleanup;
+    }
+
+    polMemCp = malloc(info.st_size);
+
+#ifdef USE_MMAP
+    polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0);
+    if ( !polMem )
+    {
+        fprintf(stderr, "Error occurred mapping policy file in memory: %s\n",
+                strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+
+    xch = xc_interface_open();
+    if ( xch < 0 )
+    {
+        fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
+                strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+
+    memcpy(polMemCp, polMem, info.st_size);
+#else
+    ret = read(polFd, polMemCp, info.st_size);
+    if ( ret < 0 )
+    {
+        fprintf(stderr, "Unable to read new Flask policy file: %s\n",
+                strerror(errno));
+        goto cleanup;
+    }
+    else
+    {
+        printf("Read %d bytes from policy file '%s'.\n", ret, polFName);
+    }
+#endif
+
+    ret = flask_load(xch, polMemCp, info.st_size);
+    if ( ret < 0 )
+    {
+        errno = -ret;
+        fprintf(stderr, "Unable to load new Flask policy: %s\n",
+                strerror(errno));
+        ret = -1;
+        goto cleanup;
+    }
+    else
+    {
+        printf("Successfully loaded policy.\n");
+    }
+
+done:
+    if ( polMemCp )
+        free(polMemCp);
+    if ( polMem )
+    {
+        ret = munmap(polMem, info.st_size);
+        if ( ret < 0 )
+            fprintf(stderr, "Unable to unmap policy memory: %s\n", 
strerror(errno));
+    }
+    if ( polFd )
+        close(polFd);
+    if ( xch )
+        xc_interface_close(xch);
+
+    return ret;
+
+cleanup:
+    goto done;
+}
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/Makefile.target       Thu Sep 06 12:05:15 2007 -0600
@@ -197,7 +197,6 @@ LIBS+=-lm
 LIBS+=-lm
 LIBS+=-L../../libxc -lxenctrl -lxenguest
 LIBS+=-L../../xenstore -lxenstore
-LIBS+=-lpthread
 ifndef CONFIG_USER_ONLY
 LIBS+=-lz
 endif
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/hw/cirrus_vga.c       Thu Sep 06 12:05:15 2007 -0600
@@ -2559,7 +2559,11 @@ static void *set_vram_mapping(unsigned l
     for (i = 0; i < nr_extents; i++)
         extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
 
-    set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
+    if (set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start) < 0) {
+        fprintf(logfile, "Failed set_mm_mapping\n");
+        free(extent_start);
+        return NULL;
+    }
 
     vram_pointer = xc_map_foreign_batch(xc_handle, domid,
                                         PROT_READ|PROT_WRITE,
@@ -2567,6 +2571,7 @@ static void *set_vram_mapping(unsigned l
     if (vram_pointer == NULL) {
         fprintf(logfile, "xc_map_foreign_batch vgaram returned error %d\n",
                 errno);
+        free(extent_start);
         return NULL;
     }
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/hw/ide.c      Thu Sep 06 12:05:15 2007 -0600
@@ -1876,6 +1876,9 @@ static void ide_ioport_write(void *opaqu
                 break;
             case 0xaa: /* read look-ahead enable */
             case 0x55: /* read look-ahead disable */
+            case 0x42: /* EN_AAM: enable Automatic Acoustic Mode */
+            case 0xc2: /* DIS_AAM: disable Automatic Acoustic Mode */
+            case 0x85: /* DIS_APM: disable APM */
                 s->status = READY_STAT | SEEK_STAT;
                 ide_set_irq(s);
                 break;
@@ -1914,8 +1917,15 @@ static void ide_ioport_write(void *opaqu
            s->status = READY_STAT;
             ide_set_irq(s);
             break;
-       case WIN_STANDBYNOW1:
         case WIN_IDLEIMMEDIATE:
+        case WIN_STANDBY:
+        case WIN_SETIDLE1:
+        case WIN_STANDBYNOW1:
+        case WIN_SLEEPNOW1:
+        case WIN_STANDBY2:
+        case WIN_SETIDLE2:
+        case WIN_STANDBYNOW2:
+        case WIN_SLEEPNOW2:
            s->status = READY_STAT;
             ide_set_irq(s);
             break;
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/hw/tpm_tis.c
--- a/tools/ioemu/hw/tpm_tis.c  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/hw/tpm_tis.c  Thu Sep 06 12:05:15 2007 -0600
@@ -154,16 +154,16 @@ static int has_channel_local_socket(tpmS
 #define NUM_TRANSPORTS 1
 
 struct vTPM_transmit {
-    int (*open) (tpmState *s, uint32_t vtpm_instance);
-    int (*write) (tpmState *s, const tpmBuffer *);
-    int (*read) (tpmState *s, tpmBuffer *);
-    int (*close) (tpmState *s, int);
+    int (*open_fn) (tpmState *s, uint32_t vtpm_instance);
+    int (*write_fn) (tpmState *s, const tpmBuffer *);
+    int (*read_fn) (tpmState *s, tpmBuffer *);
+    int (*close_fn) (tpmState *s, int);
     int (*has_channel) (tpmState *s);
 } vTPMTransmit[NUM_TRANSPORTS] = {
-    { .open = create_local_socket,
-      .write = write_local_socket,
-      .read = read_local_socket,
-      .close = close_local_socket,
+    { .open_fn = create_local_socket,
+      .write_fn = write_local_socket,
+      .read_fn = read_local_socket,
+      .close_fn = close_local_socket,
       .has_channel = has_channel_local_socket,
     }
 };
@@ -200,7 +200,7 @@ static void open_vtpm_channel(tpmState *
     int idx;
     /* search a usable transmit layer */
     for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
-        if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) {
+        if (1 == vTPMTransmit[idx].open_fn(s, s->vtpm_instance)) {
             /* found one */
             s->Transmitlayer = idx;
             break;
@@ -213,7 +213,7 @@ static void open_vtpm_channel(tpmState *
  */
 static inline void close_vtpm_channel(tpmState *s, int force)
 {
-    if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) {
+    if (1 == vTPMTransmit[s->Transmitlayer].close_fn(s, force)) {
         s->Transmitlayer = -1;
     }
 }
@@ -974,7 +974,7 @@ static int TPM_Send(tpmState *s, tpmBuff
     buffer->instance[0] &= 0x1f;
     buffer->instance[0] |= (locty << 5);
 
-    len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
+    len = vTPMTransmit[s->Transmitlayer].write_fn(s, buffer);
     if (len < 0) {
         s->Transmitlayer = -1;
     }
@@ -990,7 +990,7 @@ static int TPM_Receive(tpmState *s, tpmB
 {
     int off;
 
-    off = vTPMTransmit[s->Transmitlayer].read(s, buffer);
+    off = vTPMTransmit[s->Transmitlayer].read_fn(s, buffer);
 
     if (off < 0) {
         /* EAGAIN is set in errno due to non-blocking mode */
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Thu Sep 06 12:05:15 2007 -0600
@@ -125,17 +125,10 @@ FILE *logfile;
 FILE *logfile;
 int loglevel;
 
-#ifdef MAPCACHE
-pthread_mutex_t mapcache_mutex;
-#endif
-
 void cpu_exec_init(CPUState *env)
 {
     CPUState **penv;
     int cpu_index;
-#ifdef MAPCACHE
-    pthread_mutexattr_t mxattr; 
-#endif
 
     env->next_cpu = NULL;
     penv = &first_cpu;
@@ -149,14 +142,6 @@ void cpu_exec_init(CPUState *env)
 
     /* alloc dirty bits array */
     phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
-
-#ifdef MAPCACHE
-    /* setup memory access mutex to protect mapcache */
-    pthread_mutexattr_init(&mxattr); 
-    pthread_mutexattr_settype(&mxattr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&mapcache_mutex, &mxattr); 
-    pthread_mutexattr_destroy(&mxattr); 
-#endif
 }
 
 /* enable or disable low levels log */
@@ -470,6 +455,12 @@ static void memcpy_words(void *dst, void
 #else
 static void memcpy_words(void *dst, void *src, size_t n)
 {
+    /* Some architectures do not like unaligned accesses. */
+    if (((unsigned long)dst | (unsigned long)src) & 3) {
+        memcpy(dst, src, n);
+        return;
+    }
+
     while (n >= sizeof(uint32_t)) {
         *((uint32_t *)dst) = *((uint32_t *)src);
         dst = ((uint32_t *)dst) + 1;
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/ioemu/vl.h  Thu Sep 06 12:05:15 2007 -0600
@@ -160,25 +160,15 @@ extern FILE *logfile;
 
 
 #if defined(__i386__) || defined(__x86_64__)
-
 #define MAPCACHE
-
 uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
 void     qemu_invalidate_map_cache(void);
-
-#include <pthread.h>
-extern  pthread_mutex_t mapcache_mutex;
-#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
-#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
-
 #else 
-
 #define qemu_invalidate_map_cache() ((void)0)
+#endif
 
 #define mapcache_lock()   ((void)0)
 #define mapcache_unlock() ((void)0)
-
-#endif
 
 extern int xc_handle;
 extern int domid;
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_acm.c
--- a/tools/libxc/xc_acm.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_acm.c      Thu Sep 06 12:05:15 2007 -0600
@@ -81,7 +81,7 @@ int xc_acm_op(int xc_handle, int cmd, vo
     acmctl.cmd = cmd;
     acmctl.interface_version = ACM_INTERFACE_VERSION;
 
-    hypercall.op = __HYPERVISOR_acm_op;
+    hypercall.op = __HYPERVISOR_xsm_op;
     hypercall.arg[0] = (unsigned long)&acmctl;
     if ( lock_pages(&acmctl, sizeof(acmctl)) != 0)
     {
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core.c     Thu Sep 06 12:05:15 2007 -0600
@@ -17,8 +17,8 @@
  *  |    .xen_prstatus                                       |
  *  |    .xen_ia64_mmapped_regs if ia64                      |
  *  |    .xen_shared_info if present                         |
+ *  |    .xen_pages                                          |
  *  |    .xen_p2m or .xen_pfn                                |
- *  |    .xen_pages                                          |
  *  +--------------------------------------------------------+
  *  |.note.Xen:note section                                  |
  *  |    "Xen" is used as note name,                         |
@@ -37,12 +37,12 @@
  *  +--------------------------------------------------------+
  *  |.xen_shared_info if possible                            |
  *  +--------------------------------------------------------+
+ *  |.xen_pages                                              |
+ *  |    page * nr_pages                                     |
+ *  +--------------------------------------------------------+
  *  |.xen_p2m or .xen_pfn                                    |
  *  |    .xen_p2m: struct xen_dumpcore_p2m[nr_pages]         |
  *  |    .xen_pfn: uint64_t[nr_pages]                        |
- *  +--------------------------------------------------------+
- *  |.xen_pages                                              |
- *  |    page * nr_pages                                     |
  *  +--------------------------------------------------------+
  *  |.shstrtab: section header string table                  |
  *  +--------------------------------------------------------+
@@ -57,21 +57,6 @@
 
 /* number of pages to write at a time */
 #define DUMP_INCREMENT (4 * 1024)
-
-static int
-copy_from_domain_page(int xc_handle,
-                      uint32_t domid,
-                      unsigned long mfn,
-                      void *dst_page)
-{
-    void *vaddr = xc_map_foreign_range(
-        xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
-    if ( vaddr == NULL )
-        return -1;
-    memcpy(dst_page, vaddr, PAGE_SIZE);
-    munmap(vaddr, PAGE_SIZE);
-    return 0;
-}
 
 /* string table */
 struct xc_core_strtab {
@@ -231,6 +216,35 @@ xc_core_shdr_set(Elf64_Shdr *shdr,
     return 0;
 }
 
+static void
+xc_core_ehdr_init(Elf64_Ehdr *ehdr)
+{
+    memset(ehdr, 0, sizeof(*ehdr));
+    ehdr->e_ident[EI_MAG0] = ELFMAG0;
+    ehdr->e_ident[EI_MAG1] = ELFMAG1;
+    ehdr->e_ident[EI_MAG2] = ELFMAG2;
+    ehdr->e_ident[EI_MAG3] = ELFMAG3;
+    ehdr->e_ident[EI_CLASS] = ELFCLASS64;
+    ehdr->e_ident[EI_DATA] = ELF_ARCH_DATA;
+    ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+    ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
+    ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT;
+
+    ehdr->e_type = ET_CORE;
+    ehdr->e_machine = ELF_ARCH_MACHINE;
+    ehdr->e_version = EV_CURRENT;
+    ehdr->e_entry = 0;
+    ehdr->e_phoff = 0;
+    ehdr->e_shoff = sizeof(*ehdr);
+    ehdr->e_flags = ELF_CORE_EFLAGS;
+    ehdr->e_ehsize = sizeof(*ehdr);
+    ehdr->e_phentsize = sizeof(Elf64_Phdr);
+    ehdr->e_phnum = 0;
+    ehdr->e_shentsize = sizeof(Elf64_Shdr);
+    /* ehdr->e_shnum and ehdr->e_shstrndx aren't known here yet.
+     * fill it later */
+}
+
 static int
 elfnote_fill_xen_version(int xc_handle,
                          struct xen_dumpcore_elfnote_xen_version_desc
@@ -277,12 +291,100 @@ elfnote_fill_xen_version(int xc_handle,
     return 0;
 }
 
-static int
+static void
 elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
                             *format_version)
 {
     format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
-    return 0;
+}
+
+static void
+elfnote_init(struct elfnote *elfnote)
+{
+    /* elf note section */
+    memset(elfnote, 0, sizeof(*elfnote));
+    elfnote->namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
+    strncpy(elfnote->name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote->name));
+}
+
+static int
+elfnote_dump_none(void *args, dumpcore_rtn_t dump_rtn)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_none_desc none;
+
+    elfnote_init(&elfnote);
+    memset(&none, 0, sizeof(none));
+
+    elfnote.descsz = sizeof(none);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(args, (char*)&none, sizeof(none));
+}
+
+static int
+elfnote_dump_core_header(
+    void *args, dumpcore_rtn_t dump_rtn, const xc_dominfo_t *info,
+    int nr_vcpus, unsigned long nr_pages)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_header_desc header;
+    
+    elfnote_init(&elfnote);
+    memset(&header, 0, sizeof(header));
+    
+    elfnote.descsz = sizeof(header);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
+    header.xch_magic = info->hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
+    header.xch_nr_vcpus = nr_vcpus;
+    header.xch_nr_pages = nr_pages;
+    header.xch_page_size = PAGE_SIZE;
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(args, (char*)&header, sizeof(header));
+}
+
+static int
+elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int xc_handle)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
+
+    elfnote_init(&elfnote);
+    memset(&xen_version, 0, sizeof(xen_version));
+
+    elfnote.descsz = sizeof(xen_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
+    elfnote_fill_xen_version(xc_handle, &xen_version);
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
+}
+
+static int
+elfnote_dump_format_version(void *args, dumpcore_rtn_t dump_rtn)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_format_version_desc format_version;
+
+    elfnote_init(&elfnote);
+    memset(&format_version, 0, sizeof(format_version));
+    
+    elfnote.descsz = sizeof(format_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
+    elfnote_fill_format_version(&format_version);
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(args, (char*)&format_version, sizeof(format_version));
 }
 
 int
@@ -327,13 +429,6 @@ xc_domain_dumpcore_via_callback(int xc_h
     struct xc_core_section_headers *sheaders = NULL;
     Elf64_Shdr *shdr;
 
-    /* elf notes */
-    struct elfnote elfnote;
-    struct xen_dumpcore_elfnote_none_desc none;
-    struct xen_dumpcore_elfnote_header_desc header;
-    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
-    struct xen_dumpcore_elfnote_format_version_desc format_version;
-
     xc_core_arch_context_init(&arch_ctxt);
     if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
     {
@@ -379,8 +474,9 @@ xc_domain_dumpcore_via_callback(int xc_h
     }
 
     /* obtain memory map */
-    sts = xc_core_arch_memory_map_get(xc_handle, &info, live_shinfo,
-                                      &memory_map, &nr_memory_map);
+    sts = xc_core_arch_memory_map_get(xc_handle, &arch_ctxt, &info,
+                                      live_shinfo, &memory_map,
+                                      &nr_memory_map);
     if ( sts != 0 )
         goto out;
 
@@ -410,70 +506,8 @@ xc_domain_dumpcore_via_callback(int xc_h
         }
     }
 
-    /* create .xen_p2m or .xen_pfn */
-    j = 0;
-    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
-    {
-        uint64_t pfn_start;
-        uint64_t pfn_end;
-
-        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
-        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
-        for ( i = pfn_start; i < pfn_end; i++ )
-        {
-            if ( !auto_translated_physmap )
-            {
-                if ( p2m[i] == INVALID_P2M_ENTRY )
-                    continue;
-                p2m_array[j].pfn = i;
-                p2m_array[j].gmfn = p2m[i];
-            }
-            else
-            {
-                /* try to map page to determin wheter it has underlying page */
-                void *vaddr = xc_map_foreign_range(xc_handle, domid,
-                                                   PAGE_SIZE, PROT_READ, i);
-                if ( vaddr == NULL )
-                    continue;
-                munmap(vaddr, PAGE_SIZE);
-                pfn_array[j] = i;
-            }
-
-            j++;
-        }
-    }
-    if ( j != nr_pages )
-    {
-        PERROR("j (%ld) != nr_pages (%ld)", j , nr_pages);
-        /* When live dump-mode (-L option) is specified,
-         * guest domain may change its mapping.
-         */
-        nr_pages = j;
-    }
-
-    memset(&ehdr, 0, sizeof(ehdr));
-    ehdr.e_ident[EI_MAG0] = ELFMAG0;
-    ehdr.e_ident[EI_MAG1] = ELFMAG1;
-    ehdr.e_ident[EI_MAG2] = ELFMAG2;
-    ehdr.e_ident[EI_MAG3] = ELFMAG3;
-    ehdr.e_ident[EI_CLASS] = ELFCLASS64;
-    ehdr.e_ident[EI_DATA] = ELF_ARCH_DATA;
-    ehdr.e_ident[EI_VERSION] = EV_CURRENT;
-    ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV;
-    ehdr.e_ident[EI_ABIVERSION] = EV_CURRENT;
-
-    ehdr.e_type = ET_CORE;
-    ehdr.e_machine = ELF_ARCH_MACHINE;
-    ehdr.e_version = EV_CURRENT;
-    ehdr.e_entry = 0;
-    ehdr.e_phoff = 0;
-    ehdr.e_shoff = sizeof(ehdr);
-    ehdr.e_flags = ELF_CORE_EFLAGS;
-    ehdr.e_ehsize = sizeof(ehdr);
-    ehdr.e_phentsize = sizeof(Elf64_Phdr);
-    ehdr.e_phnum = 0;
-    ehdr.e_shentsize = sizeof(Elf64_Shdr);
     /* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
+    xc_core_ehdr_init(&ehdr);
 
     /* create section header */
     strtab = xc_core_strtab_init();
@@ -549,7 +583,7 @@ xc_domain_dumpcore_via_callback(int xc_h
     /* arch context */
     sts = xc_core_arch_context_get_shdr(&arch_ctxt, sheaders, strtab,
                                         &filesz, offset);
-    if ( sts != 0)
+    if ( sts != 0 )
         goto out;
     offset += filesz;
 
@@ -571,48 +605,12 @@ xc_domain_dumpcore_via_callback(int xc_h
         offset += filesz;
     }
 
-    /* p2m/pfn table */
-    shdr = xc_core_shdr_get(sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for .xen_{p2m, pfn} table");
-        goto out;
-    }
-    if ( !auto_translated_physmap )
-    {
-        filesz = nr_pages * sizeof(p2m_array[0]);
-        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_P2M,
-                               SHT_PROGBITS,
-                               offset, filesz, __alignof__(p2m_array[0]),
-                               sizeof(p2m_array[0]));
-        if ( sts != 0 )
-            goto out;
-    }
-    else
-    {
-        filesz = nr_pages * sizeof(pfn_array[0]);
-        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PFN,
-                               SHT_PROGBITS,
-                               offset, filesz, __alignof__(pfn_array[0]),
-                               sizeof(pfn_array[0]));
-        if ( sts != 0 )
-            goto out;
-    }
-    offset += filesz;
-
-    /* pages */
-    shdr = xc_core_shdr_get(sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("could not get section headers for .xen_pages");
-        goto out;
-    }
-
     /*
-     * pages are the last section to allocate section headers
+     * pages and p2m/pfn are the last section to allocate section headers
      * so that we know the number of section headers here.
+     * 2 = pages section and p2m/pfn table section
      */
-    fixup = sheaders->num * sizeof(*shdr);
+    fixup = (sheaders->num + 2) * sizeof(*shdr);
     /* zeroth section should have zero offset */
     for ( i = 1; i < sheaders->num; i++ )
         sheaders->shdrs[i].sh_offset += fixup;
@@ -620,9 +618,43 @@ xc_domain_dumpcore_via_callback(int xc_h
     dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
     offset += dummy_len;
 
+    /* pages */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("could not get section headers for .xen_pages");
+        goto out;
+    }
     filesz = nr_pages * PAGE_SIZE;
     sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
                            offset, filesz, PAGE_SIZE, PAGE_SIZE);
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* p2m/pfn table */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_{p2m, pfn} table");
+        goto out;
+    }
+    if ( !auto_translated_physmap )
+    {
+        filesz = nr_pages * sizeof(p2m_array[0]);
+        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_P2M,
+                               SHT_PROGBITS,
+                               offset, filesz, __alignof__(p2m_array[0]),
+                               sizeof(p2m_array[0]));
+    }
+    else
+    {
+        filesz = nr_pages * sizeof(pfn_array[0]);
+        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PFN,
+                               SHT_PROGBITS,
+                               offset, filesz, __alignof__(pfn_array[0]),
+                               sizeof(pfn_array[0]));
+    }
     if ( sts != 0 )
         goto out;
     offset += filesz;
@@ -645,54 +677,23 @@ xc_domain_dumpcore_via_callback(int xc_h
     if ( sts != 0 )
         goto out;
 
-    /* elf note section */
-    memset(&elfnote, 0, sizeof(elfnote));
-    elfnote.namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
-    strncpy(elfnote.name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote.name));
-
-    /* elf note section:xen core header */
-    elfnote.descsz = sizeof(none);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        goto out;
-    sts = dump_rtn(args, (char*)&none, sizeof(none));
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section:xen core header */
-    elfnote.descsz = sizeof(header);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
-    header.xch_magic = info.hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
-    header.xch_nr_vcpus = nr_vcpus;
-    header.xch_nr_pages = nr_pages;
-    header.xch_page_size = PAGE_SIZE;
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        goto out;
-    sts = dump_rtn(args, (char*)&header, sizeof(header));
+    /* elf note section: xen core header */
+    sts = elfnote_dump_none(args, dump_rtn);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: xen core header */
+    sts = elfnote_dump_core_header(args, dump_rtn, &info, nr_vcpus, nr_pages);
     if ( sts != 0 )
         goto out;
 
     /* elf note section: xen version */
-    elfnote.descsz = sizeof(xen_version);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
-    elfnote_fill_xen_version(xc_handle, &xen_version);
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        goto out;
-    sts = dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
+    sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle);
     if ( sts != 0 )
         goto out;
 
     /* elf note section: format version */
-    elfnote.descsz = sizeof(format_version);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
-    elfnote_fill_format_version(&format_version);
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        goto out;
-    sts = dump_rtn(args, (char*)&format_version, sizeof(format_version));
+    sts = elfnote_dump_format_version(args, dump_rtn);
     if ( sts != 0 )
         goto out;
 
@@ -714,16 +715,6 @@ xc_domain_dumpcore_via_callback(int xc_h
     if ( sts != 0 )
         goto out;
 
-    /* p2m/pfn table: .xen_p2m/.xen_pfn */
-    if ( !auto_translated_physmap )
-        sts = dump_rtn(args, (char *)p2m_array,
-                       sizeof(p2m_array[0]) * nr_pages);
-    else
-        sts = dump_rtn(args, (char *)pfn_array,
-                       sizeof(pfn_array[0]) * nr_pages);
-    if ( sts != 0 )
-        goto out;
-
     /* Pad the output data to page alignment. */
     memset(dummy, 0, PAGE_SIZE);
     sts = dump_rtn(args, dummy, dummy_len);
@@ -731,24 +722,102 @@ xc_domain_dumpcore_via_callback(int xc_h
         goto out;
 
     /* dump pages: .xen_pages */
-    for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
-    {
-        uint64_t gmfn;
-        if ( !auto_translated_physmap )
-            gmfn = p2m_array[i].gmfn;
-        else
-            gmfn = pfn_array[i];
-
-        copy_from_domain_page(xc_handle, domid, gmfn, dump_mem);
-        dump_mem += PAGE_SIZE;
-        if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
+    j = 0;
+    dump_mem = dump_mem_start;
+    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
+    {
+        uint64_t pfn_start;
+        uint64_t pfn_end;
+
+        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
+        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
+        for ( i = pfn_start; i < pfn_end; i++ )
         {
-            sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
+            uint64_t gmfn;
+            void *vaddr;
+            
+            if ( j >= nr_pages )
+            {
+                /*
+                 * When live dump-mode (-L option) is specified,
+                 * guest domain may increase memory.
+                 */
+                IPRINTF("exceeded nr_pages (%ld) losing pages", nr_pages);
+                goto copy_done;
+            }
+
+            if ( !auto_translated_physmap )
+            {
+                gmfn = p2m[i];
+                if ( gmfn == INVALID_P2M_ENTRY )
+                    continue;
+
+                p2m_array[j].pfn = i;
+                p2m_array[j].gmfn = gmfn;
+            }
+            else
+            {
+                if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
+                    continue;
+
+                gmfn = i;
+                pfn_array[j] = i;
+            }
+
+            vaddr = xc_map_foreign_range(
+                xc_handle, domid, PAGE_SIZE, PROT_READ, gmfn);
+            if ( vaddr == NULL )
+                continue;
+            memcpy(dump_mem, vaddr, PAGE_SIZE);
+            munmap(vaddr, PAGE_SIZE);
+            dump_mem += PAGE_SIZE;
+            if ( (j + 1) % DUMP_INCREMENT == 0 )
+            {
+                sts = dump_rtn(
+                    args, dump_mem_start, dump_mem - dump_mem_start);
+                if ( sts != 0 )
+                    goto out;
+                dump_mem = dump_mem_start;
+            }
+
+            j++;
+        }
+    }
+
+copy_done:
+    sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
+    if ( sts != 0 )
+        goto out;
+    if ( j < nr_pages )
+    {
+        /* When live dump-mode (-L option) is specified,
+         * guest domain may reduce memory. pad with zero pages.
+         */
+        IPRINTF("j (%ld) != nr_pages (%ld)", j , nr_pages);
+        memset(dump_mem_start, 0, PAGE_SIZE);
+        for (; j < nr_pages; j++) {
+            sts = dump_rtn(args, dump_mem_start, PAGE_SIZE);
             if ( sts != 0 )
                 goto out;
-            dump_mem = dump_mem_start;
-        }
-    }
+            if ( !auto_translated_physmap )
+            {
+                p2m_array[j].pfn = XC_CORE_INVALID_PFN;
+                p2m_array[j].gmfn = XC_CORE_INVALID_GMFN;
+            }
+            else
+                pfn_array[j] = XC_CORE_INVALID_PFN;
+        }
+    }
+
+    /* p2m/pfn table: .xen_p2m/.xen_pfn */
+    if ( !auto_translated_physmap )
+        sts = dump_rtn(
+            args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
+    else
+        sts = dump_rtn(
+            args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
+    if ( sts != 0 )
+        goto out;
 
     /* elf section header string table: .shstrtab */
     sts = dump_rtn(args, strtab->strings, strtab->current);
@@ -758,6 +827,8 @@ xc_domain_dumpcore_via_callback(int xc_h
     sts = 0;
 
 out:
+    if ( memory_map != NULL )
+        free(memory_map);
     if ( p2m != NULL )
         munmap(p2m, PAGE_SIZE * P2M_FL_ENTRIES);
     if ( p2m_array != NULL )
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core.h
--- a/tools/libxc/xc_core.h     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core.h     Thu Sep 06 12:05:15 2007 -0600
@@ -107,6 +107,8 @@ struct xen_dumpcore_elfnote_format_versi
     struct xen_dumpcore_elfnote_format_version_desc     format_version;
 };
 
+#define XC_CORE_INVALID_PFN     (~(uint64_t)0)
+#define XC_CORE_INVALID_GMFN    (~(uint64_t)0)
 struct xen_dumpcore_p2m {
     uint64_t    pfn;
     uint64_t    gmfn;
@@ -131,8 +133,10 @@ struct xc_core_memory_map {
 };
 typedef struct xc_core_memory_map xc_core_memory_map_t;
 int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info);
-int xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
-                                shared_info_t *live_shinfo,
+struct xc_core_arch_context;
+int xc_core_arch_memory_map_get(int xc_handle,
+                                struct xc_core_arch_context *arch_ctxt,
+                                xc_dominfo_t *info, shared_info_t *live_shinfo,
                                 xc_core_memory_map_t **mapp,
                                 unsigned int *nr_entries);
 int xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_ia64.c
--- a/tools/libxc/xc_core_ia64.c        Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_ia64.c        Thu Sep 06 12:05:15 2007 -0600
@@ -158,8 +158,8 @@ memory_map_get_old(int xc_handle, xc_dom
 }
 
 int
-xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
-                            shared_info_t *live_shinfo,
+xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
+                            xc_dominfo_t *info, shared_info_t *live_shinfo,
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_ia64.h
--- a/tools/libxc/xc_core_ia64.h        Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_ia64.h        Thu Sep 06 12:05:15 2007 -0600
@@ -46,6 +46,7 @@ int
 int
 xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
                           void* args, dumpcore_rtn_t dump_rtn);
+#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
 
 #endif /* XC_CORE_IA64_H */
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_powerpc.c
--- a/tools/libxc/xc_core_powerpc.c     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_powerpc.c     Thu Sep 06 12:05:15 2007 -0600
@@ -43,8 +43,8 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
 }
 
 int
-xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
-                            shared_info_t *live_shinfo,
+xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
+                            xc_dominfo_t *info, shared_info_t *live_shinfo,
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_powerpc.h
--- a/tools/libxc/xc_core_powerpc.h     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_powerpc.h     Thu Sep 06 12:05:15 2007 -0600
@@ -33,6 +33,7 @@ struct xc_core_arch_context {
 #define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
                                                                 (0)
 #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
+#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
 
 static inline int
 xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_x86.c
--- a/tools/libxc/xc_core_x86.c Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_x86.c Thu Sep 06 12:05:15 2007 -0600
@@ -33,8 +33,8 @@ xc_core_arch_auto_translated_physmap(con
 }
 
 int
-xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
-                            shared_info_t *live_shinfo,
+xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
+                            xc_dominfo_t *info, shared_info_t *live_shinfo,
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_core_x86.h
--- a/tools/libxc/xc_core_x86.h Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_core_x86.h Thu Sep 06 12:05:15 2007 -0600
@@ -40,6 +40,7 @@ struct xc_core_arch_context {
 #define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
                                                                 (0)
 #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
+#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
 
 static inline int
 xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xc_domain.c   Thu Sep 06 12:05:15 2007 -0600
@@ -55,10 +55,14 @@ int xc_domain_destroy(int xc_handle,
 int xc_domain_destroy(int xc_handle,
                       uint32_t domid)
 {
+    int ret;
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_destroydomain;
     domctl.domain = (domid_t)domid;
-    return do_domctl(xc_handle, &domctl);
+    do {
+        ret = do_domctl(xc_handle, &domctl);
+    } while ( ret && (errno == EAGAIN) );
+    return ret;
 }
 
 int xc_domain_shutdown(int xc_handle,
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/libxc/xenctrl.h     Thu Sep 06 12:05:15 2007 -0600
@@ -26,8 +26,8 @@
 #include <xen/event_channel.h>
 #include <xen/sched.h>
 #include <xen/memory.h>
-#include <xen/acm.h>
-#include <xen/acm_ops.h>
+#include <xen/xsm/acm.h>
+#include <xen/xsm/acm_ops.h>
 
 #ifdef __ia64__
 #define XC_PAGE_SHIFT           14
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/misc/xenperf.c
--- a/tools/misc/xenperf.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/misc/xenperf.c      Thu Sep 06 12:05:15 2007 -0600
@@ -46,7 +46,7 @@ const char *hypercall_name_table[64] =
     X(vcpu_op),
     X(set_segment_base),
     X(mmuext_op),
-    X(acm_op),
+    X(xsm_op),
     X(nmi_op),
     X(sched_op),
     X(callback_op),
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/Makefile
--- a/tools/python/Makefile     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/Makefile     Thu Sep 06 12:05:15 2007 -0600
@@ -1,5 +1,13 @@ XEN_ROOT = ../..
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
+
+XEN_SECURITY_MODULE = dummy
+ifeq ($(FLASK_ENABLE),y)
+XEN_SECURITY_MODULE = flask
+endif
+ifeq ($(ACM_SECURITY),y)
+XEN_SECURITY_MODULE = acm
+endif
 
 .PHONY: all
 all: build
@@ -15,8 +23,8 @@ NLSDIR = /usr/share/locale
 NLSDIR = /usr/share/locale
 
 .PHONY: build buildpy
-buildpy:
-       CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build
+buildpy: xsm.py
+       CC="$(CC)" CFLAGS="$(CFLAGS)" 
XEN_SECURITY_MODULE="$(XEN_SECURITY_MODULE)" python setup.py build
 
 build: buildpy refresh-pot refresh-po $(CATALOGS)
 
@@ -53,6 +61,18 @@ refresh-po: $(POTFILE)
 %.mo: %.po
        $(MSGFMT) -c -o $@ $<
 
+xsm.py:
+       @(set -e; \
+         echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \
+         echo "from xsm_core import *"; \
+         echo ""; \
+         echo "import 
xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" as xsm_module"; \
+         echo ""; \
+         echo "xsm_init(xsm_module)"; \
+         echo "from 
xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" import *"; \
+         echo "del xsm_module"; \
+         echo "") >xen/util/xsm/$@
+
 .PHONY: install
 ifndef XEN_PYTHON_NATIVE_INSTALL
 install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print 
auxbin.libpath()")
@@ -84,4 +104,4 @@ test:
 
 .PHONY: clean
 clean:
-       rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS)
+       rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/xsm/xsm.py
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/setup.py
--- a/tools/python/setup.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/setup.py     Thu Sep 06 12:05:15 2007 -0600
@@ -44,6 +44,14 @@ acm = Extension("acm",
                libraries          = libraries,
                sources            = [ "xen/lowlevel/acm/acm.c" ])
 
+flask = Extension("flask",
+               extra_compile_args = extra_compile_args,
+               include_dirs       = include_dirs + [ "xen/lowlevel/flask" ] + 
+                                        [ "../flask/libflask/include" ],
+               library_dirs       = library_dirs + [ "../flask/libflask" ],
+               libraries          = libraries + [ "flask" ],
+               sources            = [ "xen/lowlevel/flask/flask.c" ])
+
 ptsname = Extension("ptsname",
                extra_compile_args = extra_compile_args,
                include_dirs       = include_dirs + [ "ptsname" ],
@@ -51,7 +59,7 @@ ptsname = Extension("ptsname",
                libraries          = libraries,
                sources            = [ "ptsname/ptsname.c" ])
 
-modules = [ xc, xs, acm, ptsname ]
+modules = [ xc, xs, ptsname, acm, flask ]
 if os.uname()[0] == 'SunOS':
     modules.append(scf)
 
@@ -61,6 +69,10 @@ setup(name            = 'xen',
       packages        = ['xen',
                          'xen.lowlevel',
                          'xen.util',
+                         'xen.util.xsm',
+                         'xen.util.xsm.dummy',
+                         'xen.util.xsm.flask',
+                         'xen.util.xsm.acm',
                          'xen.xend',
                          'xen.xend.server',
                          'xen.xend.xenstore',
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/lowlevel/acm/acm.c
--- a/tools/python/xen/lowlevel/acm/acm.c       Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/lowlevel/acm/acm.c       Thu Sep 06 12:05:15 2007 -0600
@@ -18,6 +18,7 @@
  *
  * indent -i4 -kr -nut
  */
+
 #include <Python.h>
 
 #include <stdio.h>
@@ -27,8 +28,8 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <netinet/in.h>
-#include <xen/acm.h>
-#include <xen/acm_ops.h>
+#include <xen/xsm/acm.h>
+#include <xen/xsm/acm_ops.h>
 
 #include <xenctrl.h>
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/lowlevel/flask/flask.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/lowlevel/flask/flask.c   Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,139 @@
+/******************************************************************************
+ * flask.c
+ * 
+ * Authors: George Coker, <gscoker@xxxxxxxxxxxxxx>
+ *          Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License version 2,
+ *    as published by the Free Software Foundation.
+ */
+
+#include <Python.h>
+#include <xenctrl.h>
+
+#include <flask_op.h>
+
+#define PKG "xen.lowlevel.flask"
+#define CLS "flask"
+
+#define CTX_LEN 1024
+
+static PyObject *xc_error_obj;
+
+typedef struct {
+    PyObject_HEAD;
+    int xc_handle;
+} XcObject;
+
+static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
+                                                                 PyObject 
*kwds)
+{
+    int xc_handle;
+    char *ctx;
+    char *buf;
+    uint32_t len;
+    uint32_t sid;
+    int ret;
+
+    static char *kwd_list[] = { "context", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list,
+                                      &ctx) )
+        return NULL;
+
+    len = strlen(ctx);
+
+    buf = malloc(len);
+    if (!buf) {
+        errno = -ENOMEM;
+        PyErr_SetFromErrno(xc_error_obj);
+    }
+    
+    memcpy(buf, ctx, len);
+    
+    xc_handle = xc_interface_open();
+    if (xc_handle < 0) {
+        errno = xc_handle;
+        return PyErr_SetFromErrno(xc_error_obj);
+    }
+    
+    ret = flask_context_to_sid(xc_handle, buf, len, &sid);
+        
+    xc_interface_close(xc_handle);
+
+    free(buf);
+    
+    if ( ret != 0 ) {
+        errno = -ret;
+        return PyErr_SetFromErrno(xc_error_obj);
+    }
+
+    return PyInt_FromLong(sid);
+}
+
+static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args,
+                                                                 PyObject 
*kwds)
+{
+    int xc_handle;
+    uint32_t sid;
+    char ctx[CTX_LEN];
+    uint32_t ctx_len = CTX_LEN;
+    int ret;
+
+    static char *kwd_list[] = { "sid", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
+                                      &sid) )
+        return NULL;
+
+    xc_handle = xc_interface_open();
+    if (xc_handle < 0) {
+        errno = xc_handle;
+        return PyErr_SetFromErrno(xc_error_obj);
+    }
+    
+    ret = flask_sid_to_context(xc_handle, sid, ctx, ctx_len);
+    
+    xc_interface_close(xc_handle);
+    
+    if ( ret != 0 ) {
+        errno = -ret;
+        return PyErr_SetFromErrno(xc_error_obj);
+    }
+
+    return Py_BuildValue("s", ctx, ctx_len);
+}
+
+
+static PyMethodDef pyflask_methods[] = {
+    { "flask_context_to_sid",
+      (PyCFunction)pyflask_context_to_sid,
+      METH_KEYWORDS, "\n"
+      "Convert a context string to a dynamic SID.\n"
+      " context [str]: String specifying context to be converted\n"
+      "Returns: [int]: Numeric SID on success; -1 on error.\n" },
+
+    { "flask_sid_to_context",
+      (PyCFunction)pyflask_sid_to_context,
+      METH_KEYWORDS, "\n"
+      "Convert a dynamic SID to context string.\n"
+      " context [int]: SID to be converted\n"
+      "Returns: [str]: Numeric SID on success; -1 on error.\n" },
+
+    { NULL, NULL, 0, NULL }
+};
+
+PyMODINIT_FUNC initflask(void)
+{
+    Py_InitModule("flask", pyflask_methods);
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Sep 06 12:05:15 2007 -0600
@@ -685,7 +685,7 @@ static PyObject *pyxc_physinfo(XcObject 
     char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
     int i, j, max_cpu_id;
     PyObject *ret_obj, *node_to_cpu_obj;
-    xc_cpu_to_node_t map[MAX_CPU_ID];
+    xc_cpu_to_node_t map[MAX_CPU_ID + 1];
 
     set_xen_guest_handle(info.cpu_to_node, map);
     info.max_cpu_id = MAX_CPU_ID;
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/acmpolicy.py
--- a/tools/python/xen/util/acmpolicy.py        Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/util/acmpolicy.py        Thu Sep 06 12:05:15 2007 -0600
@@ -1,4 +1,4 @@
-#============================================================================
+ #============================================================================
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of version 2.1 of the GNU Lesser General Public
 # License as published by the Free Software Foundation.
@@ -23,10 +23,11 @@ import array
 import array
 from xml.dom import minidom, Node
 from xen.xend.XendLogging import log
-from xen.util import security, xsconstants, bootloader, mkdir
+from xen.util import xsconstants, bootloader, mkdir
 from xen.util.xspolicy import XSPolicy
-from xen.util.security import ACMError
 from xen.xend.XendError import SecurityError
+import xen.util.xsm.acm.acm as security
+from xen.util.xsm.xsm import XSMError
 
 ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
 
@@ -1240,8 +1241,8 @@ class ACMPolicy(XSPolicy):
 
         (major, minor) = self.getVersionTuple()
         hdr_bin = struct.pack(headerformat,
+                              ACM_MAGIC,
                               ACM_POLICY_VERSION,
-                              ACM_MAGIC,
                               totallen_bin,
                               polref_offset,
                               primpolcode,
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/security.py
--- a/tools/python/xen/util/security.py Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1299 +0,0 @@
-#===========================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2006 International Business Machines Corp.
-# Author: Reiner Sailer
-# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx>
-# Author: Stefan Berger <stefanb@xxxxxxxxxx>
-#============================================================================
-
-import commands
-import logging
-import os, string, re
-import threading
-import struct
-import stat
-from xen.lowlevel import acm
-from xen.xend import sxp
-from xen.xend import XendConstants
-from xen.xend.XendLogging import log
-from xen.xend.XendError import VmError
-from xen.util import dictio, xsconstants
-from xen.xend.XendConstants import *
-
-#global directories and tools for security management
-policy_dir_prefix = "/etc/xen/acm-security/policies"
-res_label_filename = policy_dir_prefix + "/resource_labels"
-boot_filename = "/boot/grub/menu.lst"
-altboot_filename = "/boot/grub/grub.conf"
-xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
-xensec_tool = "/usr/sbin/xensec_tool"
-
-#global patterns for map file
-#police_reference_tagname = "POLICYREFERENCENAME"
-primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
-secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
-label_template_re =  re.compile(".*security_label_template.xml", re.IGNORECASE)
-mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
-policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", 
re.IGNORECASE)
-vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
-res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
-all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
-access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
-
-#global patterns for boot configuration file
-xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
-any_title_re = re.compile("\s*title\s", re.IGNORECASE)
-xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
-kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
-any_module_re = re.compile("\s*module\s", re.IGNORECASE)
-empty_line_re = re.compile("^\s*$")
-binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
-policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
-
-#decision hooks known to the hypervisor
-ACMHOOK_sharing = 1
-ACMHOOK_authorization = 2
-
-#other global variables
-NULL_SSIDREF = 0
-
-#general Rlock for map files; only one lock for all mapfiles
-__mapfile_lock = threading.RLock()
-__resfile_lock = threading.RLock()
-
-log = logging.getLogger("xend.util.security")
-
-# Our own exception definition. It is masked (pass) if raised and
-# whoever raises this exception must provide error information.
-class ACMError(Exception):
-    def __init__(self,value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
-
-
-def err(msg):
-    """Raise ACM exception.
-    """
-    raise ACMError(msg)
-
-
-
-active_policy = None
-
-
-def mapfile_lock():
-    __mapfile_lock.acquire()
-
-def mapfile_unlock():
-    __mapfile_lock.release()
-
-
-def refresh_security_policy():
-    """
-    retrieves security policy
-    """
-    global active_policy
-
-    try:
-        active_policy = acm.policy()
-    except:
-        active_policy = "INACTIVE"
-
-# now set active_policy
-refresh_security_policy()
-
-def on():
-    """
-    returns none if security policy is off (not compiled),
-    any string otherwise, use it: if not security.on() ...
-    """
-    refresh_security_policy()
-    return (active_policy not in ['INACTIVE', 'NULL'])
-
-
-def calc_dom_ssidref_from_info(info):
-    """
-       Calculate a domain's ssidref from the security_label in its
-       info.
-       This function is called before the domain is started and
-       makes sure that:
-        - the type of the policy is the same as indicated in the label
-        - the name of the policy is the same as indicated in the label
-        - calculates an up-to-date ssidref for the domain
-       The latter is necessary since the domain's ssidref could have
-       changed due to changes to the policy.
-    """
-    import xen.xend.XendConfig
-    if isinstance(info, xen.xend.XendConfig.XendConfig):
-        if info.has_key('security_label'):
-            seclab = info['security_label']
-            tmp = seclab.split(":")
-            if len(tmp) != 3:
-                raise VmError("VM label '%s' in wrong format." % seclab)
-            typ, policyname, vmlabel = seclab.split(":")
-            if typ != xsconstants.ACM_POLICY_ID:
-                raise VmError("Policy type '%s' must be changed." % typ)
-            refresh_security_policy()
-            if active_policy != policyname:
-                raise VmError("Active policy '%s' different than "
-                              "what in VM's label ('%s')." %
-                              (active_policy, policyname))
-            ssidref = label2ssidref(vmlabel, policyname, "dom")
-            return ssidref
-        else:
-            return 0x0
-    raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
-                  "not supported." % type(info))
-
-
-def getmapfile(policyname):
-    """
-    in: if policyname is None then the currently
-    active hypervisor policy is used
-    out: 1. primary policy, 2. secondary policy,
-    3. open file descriptor for mapping file, and
-    4. True if policy file is available, False otherwise
-    """
-    if not policyname:
-        policyname = active_policy
-    map_file_ok = False
-    primary = None
-    secondary = None
-    #strip last part of policy as file name part
-    policy_dir_list = string.split(policyname, ".")
-    policy_file = policy_dir_list.pop()
-    if len(policy_dir_list) > 0:
-        policy_dir = string.join(policy_dir_list, "/") + "/"
-    else:
-        policy_dir = ""
-
-    map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
-    # check if it is there, if not check if policy file is there
-    if not os.path.isfile(map_filename):
-        policy_filename =  policy_dir_prefix + "/" + policy_dir + policy_file 
+ "-security_policy.xml"
-        if not os.path.isfile(policy_filename):
-            err("Policy file \'" + policy_filename + "\' not found.")
-        else:
-            err("Mapping file \'" + map_filename + "\' not found." +
-                " Use xm makepolicy to create it.")
-
-    f = open(map_filename)
-    for line in f:
-        if policy_reference_entry_re.match(line):
-            l = line.split()
-            if (len(l) == 2) and (l[1] == policyname):
-                map_file_ok = True
-        elif primary_entry_re.match(line):
-            l = line.split()
-            if len(l) == 2:
-                primary = l[1]
-        elif secondary_entry_re.match(line):
-            l = line.split()
-            if len(l) == 2:
-                secondary = l[1]
-    f.close()
-    f = open(map_filename)
-    if map_file_ok and primary and secondary:
-        return (primary, secondary, f, True)
-    else:
-        err("Mapping file inconsistencies found. Try makepolicy to create a 
new one.")
-
-
-
-def ssidref2label(ssidref_var):
-    """
-    returns labelname corresponding to ssidref;
-    maps current policy to default directory
-    to find mapping file
-    """
-    #1. translated permitted input formats
-    if isinstance(ssidref_var, str):
-        ssidref_var.strip()
-        if ssidref_var[0:2] == "0x":
-            ssidref = int(ssidref_var[2:], 16)
-        else:
-            ssidref = int(ssidref_var)
-    elif isinstance(ssidref_var, int):
-        ssidref = ssidref_var
-    else:
-        err("Instance type of ssidref not supported (must be of type 'str' or 
'int')")
-
-    if ssidref == 0:
-        from xen.util.acmpolicy import ACM_LABEL_UNLABELED
-        return ACM_LABEL_UNLABELED
-
-    try:
-        mapfile_lock()
-
-        (primary, secondary, f, pol_exists) = getmapfile(None)
-        if not f:
-            if (pol_exists):
-                err("Mapping file for policy not found.\n" +
-                    "Please use makepolicy command to create mapping file!")
-            else:
-                err("Policy file for \'" + active_policy + "\' not found.")
-
-        #2. get labelnames for both ssidref parts
-        pri_ssid = ssidref & 0xffff
-        sec_ssid = ssidref >> 16
-        pri_null_ssid = NULL_SSIDREF & 0xffff
-        sec_null_ssid = NULL_SSIDREF >> 16
-        pri_labels = []
-        sec_labels = []
-        labels = []
-
-        for line in f:
-            l = line.split()
-            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
-                continue
-            if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
-                pri_labels.append(l[3])
-            if secondary and (l[2] == secondary) and (int(l[4], 16) == 
sec_ssid):
-                sec_labels.append(l[3])
-        f.close()
-    finally:
-        mapfile_unlock()
-
-    #3. get the label that is in both lists (combination must be a single 
label)
-    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != 
sec_null_ssid):
-        labels = sec_labels
-    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid 
== sec_null_ssid):
-        labels = pri_labels
-    elif secondary == "NULL":
-        labels = pri_labels
-    else:
-        for i in pri_labels:
-            for j in sec_labels:
-                if (i==j):
-                    labels.append(i)
-    if len(labels) != 1:
-        err("Label for ssidref \'" +  str(ssidref) +
-            "\' unknown or not unique in policy \'" + active_policy + "\'")
-
-    return labels[0]
-
-
-
-def label2ssidref(labelname, policyname, typ):
-    """
-    returns ssidref corresponding to labelname;
-    maps current policy to default directory
-    to find mapping file    """
-
-    if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
-        err("Cannot translate labels for \'" + policyname + "\' policy.")
-
-    allowed_types = ['ANY']
-    if typ == 'dom':
-        allowed_types.append('VM')
-    elif typ == 'res':
-        allowed_types.append('RES')
-    else:
-        err("Invalid type.  Must specify 'dom' or 'res'.")
-
-    try:
-        mapfile_lock()
-        (primary, secondary, f, pol_exists) = getmapfile(policyname)
-
-        #2. get labelnames for ssidref parts and find a common label
-        pri_ssid = []
-        sec_ssid = []
-        for line in f:
-            l = line.split()
-            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
-                continue
-            if primary and (l[1] in allowed_types) and \
-                           (l[2] == primary) and \
-                           (l[3] == labelname):
-                pri_ssid.append(int(l[4], 16))
-            if secondary and (l[1] in allowed_types) and \
-                             (l[2] == secondary) and \
-                             (l[3] == labelname):
-                sec_ssid.append(int(l[4], 16))
-        f.close()
-        if (typ == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
-            pri_ssid.append(NULL_SSIDREF)
-        elif (typ == 'res') and (secondary == "CHWALL") and \
-             (len(sec_ssid) == 0):
-            sec_ssid.append(NULL_SSIDREF)
-
-        #3. sanity check and composition of ssidref
-        if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and \
-            (secondary != "NULL")):
-            err("Label \'" + labelname + "\' not found.")
-        elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
-            err("Label \'" + labelname + "\' not unique in policy (policy 
error)")
-        if secondary == "NULL":
-            return pri_ssid[0]
-        else:
-            return (sec_ssid[0] << 16) | pri_ssid[0]
-    finally:
-       mapfile_unlock()
-
-
-def refresh_ssidref(config):
-    """
-    looks up ssidref from security field
-    and refreshes the value if label exists
-    """
-    #called by dom0, policy could have changed after xen.utils.security was 
initialized
-    refresh_security_policy()
-
-    security = None
-    if isinstance(config, dict):
-        security = config['security']
-    elif isinstance(config, list):
-        security = sxp.child_value(config, 'security')
-    else:
-        err("Instance type of config parameter not supported.")
-    if not security:
-        #nothing to do (no security label attached)
-        return config
-
-    policyname = None
-    labelname = None
-    # compose new security field
-    for idx in range(0, len(security)):
-        if security[idx][0] == 'ssidref':
-            security.pop(idx)
-            break
-        elif security[idx][0] == 'access_control':
-            for jdx in [1, 2]:
-                if security[idx][jdx][0] == 'label':
-                    labelname = security[idx][jdx][1]
-                elif security[idx][jdx][0] == 'policy':
-                    policyname = security[idx][jdx][1]
-                else:
-                    err("Illegal field in access_control")
-    #verify policy is correct
-    if active_policy != policyname:
-        err("Policy \'" + str(policyname) +
-            "\' in label does not match active policy \'"
-            + str(active_policy) +"\'!")
-
-    new_ssidref = label2ssidref(labelname, policyname, 'dom')
-    if not new_ssidref:
-        err("SSIDREF refresh failed!")
-
-    security.append([ 'ssidref',str(new_ssidref)])
-    security = ['security', security ]
-
-    for idx in range(0,len(config)):
-        if config[idx][0] == 'security':
-            config.pop(idx)
-            break
-        config.append(security)
-
-
-
-def get_ssid(domain):
-    """
-    enables domains to retrieve the label / ssidref of a running domain
-    """
-    if not on():
-        err("No policy active.")
-
-    if isinstance(domain, str):
-        domain_int = int(domain)
-    elif isinstance(domain, int):
-        domain_int = domain
-    else:
-        err("Illegal parameter type.")
-    try:
-        ssid_info = acm.getssid(int(domain_int))
-    except:
-        err("Cannot determine security information.")
-
-    if active_policy in ["DEFAULT"]:
-        label = "DEFAULT"
-    else:
-        label = ssidref2label(ssid_info["ssidref"])
-    return(ssid_info["policyreference"],
-           label,
-           ssid_info["policytype"],
-           ssid_info["ssidref"])
-
-
-
-def get_decision(arg1, arg2):
-    """
-    enables domains to retrieve access control decisions from
-    the hypervisor Access Control Module.
-    IN: args format = ['domid', id] or ['ssidref', ssidref]
-    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
-    """
-
-    if not on():
-        err("No policy active.")
-
-    #translate labels before calling low-level function
-    if arg1[0] == 'access_control':
-        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] 
!= 'type'):
-            err("Argument type not supported.")
-        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
-        arg1 = ['ssidref', str(ssidref)]
-    if arg2[0] == 'access_control':
-        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] 
!= 'type'):
-            err("Argument type not supported.")
-        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
-        arg2 = ['ssidref', str(ssidref)]
-
-    # accept only int or string types for domid and ssidref
-    if isinstance(arg1[1], int):
-        arg1[1] = str(arg1[1])
-    if isinstance(arg2[1], int):
-        arg2[1] = str(arg2[1])
-    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
-        err("Invalid id or ssidref type, string or int required")
-
-    try:
-        decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1],
-                                   ACMHOOK_sharing)
-    except:
-        err("Cannot determine decision.")
-
-    if decision:
-        return decision
-    else:
-        err("Cannot determine decision (Invalid parameter).")
-
-
-def has_authorization(ssidref):
-    """ Check if the domain with the given ssidref has authorization to
-        run on this system. To have authoriztion dom0's STE types must
-        be a superset of that of the domain's given through its ssidref.
-    """
-    rc = True
-    dom0_ssidref = int(acm.getssid(0)['ssidref'])
-    decision = acm.getdecision('ssidref', str(dom0_ssidref),
-                               'ssidref', str(ssidref),
-                               ACMHOOK_authorization)
-    if decision == "DENIED":
-        rc = False
-    return rc
-
-
-def hv_chg_policy(bin_pol, del_array, chg_array):
-    """
-        Change the binary policy in the hypervisor
-        The 'del_array' and 'chg_array' give hints about deleted ssidrefs
-        and changed ssidrefs which can be due to deleted VM labels
-        or reordered VM labels
-    """
-    rc = -xsconstants.XSERR_GENERAL_FAILURE
-    errors = ""
-    if not on():
-        err("No policy active.")
-    try:
-        rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
-    except Exception, e:
-        pass
-    if len(errors) > 0:
-        rc = -xsconstants.XSERR_HV_OP_FAILED
-    return rc, errors
-
-
-def make_policy(policy_name):
-    policy_file = string.join(string.split(policy_name, "."), "/")
-    if not os.path.isfile(policy_dir_prefix + "/" + policy_file + 
"-security_policy.xml"):
-        err("Unknown policy \'" + policy_name + "\'")
-
-    (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + 
policy_dir_prefix + " " + policy_file)
-    if ret:
-        err("Creating policy failed:\n" + output)
-
-def load_policy(policy_name):
-    global active_policy
-    policy_file = policy_dir_prefix + "/" + 
string.join(string.split(policy_name, "."), "/")
-    if not os.path.isfile(policy_file + ".bin"):
-        if os.path.isfile(policy_file + "-security_policy.xml"):
-            err("Binary file does not exist." +
-                "Please use makepolicy to build the policy binary.")
-        else:
-            err("Unknown Policy " + policy_name)
-
-    #require this policy to be the first or the same as installed
-    if active_policy not in ['DEFAULT', policy_name]:
-        err("Active policy \'" + active_policy +
-            "\' incompatible with new policy \'" + policy_name + "\'")
-    (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + 
policy_file + ".bin")
-    if ret:
-        err("Loading policy failed:\n" + output)
-    else:
-        # refresh active policy
-        refresh_security_policy()
-
-
-
-def dump_policy():
-    if active_policy in ['NULL', 'INACTIVE']:
-        err("\'" + active_policy + "\' policy. Nothing to dump.")
-
-    (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
-    if ret:
-       err("Dumping hypervisor policy failed:\n" + output)
-    print output
-
-
-
-def list_labels(policy_name, condition):
-    if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", 
"DEFAULT"]:
-        err("Current policy \'" + active_policy + "\' has no labels 
defined.\n")
-
-    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
-    if not f:
-        if pol_exists:
-            err("Cannot find mapfile for policy \'" + policy_name +
-                "\'.\nPlease use makepolicy to create mapping file.")
-        else:
-            err("Unknown policy \'" + policy_name + "\'")
-
-    labels = []
-    for line in f:
-        if condition.match(line):
-            label = line.split()[3]
-            if label not in labels:
-                labels.append(label)
-    return labels
-
-
-def get_res_label(resource):
-    """Returns resource label information (policytype, label, policy) if
-       it exists. Otherwise returns null label and policy.
-    """
-    def default_res_label():
-        ssidref = NULL_SSIDREF
-        if on():
-            label = ssidref2label(ssidref)
-        else:
-            label = None
-        return (xsconstants.ACM_POLICY_ID, 'NULL', label)
-
-
-    tmp = get_resource_label(resource)
-    if len(tmp) == 2:
-        policytype = xsconstants.ACM_POLICY_ID
-        policy, label = tmp
-    elif len(tmp) == 3:
-        policytype, policy, label = tmp
-    else:
-        policytype, policy, label = default_res_label()
-
-    return (policytype, label, policy)
-
-
-def get_res_security_details(resource):
-    """Returns the (label, ssidref, policy) associated with a given
-       resource from the global resource label file.
-    """
-    def default_security_details():
-        ssidref = NULL_SSIDREF
-        if on():
-            label = ssidref2label(ssidref)
-        else:
-            label = None
-        policy = active_policy
-        return (label, ssidref, policy)
-
-    (label, ssidref, policy) = default_security_details()
-
-    # find the entry associated with this resource
-    (policytype, label, policy) = get_res_label(resource)
-    if policy == 'NULL':
-        log.info("Resource label for "+resource+" not in file, using DEFAULT.")
-        return default_security_details()
-
-    # is this resource label for the running policy?
-    if policy == active_policy:
-        ssidref = label2ssidref(label, policy, 'res')
-    else:
-        log.info("Resource label not for active policy, using DEFAULT.")
-        return default_security_details()
-
-    return (label, ssidref, policy)
-
-def security_label_to_details(seclab):
-    """ Convert a Xen-API type of security label into details """
-    def default_security_details():
-        ssidref = NULL_SSIDREF
-        if on():
-            label = ssidref2label(ssidref)
-        else:
-            label = None
-        policy = active_policy
-        return (label, ssidref, policy)
-
-    (policytype, policy, label) = seclab.split(":")
-
-    # is this resource label for the running policy?
-    if policy == active_policy:
-        ssidref = label2ssidref(label, policy, 'res')
-    else:
-        log.info("Resource label not for active policy, using DEFAULT.")
-        return default_security_details()
-
-    return (label, ssidref, policy)
-
-def unify_resname(resource, mustexist=True):
-    """Makes all resource locations absolute. In case of physical
-    resources, '/dev/' is added to local file names"""
-
-    if not resource:
-        return resource
-
-    # sanity check on resource name
-    try:
-        (typ, resfile) = resource.split(":", 1)
-    except:
-        err("Resource spec '%s' contains no ':' delimiter" % resource)
-
-    if typ == "tap":
-        try:
-            (subtype, resfile) = resfile.split(":")
-        except:
-            err("Resource spec '%s' contains no tap subtype" % resource)
-
-    import os
-    if typ in ["phy", "tap"]:
-        if not resfile.startswith("/"):
-            resfile = "/dev/" + resfile
-        if mustexist:
-            stats = os.lstat(resfile)
-            if stat.S_ISLNK(stats[stat.ST_MODE]):
-                resolved = os.readlink(resfile)
-                if resolved[0] != "/":
-                    resfile = os.path.join(os.path.dirname(resfile), resolved)
-                    resfile = os.path.abspath(resfile)
-                else:
-                    resfile = resolved
-                stats = os.lstat(resfile)
-            if not (stat.S_ISBLK(stats[stat.ST_MODE])):
-                err("Invalid resource")
-
-    if typ in [ "file", "tap" ]:
-        if mustexist:
-            stats = os.lstat(resfile)
-            if stat.S_ISLNK(stats[stat.ST_MODE]):
-                resfile = os.readlink(resfile)
-                stats = os.lstat(resfile)
-            if not stat.S_ISREG(stats[stat.ST_MODE]):
-                err("Invalid resource")
-
-    #file: resources must specified with absolute path
-    #vlan resources don't start with '/'
-    if typ != "vlan":
-        if (not resfile.startswith("/")) or \
-           (mustexist and not os.path.exists(resfile)):
-            err("Invalid resource.")
-
-    # from here on absolute file names with resources
-    if typ == "tap":
-        typ = typ + ":" + subtype
-    resource = typ + ":" + resfile
-    return resource
-
-
-def res_security_check(resource, domain_label):
-    """Checks if the given resource can be used by the given domain
-       label.  Returns 1 if the resource can be used, otherwise 0.
-    """
-    rtnval = 1
-
-    # if security is on, ask the hypervisor for a decision
-    if on():
-        #build canonical resource name
-        resource = unify_resname(resource)
-
-        (label, ssidref, policy) = get_res_security_details(resource)
-        domac = ['access_control']
-        domac.append(['policy', active_policy])
-        domac.append(['label', domain_label])
-        domac.append(['type', 'dom'])
-        decision = get_decision(domac, ['ssidref', str(ssidref)])
-
-        # provide descriptive error messages
-        if decision == 'DENIED':
-            if label == ssidref2label(NULL_SSIDREF):
-                raise ACMError("Resource '"+resource+"' is not labeled")
-                rtnval = 0
-            else:
-                raise ACMError("Permission denied for resource '"+resource+"' 
because label '"+label+"' is not allowed")
-                rtnval = 0
-
-    # security is off, make sure resource isn't labeled
-    else:
-        # Note, we can't canonicalise the resource here, because people using
-        # xm without ACM are free to use relative paths.
-        (policytype, label, policy) = get_res_label(resource)
-        if policy != 'NULL':
-            raise ACMError("Security is off, but '"+resource+"' is labeled")
-            rtnval = 0
-
-    return rtnval
-
-def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
-    """Checks if the given resource can be used by the given domain
-       label.  Returns 1 if the resource can be used, otherwise 0.
-    """
-    rtnval = 1
-    # if security is on, ask the hypervisor for a decision
-    if on():
-        typ, dpolicy, domain_label = xapi_dom_label.split(":")
-        if not dpolicy or not domain_label:
-            raise VmError("VM security label in wrong format.")
-        if active_policy != rpolicy:
-            raise VmError("Resource's policy '%s' != active policy '%s'" %
-                          (rpolicy, active_policy))
-        domac = ['access_control']
-        domac.append(['policy', active_policy])
-        domac.append(['label', domain_label])
-        domac.append(['type', 'dom'])
-        decision = get_decision(domac, ['ssidref', str(rssidref)])
-
-        log.info("Access Control Decision : %s" % decision)
-        # provide descriptive error messages
-        if decision == 'DENIED':
-            if rlabel == ssidref2label(NULL_SSIDREF):
-                #raise ACMError("Resource is not labeled")
-                rtnval = 0
-            else:
-                #raise ACMError("Permission denied for resource because label 
'"+rlabel+"' is not allowed")
-                rtnval = 0
-
-    # security is off, make sure resource isn't labeled
-    else:
-        # Note, we can't canonicalise the resource here, because people using
-        # xm without ACM are free to use relative paths.
-        if rpolicy != 'NULL':
-            #raise ACMError("Security is off, but resource is labeled")
-            rtnval = 0
-
-    return rtnval
-
-
-def validate_label(label, policyref):
-    """
-       Make sure that this label is part of the currently enforced policy
-       and that it reference the current policy.
-    """
-    rc = xsconstants.XSERR_SUCCESS
-    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
-    curpol = XSPolicyAdminInstance().get_loaded_policy()
-    if not curpol or curpol.get_name() != policyref:
-        rc = -xsconstants.XSERR_BAD_LABEL
-    else:
-        try:
-            label2ssidref(label, curpol.get_name() , 'res')
-        except:
-            rc = -xsconstants.XSERR_BAD_LABEL
-    return rc
-
-
-def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
-    """Assign a resource label to a resource
-    @param resource: The name of a resource, i.e., "phy:/dev/hda", or
-              "tap:qcow:/path/to/file.qcow"
-
-    @param reslabel_xapi: A resource label foramtted as in all other parts of
-                          the Xen-API, i.e., ACM:xm-test:blue"
-    @rtype: int
-    @return Success (0) or failure value (< 0)
-    """
-    olabel = ""
-    if reslabel_xapi == "":
-        return rm_resource_label(resource, oldlabel_xapi)
-    typ, policyref, label = reslabel_xapi.split(":")
-    if typ != xsconstants.ACM_POLICY_ID:
-        return -xsconstants.XSERR_WRONG_POLICY_TYPE
-    if not policyref or not label:
-        return -xsconstants.XSERR_BAD_LABEL_FORMAT
-    if oldlabel_xapi not in [ "" ]:
-        tmp = oldlabel_xapi.split(":")
-        if len(tmp) != 3:
-            return -xsconstants.XSERR_BAD_LABEL_FORMAT
-        otyp, opolicyref, olabel = tmp
-        # Only ACM is supported
-        if otyp != xsconstants.ACM_POLICY_ID  and \
-           otyp != xsconstants.INVALID_POLICY_PREFIX + \
-                   xsconstants.ACM_POLICY_ID:
-            return -xsconstants.XSERR_WRONG_POLICY_TYPE
-    rc = validate_label(label, policyref)
-    if rc != xsconstants.XSERR_SUCCESS:
-        return rc
-    return set_resource_label(resource, typ, policyref, label, olabel)
-
-
-def is_resource_in_use(resource):
-    """
-       Domain-0 'owns' resources of type 'VLAN', the rest are owned by
-       the guests.
-    """
-    from xen.xend import XendDomain
-    lst = []
-    if resource.startswith('vlan'):
-        from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
-        curpol = XSPolicyAdminInstance().get_loaded_policy()
-        policytype, label, policy = get_res_label(resource)
-        if curpol and \
-           policytype == xsconstants.ACM_POLICY_ID and \
-           policy == curpol.get_name() and \
-           label in curpol.policy_get_resourcelabel_names():
-            # VLAN is in use.
-            lst.append(XendDomain.instance().
-                         get_vm_by_uuid(XendDomain.DOM0_UUID))
-    else:
-        dominfos = XendDomain.instance().list('all')
-        for dominfo in dominfos:
-            if is_resource_in_use_by_dom(dominfo, resource):
-                lst.append(dominfo)
-    return lst
-
-def devices_equal(res1, res2, mustexist=True):
-    """ Determine whether two devices are equal """
-    return (unify_resname(res1, mustexist) ==
-            unify_resname(res2, mustexist))
-
-def is_resource_in_use_by_dom(dominfo, resource):
-    """ Determine whether a resources is in use by a given domain
-        @return True or False
-    """
-    if not dominfo.domid:
-        return False
-    if dominfo._stateGet() not in [ DOM_STATE_RUNNING ]:
-        return False
-    devs = dominfo.info['devices']
-    uuids = devs.keys()
-    for uuid in uuids:
-        dev = devs[uuid]
-        if len(dev) >= 2 and dev[1].has_key('uname'):
-            # dev[0] is type, i.e. 'vbd'
-            if devices_equal(dev[1]['uname'], resource, mustexist=False):
-                log.info("RESOURCE IN USE: Domain %d uses %s." %
-                         (dominfo.domid, resource))
-                return True
-    return False
-
-
-def get_domain_resources(dominfo):
-    """ Collect all resources of a domain in a map where each entry of
-        the map is a list.
-        Entries are strored in the following formats:
-          tap:qcow:/path/xyz.qcow
-    """
-    resources = { 'vbd' : [], 'tap' : [], 'vif' : []}
-    devs = dominfo.info['devices']
-    uuids = devs.keys()
-    for uuid in uuids:
-        dev = devs[uuid]
-        typ = dev[0]
-        if typ in [ 'vbd', 'tap' ]:
-            resources[typ].append(dev[1]['uname'])
-        if typ in [ 'vif' ]:
-            sec_lab = dev[1].get('security_label')
-            if sec_lab:
-                resources[typ].append(sec_lab)
-            else:
-                # !!! This should really get the label of the domain
-                # or at least a resource label that has the same STE type
-                # as the domain has
-                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
-                resources[typ].append("%s:%s:%s" %
-                                      (xsconstants.ACM_POLICY_ID,
-                                       active_policy,
-                                       ACM_LABEL_UNLABELED))
-
-    return resources
-
-
-def resources_compatible_with_vmlabel(xspol, dominfo, vmlabel):
-    """
-       Check whether the resources' labels are compatible with the
-       given VM label. This is a function to be used when for example
-       a running domain is to get the new label 'vmlabel'
-    """
-    if not xspol:
-        return False
-
-    try:
-        __resfile_lock.acquire()
-        try:
-            access_control = dictio.dict_read("resources",
-                                              res_label_filename)
-        except:
-            return False
-        return __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
-                                                   access_control)
-    finally:
-        __resfile_lock.release()
-    return False
-
-
-def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
-                                        access_control,
-                                        is_policy_update=False):
-    """
-        Check whether the resources' labels are compatible with the
-        given VM label. The access_control parameter provides a
-        dictionary of the resource name to resource label mappings
-        under which the evaluation should be done.
-    """
-    def collect_labels(reslabels, s_label, polname):
-        if len(s_label) != 3 or polname != s_label[1]:
-            return False
-        label = s_label[2]
-        if not label in reslabels:
-            reslabels.append(label)
-        return True
-
-    resources = get_domain_resources(dominfo)
-    reslabels = []  # all resource labels
-
-    polname = xspol.get_name()
-    for key, value in resources.items():
-        if key in [ 'vbd', 'tap' ]:
-            for res in resources[key]:
-                try:
-                    label = access_control[res]
-                    if not collect_labels(reslabels, label, polname):
-                        return False
-                except:
-                    return False
-        elif key in [ 'vif' ]:
-            for xapi_label in value:
-                label = xapi_label.split(":")
-                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
-                if not (is_policy_update and \
-                        label[2] == ACM_LABEL_UNLABELED):
-                    if not collect_labels(reslabels, label, polname):
-                        return False
-        else:
-            log.error("Unhandled device type: %s" % key)
-            return False
-
-    # Check that all resource labes have a common STE type with the
-    # vmlabel
-    if len(reslabels) > 0:
-        rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
-    else:
-        rc = True
-    log.info("vmlabel=%s, reslabels=%s, rc=%s" %
-             (vmlabel, reslabels, str(rc)))
-    return rc;
-
-def set_resource_label(resource, policytype, policyref, reslabel, \
-                       oreslabel = None):
-    """Assign a label to a resource
-       If the old label (oreslabel) is given, then the resource must have
-       that old label.
-       A resource label may be changed if
-       - the resource is not in use
-    @param resource  : The name of a resource, i.e., "phy:/dev/hda"
-    @param policyref : The name of the policy
-    @param reslabel     : the resource label within the policy
-    @param oreslabel    : optional current resource label
-
-    @rtype: int
-    @return Success (0) or failure value (< 0)
-    """
-    try:
-        resource = unify_resname(resource, mustexist=False)
-    except Exception:
-        return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
-
-    domains = is_resource_in_use(resource)
-    if len(domains) > 0:
-        return -xsconstants.XSERR_RESOURCE_IN_USE
-
-    try:
-        __resfile_lock.acquire()
-        access_control = {}
-        try:
-             access_control = dictio.dict_read("resources", res_label_filename)
-        except:
-            pass
-        if oreslabel:
-            if not access_control.has_key(resource):
-                return -xsconstants.XSERR_BAD_LABEL
-            tmp = access_control[resource]
-            if len(tmp) != 3:
-                return -xsconstants.XSERR_BAD_LABEL
-            if tmp[2] != oreslabel:
-                return -xsconstants.XSERR_BAD_LABEL
-        if reslabel != "":
-            new_entry = { resource : tuple([policytype, policyref, reslabel])}
-            access_control.update(new_entry)
-        else:
-            if access_control.has_key(resource):
-                del access_control[resource]
-        dictio.dict_write(access_control, "resources", res_label_filename)
-    finally:
-        __resfile_lock.release()
-    return xsconstants.XSERR_SUCCESS
-
-def rm_resource_label(resource, oldlabel_xapi):
-    """Remove a resource label from a physical resource
-    @param resource: The name of a resource, i.e., "phy:/dev/hda"
-
-    @rtype: int
-    @return Success (0) or failure value (< 0)
-    """
-    tmp = oldlabel_xapi.split(":")
-    if len(tmp) != 3:
-        return -xsconstants.XSERR_BAD_LABEL_FORMAT
-    otyp, opolicyref, olabel = tmp
-    # Only ACM is supported
-    if otyp != xsconstants.ACM_POLICY_ID and \
-       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:
-        return -xsconstants.XSERR_WRONG_POLICY_TYPE
-    return set_resource_label(resource, "", "", "", olabel)
-
-def get_resource_label_xapi(resource):
-    """Get the assigned resource label of a physical resource
-      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"
-
-      @rtype: string
-      @return the string representing policy type, policy name and label of
-              the resource
-    """
-    res = get_resource_label(resource)
-    return format_resource_label(res)
-
-def format_resource_label(res):
-    if res:
-        if len(res) == 2:
-            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]
-        if len(res) == 3:
-            return ":".join(res)
-    return ""
-
-def get_resource_label(resource):
-    """Get the assigned resource label of a given resource
-    @param resource: The name of a resource, i.e., "phy:/dev/hda"
-
-    @rtype: list
-    @return tuple of (policy name, resource label), i.e., (xm-test, blue)
-    """
-    try:
-        resource = unify_resname(resource, mustexist=False)
-    except Exception:
-        return []
-
-    reslabel_map = get_labeled_resources()
-
-    if reslabel_map.has_key(resource):
-        return list(reslabel_map[resource])
-    else:
-        #Try to resolve each label entry
-        for key, value in reslabel_map.items():
-            try:
-                if resource == unify_resname(key):
-                    return list(value)
-            except:
-                pass
-
-    return []
-
-
-def get_labeled_resources_xapi():
-    """ Get a map of all labeled resource with the labels formatted in the
-        xen-api resource label format.
-    """
-    reslabel_map = get_labeled_resources()
-    for key, labeldata in reslabel_map.items():
-        reslabel_map[key] = format_resource_label(labeldata)
-    return reslabel_map
-
-
-def get_labeled_resources():
-    """Get a map of all labeled resources
-    @rtype: list
-    @return list of labeled resources
-    """
-    try:
-        __resfile_lock.acquire()
-        try:
-            access_control = dictio.dict_read("resources", res_label_filename)
-        except:
-            return {}
-    finally:
-        __resfile_lock.release()
-    return access_control
-
-
-def relabel_domains(relabel_list):
-    """
-      Relabel the given domains to have a new ssidref.
-      @param relabel_list: a list containing tuples of domid, ssidref
-                           example: [ [0, 0x00020002] ]
-    """
-    rel_rules = ""
-    for r in relabel_list:
-        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",
-                r[0], r[1])
-        rel_rules += struct.pack("ii", r[0], r[1])
-    try:
-        rc, errors = acm.relabel_domains(rel_rules)
-    except Exception, e:
-        log.info("Error after relabel_domains: %s" % str(e))
-        rc = -xsconstants.XSERR_GENERAL_FAILURE
-        errors = ""
-    if (len(errors) > 0):
-        rc = -xsconstants.XSERR_HV_OP_FAILED
-    return rc, errors
-
-
-def change_acm_policy(bin_pol, del_array, chg_array,
-                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):
-    """
-       Change the ACM policy of the system by relabeling
-       domains and resources first and doing some access checks.
-       Then update the policy in the hypervisor. If this is all successful,
-       relabel the domains permanently and commit the relabed resources.
-
-       Need to do / check the following:
-        - relabel all resources where there is a 'from' field in
-          the policy. [ NOT DOING THIS: and mark those as unlabeled where the 
label
-          does not appear in the new policy anymore (deletion) ]
-        - relabel all VMs where there is a 'from' field in the
-          policy and mark those as unlabeled where the label
-          does not appear in the new policy anymore; no running
-          or paused VM may be unlabeled through this
-        - check that under the new labeling conditions the VMs
-          still have access to their resources as before. Unlabeled
-          resources are inaccessible. If this check fails, the
-          update failed.
-        - Attempt changes in the hypervisor; if this step fails,
-          roll back the relabeling of resources and VMs
-        - Make the relabeling of resources and VMs permanent
-    """
-    rc = xsconstants.XSERR_SUCCESS
-
-    domain_label_map = {}
-    new_policyname = new_acmpol.get_name()
-    new_policytype = new_acmpol.get_type_name()
-    cur_policyname = cur_acmpol.get_name()
-    cur_policytype = cur_acmpol.get_type_name()
-    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()
-    errors=""
-
-    try:
-        __resfile_lock.acquire()
-        mapfile_lock()
-
-        # Get all domains' dominfo.
-        from xen.xend import XendDomain
-        dominfos = XendDomain.instance().list('all')
-
-        log.info("----------------------------------------------")
-        # relabel resources
-
-        access_control = {}
-        try:
-            access_control = dictio.dict_read("resources", res_label_filename)
-        finally:
-            pass
-        for key, labeldata in access_control.items():
-            if len(labeldata) == 2:
-                policy, label = labeldata
-                policytype = xsconstants.ACM_POLICY_ID
-            elif len(labeldata) == 3:
-                policytype, policy, label = labeldata
-            else:
-                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""
-
-            if policytype != cur_policytype or \
-               policy     != cur_policyname:
-                continue
-
-            # label been renamed or deleted?
-            if reslabel_map.has_key(label) and cur_policyname == policy:
-                label = reslabel_map[label]
-            elif label not in polnew_reslabels:
-                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
-            # Update entry
-            access_control[key] = \
-                   tuple([ policytype, new_policyname, label ])
-
-        # All resources have new labels in the access_control map
-        # There may still be labels in there that are invalid now.
-
-        # Do this in memory without writing to disk:
-        #  - Relabel all domains independent of whether they are running
-        #    or not
-        #  - later write back to config files
-        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()
-
-        for dominfo in dominfos:
-            sec_lab = dominfo.get_security_label()
-            if not sec_lab:
-                continue
-            policytype, policy, vmlabel = sec_lab.split(":")
-            name  = dominfo.getName()
-
-            if policytype != cur_policytype or \
-               policy     != cur_policyname:
-                continue
-
-            new_vmlabel = vmlabel
-            if vmlabel_map.has_key(vmlabel):
-                new_vmlabel = vmlabel_map[vmlabel]
-            if new_vmlabel not in polnew_vmlabels:
-                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
-            new_seclab = "%s:%s:%s" % \
-                    (policytype, new_policyname, new_vmlabel)
-
-            domain_label_map[dominfo] = [ sec_lab, new_seclab ]
-
-            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
-                compatible = __resources_compatible_with_vmlabel(new_acmpol,
-                                                      dominfo,
-                                                      new_vmlabel,
-                                                      access_control,
-                                                      is_policy_update=True)
-                log.info("Domain %s with new label '%s' can access its "
-                         "resources? : %s" %
-                         (name, new_vmlabel, str(compatible)))
-                log.info("VM labels in new policy: %s" %
-                         new_acmpol.policy_get_virtualmachinelabel_names())
-                if not compatible:
-                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
-
-        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)
-        if rc == 0:
-            # Write the relabeled resources back into the file
-            dictio.dict_write(access_control, "resources", res_label_filename)
-            # Properly update all VMs to their new labels
-            for dominfo, labels in domain_label_map.items():
-                sec_lab, new_seclab = labels
-                if sec_lab != new_seclab:
-                    log.info("Updating domain %s to new label '%s'." % \
-                             (dominfo.getName(), new_seclab))
-                    # This better be working!
-                    res = dominfo.set_security_label(new_seclab,
-                                                     sec_lab,
-                                                     new_acmpol,
-                                                     cur_acmpol)
-                    if res[0] != xsconstants.XSERR_SUCCESS:
-                        log.info("ERROR: Could not chg label on domain %s: %s" 
%
-                                 (dominfo.getName(),
-                                  xsconstants.xserr2string(-int(res[0]))))
-    finally:
-        log.info("----------------------------------------------")
-        mapfile_unlock()
-        __resfile_lock.release()
-
-    return rc, errors
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/__init__.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/__init__.py     Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,2 @@
+
+
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/acm/__init__.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/acm/__init__.py Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,1 @@
+ 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/acm/acm.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/acm/acm.py      Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,1319 @@
+#===========================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 International Business Machines Corp.
+# Author: Reiner Sailer
+# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx>
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+#============================================================================
+
+import commands
+import logging
+import os, string, re
+import threading
+import struct
+import stat
+from xen.lowlevel import acm
+from xen.xend import sxp
+from xen.xend import XendConstants
+from xen.xend.XendLogging import log
+from xen.xend.XendError import VmError
+from xen.util import dictio, xsconstants
+from xen.xend.XendConstants import *
+
+#global directories and tools for security management
+policy_dir_prefix = "/etc/xen/acm-security/policies"
+res_label_filename = policy_dir_prefix + "/resource_labels"
+boot_filename = "/boot/grub/menu.lst"
+altboot_filename = "/boot/grub/grub.conf"
+xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
+xensec_tool = "/usr/sbin/xensec_tool"
+
+#global patterns for map file
+#police_reference_tagname = "POLICYREFERENCENAME"
+primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
+secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
+label_template_re =  re.compile(".*security_label_template.xml", re.IGNORECASE)
+mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
+policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", 
re.IGNORECASE)
+vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
+res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
+all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
+access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
+
+#global patterns for boot configuration file
+xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
+any_title_re = re.compile("\s*title\s", re.IGNORECASE)
+xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
+kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
+any_module_re = re.compile("\s*module\s", re.IGNORECASE)
+empty_line_re = re.compile("^\s*$")
+binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
+policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
+
+#decision hooks known to the hypervisor
+ACMHOOK_sharing = 1
+ACMHOOK_authorization = 2
+
+#other global variables
+NULL_SSIDREF = 0
+
+#general Rlock for map files; only one lock for all mapfiles
+__mapfile_lock = threading.RLock()
+__resfile_lock = threading.RLock()
+
+log = logging.getLogger("xend.util.security")
+
+# Our own exception definition. It is masked (pass) if raised and
+# whoever raises this exception must provide error information.
+class ACMError(Exception):
+    def __init__(self,value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+
+
+def err(msg):
+    """Raise ACM exception.
+    """
+    raise ACMError(msg)
+
+
+
+active_policy = None
+
+
+def mapfile_lock():
+    __mapfile_lock.acquire()
+
+def mapfile_unlock():
+    __mapfile_lock.release()
+
+
+def refresh_security_policy():
+    """
+    retrieves security policy
+    """
+    global active_policy
+
+    try:
+        active_policy = acm.policy()
+    except:
+        active_policy = "INACTIVE"
+
+# now set active_policy
+refresh_security_policy()
+
+def on():
+    """
+    returns none if security policy is off (not compiled),
+    any string otherwise, use it: if not security.on() ...
+    """
+    refresh_security_policy()
+    return (active_policy not in ['INACTIVE', 'NULL'])
+
+
+def calc_dom_ssidref_from_info(info):
+    """
+       Calculate a domain's ssidref from the security_label in its
+       info.
+       This function is called before the domain is started and
+       makes sure that:
+        - the type of the policy is the same as indicated in the label
+        - the name of the policy is the same as indicated in the label
+        - calculates an up-to-date ssidref for the domain
+       The latter is necessary since the domain's ssidref could have
+       changed due to changes to the policy.
+    """
+    import xen.xend.XendConfig
+    if isinstance(info, xen.xend.XendConfig.XendConfig):
+        if info.has_key('security_label'):
+            seclab = info['security_label']
+            tmp = seclab.split(":")
+            if len(tmp) != 3:
+                raise VmError("VM label '%s' in wrong format." % seclab)
+            typ, policyname, vmlabel = seclab.split(":")
+            if typ != xsconstants.ACM_POLICY_ID:
+                raise VmError("Policy type '%s' must be changed." % typ)
+            refresh_security_policy()
+            if active_policy != policyname:
+                raise VmError("Active policy '%s' different than "
+                              "what in VM's label ('%s')." %
+                              (active_policy, policyname))
+            ssidref = label2ssidref(vmlabel, policyname, "dom")
+            return ssidref
+        else:
+            return 0x0
+    raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
+                  "not supported." % type(info))
+
+
+def getmapfile(policyname):
+    """
+    in: if policyname is None then the currently
+    active hypervisor policy is used
+    out: 1. primary policy, 2. secondary policy,
+    3. open file descriptor for mapping file, and
+    4. True if policy file is available, False otherwise
+    """
+    if not policyname:
+        policyname = active_policy
+    map_file_ok = False
+    primary = None
+    secondary = None
+    #strip last part of policy as file name part
+    policy_dir_list = string.split(policyname, ".")
+    policy_file = policy_dir_list.pop()
+    if len(policy_dir_list) > 0:
+        policy_dir = string.join(policy_dir_list, "/") + "/"
+    else:
+        policy_dir = ""
+
+    map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
+    # check if it is there, if not check if policy file is there
+    if not os.path.isfile(map_filename):
+        policy_filename =  policy_dir_prefix + "/" + policy_dir + policy_file 
+ "-security_policy.xml"
+        if not os.path.isfile(policy_filename):
+            err("Policy file \'" + policy_filename + "\' not found.")
+        else:
+            err("Mapping file \'" + map_filename + "\' not found." +
+                " Use xm makepolicy to create it.")
+
+    f = open(map_filename)
+    for line in f:
+        if policy_reference_entry_re.match(line):
+            l = line.split()
+            if (len(l) == 2) and (l[1] == policyname):
+                map_file_ok = True
+        elif primary_entry_re.match(line):
+            l = line.split()
+            if len(l) == 2:
+                primary = l[1]
+        elif secondary_entry_re.match(line):
+            l = line.split()
+            if len(l) == 2:
+                secondary = l[1]
+    f.close()
+    f = open(map_filename)
+    if map_file_ok and primary and secondary:
+        return (primary, secondary, f, True)
+    else:
+        err("Mapping file inconsistencies found. Try makepolicy to create a 
new one.")
+
+
+
+def ssidref2label(ssidref_var):
+    """
+    returns labelname corresponding to ssidref;
+    maps current policy to default directory
+    to find mapping file
+    """
+    #1. translated permitted input formats
+    if isinstance(ssidref_var, str):
+        ssidref_var.strip()
+        if ssidref_var[0:2] == "0x":
+            ssidref = int(ssidref_var[2:], 16)
+        else:
+            ssidref = int(ssidref_var)
+    elif isinstance(ssidref_var, int):
+        ssidref = ssidref_var
+    else:
+        err("Instance type of ssidref not supported (must be of type 'str' or 
'int')")
+
+    if ssidref == 0:
+        from xen.util.acmpolicy import ACM_LABEL_UNLABELED
+        return ACM_LABEL_UNLABELED
+
+    try:
+        mapfile_lock()
+
+        (primary, secondary, f, pol_exists) = getmapfile(None)
+        if not f:
+            if (pol_exists):
+                err("Mapping file for policy not found.\n" +
+                    "Please use makepolicy command to create mapping file!")
+            else:
+                err("Policy file for \'" + active_policy + "\' not found.")
+
+        #2. get labelnames for both ssidref parts
+        pri_ssid = ssidref & 0xffff
+        sec_ssid = ssidref >> 16
+        pri_null_ssid = NULL_SSIDREF & 0xffff
+        sec_null_ssid = NULL_SSIDREF >> 16
+        pri_labels = []
+        sec_labels = []
+        labels = []
+
+        for line in f:
+            l = line.split()
+            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
+                continue
+            if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
+                pri_labels.append(l[3])
+            if secondary and (l[2] == secondary) and (int(l[4], 16) == 
sec_ssid):
+                sec_labels.append(l[3])
+        f.close()
+    finally:
+        mapfile_unlock()
+
+    #3. get the label that is in both lists (combination must be a single 
label)
+    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != 
sec_null_ssid):
+        labels = sec_labels
+    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid 
== sec_null_ssid):
+        labels = pri_labels
+    elif secondary == "NULL":
+        labels = pri_labels
+    else:
+        for i in pri_labels:
+            for j in sec_labels:
+                if (i==j):
+                    labels.append(i)
+    if len(labels) != 1:
+        err("Label for ssidref \'" +  str(ssidref) +
+            "\' unknown or not unique in policy \'" + active_policy + "\'")
+
+    return labels[0]
+
+
+
+def label2ssidref(labelname, policyname, typ):
+    """
+    returns ssidref corresponding to labelname;
+    maps current policy to default directory
+    to find mapping file    """
+
+    if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
+        err("Cannot translate labels for \'" + policyname + "\' policy.")
+
+    allowed_types = ['ANY']
+    if typ == 'dom':
+        allowed_types.append('VM')
+    elif typ == 'res':
+        allowed_types.append('RES')
+    else:
+        err("Invalid type.  Must specify 'dom' or 'res'.")
+
+    try:
+        mapfile_lock()
+        (primary, secondary, f, pol_exists) = getmapfile(policyname)
+
+        #2. get labelnames for ssidref parts and find a common label
+        pri_ssid = []
+        sec_ssid = []
+        for line in f:
+            l = line.split()
+            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
+                continue
+            if primary and (l[1] in allowed_types) and \
+                           (l[2] == primary) and \
+                           (l[3] == labelname):
+                pri_ssid.append(int(l[4], 16))
+            if secondary and (l[1] in allowed_types) and \
+                             (l[2] == secondary) and \
+                             (l[3] == labelname):
+                sec_ssid.append(int(l[4], 16))
+        f.close()
+        if (typ == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
+            pri_ssid.append(NULL_SSIDREF)
+        elif (typ == 'res') and (secondary == "CHWALL") and \
+             (len(sec_ssid) == 0):
+            sec_ssid.append(NULL_SSIDREF)
+
+        #3. sanity check and composition of ssidref
+        if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and \
+            (secondary != "NULL")):
+            err("Label \'" + labelname + "\' not found.")
+        elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
+            err("Label \'" + labelname + "\' not unique in policy (policy 
error)")
+        if secondary == "NULL":
+            return pri_ssid[0]
+        else:
+            return (sec_ssid[0] << 16) | pri_ssid[0]
+    finally:
+       mapfile_unlock()
+
+
+def refresh_ssidref(config):
+    """
+    looks up ssidref from security field
+    and refreshes the value if label exists
+    """
+    #called by dom0, policy could have changed after xen.utils.security was 
initialized
+    refresh_security_policy()
+
+    security = None
+    if isinstance(config, dict):
+        security = config['security']
+    elif isinstance(config, list):
+        security = sxp.child_value(config, 'security')
+    else:
+        err("Instance type of config parameter not supported.")
+    if not security:
+        #nothing to do (no security label attached)
+        return config
+
+    policyname = None
+    labelname = None
+    # compose new security field
+    for idx in range(0, len(security)):
+        if security[idx][0] == 'ssidref':
+            security.pop(idx)
+            break
+        elif security[idx][0] == 'access_control':
+            for jdx in [1, 2]:
+                if security[idx][jdx][0] == 'label':
+                    labelname = security[idx][jdx][1]
+                elif security[idx][jdx][0] == 'policy':
+                    policyname = security[idx][jdx][1]
+                else:
+                    err("Illegal field in access_control")
+    #verify policy is correct
+    if active_policy != policyname:
+        err("Policy \'" + str(policyname) +
+            "\' in label does not match active policy \'"
+            + str(active_policy) +"\'!")
+
+    new_ssidref = label2ssidref(labelname, policyname, 'dom')
+    if not new_ssidref:
+        err("SSIDREF refresh failed!")
+
+    security.append([ 'ssidref',str(new_ssidref)])
+    security = ['security', security ]
+
+    for idx in range(0,len(config)):
+        if config[idx][0] == 'security':
+            config.pop(idx)
+            break
+        config.append(security)
+
+
+
+def get_ssid(domain):
+    """
+    enables domains to retrieve the label / ssidref of a running domain
+    """
+    if not on():
+        err("No policy active.")
+
+    if isinstance(domain, str):
+        domain_int = int(domain)
+    elif isinstance(domain, int):
+        domain_int = domain
+    else:
+        err("Illegal parameter type.")
+    try:
+        ssid_info = acm.getssid(int(domain_int))
+    except:
+        err("Cannot determine security information.")
+
+    if active_policy in ["DEFAULT"]:
+        label = "DEFAULT"
+    else:
+        label = ssidref2label(ssid_info["ssidref"])
+    return(ssid_info["policyreference"],
+           label,
+           ssid_info["policytype"],
+           ssid_info["ssidref"])
+
+
+
+def get_decision(arg1, arg2):
+    """
+    enables domains to retrieve access control decisions from
+    the hypervisor Access Control Module.
+    IN: args format = ['domid', id] or ['ssidref', ssidref]
+    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
+    """
+
+    if not on():
+        err("No policy active.")
+
+    #translate labels before calling low-level function
+    if arg1[0] == 'access_control':
+        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] 
!= 'type'):
+            err("Argument type not supported.")
+        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
+        arg1 = ['ssidref', str(ssidref)]
+    if arg2[0] == 'access_control':
+        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] 
!= 'type'):
+            err("Argument type not supported.")
+        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
+        arg2 = ['ssidref', str(ssidref)]
+
+    # accept only int or string types for domid and ssidref
+    if isinstance(arg1[1], int):
+        arg1[1] = str(arg1[1])
+    if isinstance(arg2[1], int):
+        arg2[1] = str(arg2[1])
+    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
+        err("Invalid id or ssidref type, string or int required")
+
+    try:
+        decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1],
+                                   ACMHOOK_sharing)
+    except:
+        err("Cannot determine decision.")
+
+    if decision:
+        return decision
+    else:
+        err("Cannot determine decision (Invalid parameter).")
+
+
+def has_authorization(ssidref):
+    """ Check if the domain with the given ssidref has authorization to
+        run on this system. To have authoriztion dom0's STE types must
+        be a superset of that of the domain's given through its ssidref.
+    """
+    rc = True
+    dom0_ssidref = int(acm.getssid(0)['ssidref'])
+    decision = acm.getdecision('ssidref', str(dom0_ssidref),
+                               'ssidref', str(ssidref),
+                               ACMHOOK_authorization)
+    if decision == "DENIED":
+        rc = False
+    return rc
+
+
+def hv_chg_policy(bin_pol, del_array, chg_array):
+    """
+        Change the binary policy in the hypervisor
+        The 'del_array' and 'chg_array' give hints about deleted ssidrefs
+        and changed ssidrefs which can be due to deleted VM labels
+        or reordered VM labels
+    """
+    rc = -xsconstants.XSERR_GENERAL_FAILURE
+    errors = ""
+    if not on():
+        err("No policy active.")
+    try:
+        rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
+    except Exception, e:
+        pass
+    if len(errors) > 0:
+        rc = -xsconstants.XSERR_HV_OP_FAILED
+    return rc, errors
+
+
+def make_policy(policy_name):
+    policy_file = string.join(string.split(policy_name, "."), "/")
+    if not os.path.isfile(policy_dir_prefix + "/" + policy_file + 
"-security_policy.xml"):
+        err("Unknown policy \'" + policy_name + "\'")
+
+    (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + 
policy_dir_prefix + " " + policy_file)
+    if ret:
+        err("Creating policy failed:\n" + output)
+
+def load_policy(policy_name):
+    global active_policy
+    policy_file = policy_dir_prefix + "/" + 
string.join(string.split(policy_name, "."), "/")
+    if not os.path.isfile(policy_file + ".bin"):
+        if os.path.isfile(policy_file + "-security_policy.xml"):
+            err("Binary file does not exist." +
+                "Please use makepolicy to build the policy binary.")
+        else:
+            err("Unknown Policy " + policy_name)
+
+    #require this policy to be the first or the same as installed
+    if active_policy not in ['DEFAULT', policy_name]:
+        err("Active policy \'" + active_policy +
+            "\' incompatible with new policy \'" + policy_name + "\'")
+    (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + 
policy_file + ".bin")
+    if ret:
+        err("Loading policy failed:\n" + output)
+    else:
+        # refresh active policy
+        refresh_security_policy()
+
+
+
+def dump_policy():
+    if active_policy in ['NULL', 'INACTIVE']:
+        err("\'" + active_policy + "\' policy. Nothing to dump.")
+
+    (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
+    if ret:
+       err("Dumping hypervisor policy failed:\n" + output)
+    print output
+
+
+
+def list_labels(policy_name, condition):
+    if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", 
"DEFAULT"]:
+        err("Current policy \'" + active_policy + "\' has no labels 
defined.\n")
+
+    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
+    if not f:
+        if pol_exists:
+            err("Cannot find mapfile for policy \'" + policy_name +
+                "\'.\nPlease use makepolicy to create mapping file.")
+        else:
+            err("Unknown policy \'" + policy_name + "\'")
+
+    labels = []
+    for line in f:
+        if condition.match(line):
+            label = line.split()[3]
+            if label not in labels:
+                labels.append(label)
+    return labels
+
+
+def get_res_label(resource):
+    """Returns resource label information (policytype, label, policy) if
+       it exists. Otherwise returns null label and policy.
+    """
+    def default_res_label():
+        ssidref = NULL_SSIDREF
+        if on():
+            label = ssidref2label(ssidref)
+        else:
+            label = None
+        return (xsconstants.ACM_POLICY_ID, 'NULL', label)
+
+
+    tmp = get_resource_label(resource)
+    if len(tmp) == 2:
+        policytype = xsconstants.ACM_POLICY_ID
+        policy, label = tmp
+    elif len(tmp) == 3:
+        policytype, policy, label = tmp
+    else:
+        policytype, policy, label = default_res_label()
+
+    return (policytype, label, policy)
+
+
+def get_res_security_details(resource):
+    """Returns the (label, ssidref, policy) associated with a given
+       resource from the global resource label file.
+    """
+    def default_security_details():
+        ssidref = NULL_SSIDREF
+        if on():
+            label = ssidref2label(ssidref)
+        else:
+            label = None
+        policy = active_policy
+        return (label, ssidref, policy)
+
+    (label, ssidref, policy) = default_security_details()
+
+    # find the entry associated with this resource
+    (policytype, label, policy) = get_res_label(resource)
+    if policy == 'NULL':
+        log.info("Resource label for "+resource+" not in file, using DEFAULT.")
+        return default_security_details()
+
+    # is this resource label for the running policy?
+    if policy == active_policy:
+        ssidref = label2ssidref(label, policy, 'res')
+    else:
+        log.info("Resource label not for active policy, using DEFAULT.")
+        return default_security_details()
+
+    return (label, ssidref, policy)
+
+def security_label_to_details(seclab):
+    """ Convert a Xen-API type of security label into details """
+    def default_security_details():
+        ssidref = NULL_SSIDREF
+        if on():
+            label = ssidref2label(ssidref)
+        else:
+            label = None
+        policy = active_policy
+        return (label, ssidref, policy)
+
+    (policytype, policy, label) = seclab.split(":")
+
+    # is this resource label for the running policy?
+    if policy == active_policy:
+        ssidref = label2ssidref(label, policy, 'res')
+    else:
+        log.info("Resource label not for active policy, using DEFAULT.")
+        return default_security_details()
+
+    return (label, ssidref, policy)
+
+def unify_resname(resource, mustexist=True):
+    """Makes all resource locations absolute. In case of physical
+    resources, '/dev/' is added to local file names"""
+
+    if not resource:
+        return resource
+
+    # sanity check on resource name
+    try:
+        (typ, resfile) = resource.split(":", 1)
+    except:
+        err("Resource spec '%s' contains no ':' delimiter" % resource)
+
+    if typ == "tap":
+        try:
+            (subtype, resfile) = resfile.split(":")
+        except:
+            err("Resource spec '%s' contains no tap subtype" % resource)
+
+    import os
+    if typ in ["phy", "tap"]:
+        if not resfile.startswith("/"):
+            resfile = "/dev/" + resfile
+        if mustexist:
+            stats = os.lstat(resfile)
+            if stat.S_ISLNK(stats[stat.ST_MODE]):
+                resolved = os.readlink(resfile)
+                if resolved[0] != "/":
+                    resfile = os.path.join(os.path.dirname(resfile), resolved)
+                    resfile = os.path.abspath(resfile)
+                else:
+                    resfile = resolved
+                stats = os.lstat(resfile)
+            if not (stat.S_ISBLK(stats[stat.ST_MODE])):
+                err("Invalid resource")
+
+    if typ in [ "file", "tap" ]:
+        if mustexist:
+            stats = os.lstat(resfile)
+            if stat.S_ISLNK(stats[stat.ST_MODE]):
+                resfile = os.readlink(resfile)
+                stats = os.lstat(resfile)
+            if not stat.S_ISREG(stats[stat.ST_MODE]):
+                err("Invalid resource")
+
+    #file: resources must specified with absolute path
+    #vlan resources don't start with '/'
+    if typ != "vlan":
+        if (not resfile.startswith("/")) or \
+           (mustexist and not os.path.exists(resfile)):
+            err("Invalid resource.")
+
+    # from here on absolute file names with resources
+    if typ == "tap":
+        typ = typ + ":" + subtype
+    resource = typ + ":" + resfile
+    return resource
+
+
+def res_security_check(resource, domain_label):
+    """Checks if the given resource can be used by the given domain
+       label.  Returns 1 if the resource can be used, otherwise 0.
+    """
+    rtnval = 1
+
+    # if security is on, ask the hypervisor for a decision
+    if on():
+        #build canonical resource name
+        resource = unify_resname(resource)
+
+        (label, ssidref, policy) = get_res_security_details(resource)
+        domac = ['access_control']
+        domac.append(['policy', active_policy])
+        domac.append(['label', domain_label])
+        domac.append(['type', 'dom'])
+        decision = get_decision(domac, ['ssidref', str(ssidref)])
+
+        # provide descriptive error messages
+        if decision == 'DENIED':
+            if label == ssidref2label(NULL_SSIDREF):
+                raise ACMError("Resource '"+resource+"' is not labeled")
+                rtnval = 0
+            else:
+                raise ACMError("Permission denied for resource '"+resource+"' 
because label '"+label+"' is not allowed")
+                rtnval = 0
+
+    # security is off, make sure resource isn't labeled
+    else:
+        # Note, we can't canonicalise the resource here, because people using
+        # xm without ACM are free to use relative paths.
+        (policytype, label, policy) = get_res_label(resource)
+        if policy != 'NULL':
+            raise ACMError("Security is off, but '"+resource+"' is labeled")
+            rtnval = 0
+
+    return rtnval
+
+def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
+    """Checks if the given resource can be used by the given domain
+       label.  Returns 1 if the resource can be used, otherwise 0.
+    """
+    rtnval = 1
+    # if security is on, ask the hypervisor for a decision
+    if on():
+        typ, dpolicy, domain_label = xapi_dom_label.split(":")
+        if not dpolicy or not domain_label:
+            raise VmError("VM security label in wrong format.")
+        if active_policy != rpolicy:
+            raise VmError("Resource's policy '%s' != active policy '%s'" %
+                          (rpolicy, active_policy))
+        domac = ['access_control']
+        domac.append(['policy', active_policy])
+        domac.append(['label', domain_label])
+        domac.append(['type', 'dom'])
+        decision = get_decision(domac, ['ssidref', str(rssidref)])
+
+        log.info("Access Control Decision : %s" % decision)
+        # provide descriptive error messages
+        if decision == 'DENIED':
+            if rlabel == ssidref2label(NULL_SSIDREF):
+                #raise ACMError("Resource is not labeled")
+                rtnval = 0
+            else:
+                #raise ACMError("Permission denied for resource because label 
'"+rlabel+"' is not allowed")
+                rtnval = 0
+
+    # security is off, make sure resource isn't labeled
+    else:
+        # Note, we can't canonicalise the resource here, because people using
+        # xm without ACM are free to use relative paths.
+        if rpolicy != 'NULL':
+            #raise ACMError("Security is off, but resource is labeled")
+            rtnval = 0
+
+    return rtnval
+
+
+def validate_label(label, policyref):
+    """
+       Make sure that this label is part of the currently enforced policy
+       and that it reference the current policy.
+    """
+    rc = xsconstants.XSERR_SUCCESS
+    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+    curpol = XSPolicyAdminInstance().get_loaded_policy()
+    if not curpol or curpol.get_name() != policyref:
+        rc = -xsconstants.XSERR_BAD_LABEL
+    else:
+        try:
+            label2ssidref(label, curpol.get_name() , 'res')
+        except:
+            rc = -xsconstants.XSERR_BAD_LABEL
+    return rc
+
+
+def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
+    """Assign a resource label to a resource
+    @param resource: The name of a resource, i.e., "phy:/dev/hda", or
+              "tap:qcow:/path/to/file.qcow"
+
+    @param reslabel_xapi: A resource label foramtted as in all other parts of
+                          the Xen-API, i.e., ACM:xm-test:blue"
+    @rtype: int
+    @return Success (0) or failure value (< 0)
+    """
+    olabel = ""
+    if reslabel_xapi == "":
+        return rm_resource_label(resource, oldlabel_xapi)
+    typ, policyref, label = reslabel_xapi.split(":")
+    if typ != xsconstants.ACM_POLICY_ID:
+        return -xsconstants.XSERR_WRONG_POLICY_TYPE
+    if not policyref or not label:
+        return -xsconstants.XSERR_BAD_LABEL_FORMAT
+    if oldlabel_xapi not in [ "" ]:
+        tmp = oldlabel_xapi.split(":")
+        if len(tmp) != 3:
+            return -xsconstants.XSERR_BAD_LABEL_FORMAT
+        otyp, opolicyref, olabel = tmp
+        # Only ACM is supported
+        if otyp != xsconstants.ACM_POLICY_ID  and \
+           otyp != xsconstants.INVALID_POLICY_PREFIX + \
+                   xsconstants.ACM_POLICY_ID:
+            return -xsconstants.XSERR_WRONG_POLICY_TYPE
+    rc = validate_label(label, policyref)
+    if rc != xsconstants.XSERR_SUCCESS:
+        return rc
+    return set_resource_label(resource, typ, policyref, label, olabel)
+
+
+def is_resource_in_use(resource):
+    """
+       Domain-0 'owns' resources of type 'VLAN', the rest are owned by
+       the guests.
+    """
+    from xen.xend import XendDomain
+    lst = []
+    if resource.startswith('vlan'):
+        from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+        curpol = XSPolicyAdminInstance().get_loaded_policy()
+        policytype, label, policy = get_res_label(resource)
+        if curpol and \
+           policytype == xsconstants.ACM_POLICY_ID and \
+           policy == curpol.get_name() and \
+           label in curpol.policy_get_resourcelabel_names():
+            # VLAN is in use.
+            lst.append(XendDomain.instance().
+                         get_vm_by_uuid(XendDomain.DOM0_UUID))
+    else:
+        dominfos = XendDomain.instance().list('all')
+        for dominfo in dominfos:
+            if is_resource_in_use_by_dom(dominfo, resource):
+                lst.append(dominfo)
+    return lst
+
+def devices_equal(res1, res2, mustexist=True):
+    """ Determine whether two devices are equal """
+    return (unify_resname(res1, mustexist) ==
+            unify_resname(res2, mustexist))
+
+def is_resource_in_use_by_dom(dominfo, resource):
+    """ Determine whether a resources is in use by a given domain
+        @return True or False
+    """
+    if not dominfo.domid:
+        return False
+    if dominfo._stateGet() not in [ DOM_STATE_RUNNING ]:
+        return False
+    devs = dominfo.info['devices']
+    uuids = devs.keys()
+    for uuid in uuids:
+        dev = devs[uuid]
+        if len(dev) >= 2 and dev[1].has_key('uname'):
+            # dev[0] is type, i.e. 'vbd'
+            if devices_equal(dev[1]['uname'], resource, mustexist=False):
+                log.info("RESOURCE IN USE: Domain %d uses %s." %
+                         (dominfo.domid, resource))
+                return True
+    return False
+
+
+def get_domain_resources(dominfo):
+    """ Collect all resources of a domain in a map where each entry of
+        the map is a list.
+        Entries are strored in the following formats:
+          tap:qcow:/path/xyz.qcow
+    """
+    resources = { 'vbd' : [], 'tap' : [], 'vif' : []}
+    devs = dominfo.info['devices']
+    uuids = devs.keys()
+    for uuid in uuids:
+        dev = devs[uuid]
+        typ = dev[0]
+        if typ in [ 'vbd', 'tap' ]:
+            resources[typ].append(dev[1]['uname'])
+        if typ in [ 'vif' ]:
+            sec_lab = dev[1].get('security_label')
+            if sec_lab:
+                resources[typ].append(sec_lab)
+            else:
+                # !!! This should really get the label of the domain
+                # or at least a resource label that has the same STE type
+                # as the domain has
+                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
+                resources[typ].append("%s:%s:%s" %
+                                      (xsconstants.ACM_POLICY_ID,
+                                       active_policy,
+                                       ACM_LABEL_UNLABELED))
+
+    return resources
+
+
+def resources_compatible_with_vmlabel(xspol, dominfo, vmlabel):
+    """
+       Check whether the resources' labels are compatible with the
+       given VM label. This is a function to be used when for example
+       a running domain is to get the new label 'vmlabel'
+    """
+    if not xspol:
+        return False
+
+    try:
+        __resfile_lock.acquire()
+        try:
+            access_control = dictio.dict_read("resources",
+                                              res_label_filename)
+        except:
+            # No labeled resources -> must be compatible
+            return True
+        return __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
+                                                   access_control)
+    finally:
+        __resfile_lock.release()
+    return False
+
+
+def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
+                                        access_control,
+                                        is_policy_update=False):
+    """
+        Check whether the resources' labels are compatible with the
+        given VM label. The access_control parameter provides a
+        dictionary of the resource name to resource label mappings
+        under which the evaluation should be done.
+        Call this only for a paused or running domain.
+    """
+    def collect_labels(reslabels, s_label, polname):
+        if len(s_label) != 3 or polname != s_label[1]:
+            return False
+        label = s_label[2]
+        if not label in reslabels:
+            reslabels.append(label)
+        return True
+
+    resources = get_domain_resources(dominfo)
+    reslabels = []  # all resource labels
+
+    polname = xspol.get_name()
+    for key, value in resources.items():
+        if key in [ 'vbd', 'tap' ]:
+            for res in resources[key]:
+                try:
+                    label = access_control[res]
+                    if not collect_labels(reslabels, label, polname):
+                        return False
+                except:
+                    return False
+        elif key in [ 'vif' ]:
+            for xapi_label in value:
+                label = xapi_label.split(":")
+                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
+                if not (is_policy_update and \
+                        label[2] == ACM_LABEL_UNLABELED):
+                    if not collect_labels(reslabels, label, polname):
+                        return False
+        else:
+            log.error("Unhandled device type: %s" % key)
+            return False
+
+    # Check that all resource labes have a common STE type with the
+    # vmlabel
+    if len(reslabels) > 0:
+        rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
+    else:
+        rc = True
+    log.info("vmlabel=%s, reslabels=%s, rc=%s" %
+             (vmlabel, reslabels, str(rc)))
+    return rc;
+
+def set_resource_label(resource, policytype, policyref, reslabel, \
+                       oreslabel = None):
+    """Assign a label to a resource
+       If the old label (oreslabel) is given, then the resource must have
+       that old label.
+       A resource label may be changed if
+       - the resource is not in use
+    @param resource  : The name of a resource, i.e., "phy:/dev/hda"
+    @param policyref : The name of the policy
+    @param reslabel     : the resource label within the policy
+    @param oreslabel    : optional current resource label
+
+    @rtype: int
+    @return Success (0) or failure value (< 0)
+    """
+    try:
+        resource = unify_resname(resource, mustexist=False)
+    except Exception:
+        return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
+
+    domains = is_resource_in_use(resource)
+    if len(domains) > 0:
+        return -xsconstants.XSERR_RESOURCE_IN_USE
+
+    try:
+        __resfile_lock.acquire()
+        access_control = {}
+        try:
+             access_control = dictio.dict_read("resources", res_label_filename)
+        except:
+            pass
+        if oreslabel:
+            if not access_control.has_key(resource):
+                return -xsconstants.XSERR_BAD_LABEL
+            tmp = access_control[resource]
+            if len(tmp) != 3:
+                return -xsconstants.XSERR_BAD_LABEL
+            if tmp[2] != oreslabel:
+                return -xsconstants.XSERR_BAD_LABEL
+        if reslabel != "":
+            new_entry = { resource : tuple([policytype, policyref, reslabel])}
+            access_control.update(new_entry)
+        else:
+            if access_control.has_key(resource):
+                del access_control[resource]
+        dictio.dict_write(access_control, "resources", res_label_filename)
+    finally:
+        __resfile_lock.release()
+    return xsconstants.XSERR_SUCCESS
+
+def rm_resource_label(resource, oldlabel_xapi):
+    """Remove a resource label from a physical resource
+    @param resource: The name of a resource, i.e., "phy:/dev/hda"
+
+    @rtype: int
+    @return Success (0) or failure value (< 0)
+    """
+    tmp = oldlabel_xapi.split(":")
+    if len(tmp) != 3:
+        return -xsconstants.XSERR_BAD_LABEL_FORMAT
+    otyp, opolicyref, olabel = tmp
+    # Only ACM is supported
+    if otyp != xsconstants.ACM_POLICY_ID and \
+       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:
+        return -xsconstants.XSERR_WRONG_POLICY_TYPE
+    return set_resource_label(resource, "", "", "", olabel)
+
+def get_resource_label_xapi(resource):
+    """Get the assigned resource label of a physical resource
+      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"
+
+      @rtype: string
+      @return the string representing policy type, policy name and label of
+              the resource
+    """
+    res = get_resource_label(resource)
+    return format_resource_label(res)
+
+def format_resource_label(res):
+    if res:
+        if len(res) == 2:
+            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]
+        if len(res) == 3:
+            return ":".join(res)
+    return ""
+
+def get_resource_label(resource):
+    """Get the assigned resource label of a given resource
+    @param resource: The name of a resource, i.e., "phy:/dev/hda"
+
+    @rtype: list
+    @return tuple of (policy name, resource label), i.e., (xm-test, blue)
+    """
+    try:
+        resource = unify_resname(resource, mustexist=False)
+    except Exception:
+        return []
+
+    reslabel_map = get_labeled_resources()
+
+    if reslabel_map.has_key(resource):
+        return list(reslabel_map[resource])
+    else:
+        #Try to resolve each label entry
+        for key, value in reslabel_map.items():
+            try:
+                if resource == unify_resname(key):
+                    return list(value)
+            except:
+                pass
+
+    return []
+
+
+def get_labeled_resources_xapi():
+    """ Get a map of all labeled resource with the labels formatted in the
+        xen-api resource label format.
+    """
+    reslabel_map = get_labeled_resources()
+    for key, labeldata in reslabel_map.items():
+        reslabel_map[key] = format_resource_label(labeldata)
+    return reslabel_map
+
+
+def get_labeled_resources():
+    """Get a map of all labeled resources
+    @rtype: list
+    @return list of labeled resources
+    """
+    try:
+        __resfile_lock.acquire()
+        try:
+            access_control = dictio.dict_read("resources", res_label_filename)
+        except:
+            return {}
+    finally:
+        __resfile_lock.release()
+    return access_control
+
+
+def relabel_domains(relabel_list):
+    """
+      Relabel the given domains to have a new ssidref.
+      @param relabel_list: a list containing tuples of domid, ssidref
+                           example: [ [0, 0x00020002] ]
+    """
+    rel_rules = ""
+    for r in relabel_list:
+        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",
+                r[0], r[1])
+        rel_rules += struct.pack("ii", r[0], r[1])
+    try:
+        rc, errors = acm.relabel_domains(rel_rules)
+    except Exception, e:
+        log.info("Error after relabel_domains: %s" % str(e))
+        rc = -xsconstants.XSERR_GENERAL_FAILURE
+        errors = ""
+    if (len(errors) > 0):
+        rc = -xsconstants.XSERR_HV_OP_FAILED
+    return rc, errors
+
+
+def change_acm_policy(bin_pol, del_array, chg_array,
+                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):
+    """
+       Change the ACM policy of the system by relabeling
+       domains and resources first and doing some access checks.
+       Then update the policy in the hypervisor. If this is all successful,
+       relabel the domains permanently and commit the relabed resources.
+
+       Need to do / check the following:
+        - relabel all resources where there is a 'from' field in
+          the policy. [ NOT DOING THIS: and mark those as unlabeled where the 
label
+          does not appear in the new policy anymore (deletion) ]
+        - relabel all VMs where there is a 'from' field in the
+          policy and mark those as unlabeled where the label
+          does not appear in the new policy anymore; no running
+          or paused VM may be unlabeled through this
+        - check that under the new labeling conditions the VMs
+          still have access to their resources as before. Unlabeled
+          resources are inaccessible. If this check fails, the
+          update failed.
+        - Attempt changes in the hypervisor; if this step fails,
+          roll back the relabeling of resources and VMs
+        - Make the relabeling of resources and VMs permanent
+    """
+    rc = xsconstants.XSERR_SUCCESS
+
+    domain_label_map = {}
+    new_policyname = new_acmpol.get_name()
+    new_policytype = new_acmpol.get_type_name()
+    cur_policyname = cur_acmpol.get_name()
+    cur_policytype = cur_acmpol.get_type_name()
+    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()
+    errors=""
+
+    try:
+        __resfile_lock.acquire()
+        mapfile_lock()
+
+        # Get all domains' dominfo.
+        from xen.xend import XendDomain
+        dominfos = XendDomain.instance().list('all')
+
+        log.info("----------------------------------------------")
+        # relabel resources
+
+        access_control = {}
+        try:
+            access_control = dictio.dict_read("resources", res_label_filename)
+        except:
+            pass
+        for key, labeldata in access_control.items():
+            if len(labeldata) == 2:
+                policy, label = labeldata
+                policytype = xsconstants.ACM_POLICY_ID
+            elif len(labeldata) == 3:
+                policytype, policy, label = labeldata
+            else:
+                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""
+
+            if policytype != cur_policytype or \
+               policy     != cur_policyname:
+                continue
+
+            # label been renamed or deleted?
+            if reslabel_map.has_key(label) and cur_policyname == policy:
+                label = reslabel_map[label]
+            elif label not in polnew_reslabels:
+                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
+            # Update entry
+            access_control[key] = \
+                   tuple([ policytype, new_policyname, label ])
+
+        # All resources have new labels in the access_control map
+        # There may still be labels in there that are invalid now.
+
+        # Do this in memory without writing to disk:
+        #  - Relabel all domains independent of whether they are running
+        #    or not
+        #  - later write back to config files
+        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()
+
+        for dominfo in dominfos:
+            sec_lab = dominfo.get_security_label()
+            if not sec_lab:
+                continue
+            policytype, policy, vmlabel = sec_lab.split(":")
+            name  = dominfo.getName()
+
+            if policytype != cur_policytype or \
+               policy     != cur_policyname:
+                continue
+
+            new_vmlabel = vmlabel
+            if vmlabel_map.has_key(vmlabel):
+                new_vmlabel = vmlabel_map[vmlabel]
+            if new_vmlabel not in polnew_vmlabels:
+                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
+            new_seclab = "%s:%s:%s" % \
+                    (policytype, new_policyname, new_vmlabel)
+
+            domain_label_map[dominfo] = [ sec_lab, new_seclab ]
+
+            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
+                compatible = __resources_compatible_with_vmlabel(new_acmpol,
+                                                      dominfo,
+                                                      new_vmlabel,
+                                                      access_control,
+                                                      is_policy_update=True)
+                log.info("Domain %s with new label '%s' can access its "
+                         "resources? : %s" %
+                         (name, new_vmlabel, str(compatible)))
+                log.info("VM labels in new policy: %s" %
+                         new_acmpol.policy_get_virtualmachinelabel_names())
+                if not compatible:
+                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
+
+        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)
+        if rc == 0:
+            # Write the relabeled resources back into the file
+            dictio.dict_write(access_control, "resources", res_label_filename)
+            # Properly update all VMs to their new labels
+            for dominfo, labels in domain_label_map.items():
+                sec_lab, new_seclab = labels
+                if sec_lab != new_seclab:
+                    log.info("Updating domain %s to new label '%s'." % \
+                             (dominfo.getName(), new_seclab))
+                    # This better be working!
+                    res = dominfo.set_security_label(new_seclab,
+                                                     sec_lab,
+                                                     new_acmpol,
+                                                     cur_acmpol)
+                    if res[0] != xsconstants.XSERR_SUCCESS:
+                        log.info("ERROR: Could not chg label on domain %s: %s" 
%
+                                 (dominfo.getName(),
+                                  xsconstants.xserr2string(-int(res[0]))))
+    finally:
+        log.info("----------------------------------------------")
+        mapfile_unlock()
+        __resfile_lock.release()
+
+    return rc, errors
+
+def parse_security_label(security_label):
+    tmp = security_label.split(":")
+    if len(tmp) != 3:
+        return ""
+    else:
+        return security_label
+
+def set_security_label(policy, label):
+    policytype = xsconstants.ACM_POLICY_ID
+    if label != "" and policy != "":
+        return "%s:%s:%s" % (policytype, policy, label)
+    else:
+        return ""
+
+def ssidref2security_label(ssidref):
+    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+    return XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/dummy/__init__.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/dummy/__init__.py       Thu Sep 06 12:05:15 
2007 -0600
@@ -0,0 +1,1 @@
+ 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/dummy/dummy.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/dummy/dummy.py  Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,53 @@
+import sys
+
+class XSMError(Exception):
+    def __init__(self,value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+policy_dir_prefix = "";
+active_policy = "";
+NULL_SSIDREF = 0;
+
+def err(msg):
+    """Raise XSM-dummy exception.
+    """
+    sys.stderr.write("XSM-dummyError: " + msg + "\n")
+    raise XSMError(msg)
+
+def on():
+    return 0
+
+def ssidref2label(ssidref):
+    return 0
+
+def label2ssidref(label, policy, type):
+    return 0
+
+def res_security_check(resource, domain_label):
+    return 1
+
+def get_res_security_details(resource):
+    return ("","","")
+
+def get_res_label(resource):
+    return ("","")
+
+def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
+    return 1
+
+def parse_security_label(security_label):
+    return ""
+
+def calc_dom_ssidref_from_info(info):
+    return ""
+
+def set_security_label(policy, label):
+     return ""
+
+def ssidref2security_label(ssidref):
+    return ""
+
+def has_authorization(ssidref):
+    return True
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/flask/__init__.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/flask/__init__.py       Thu Sep 06 12:05:15 
2007 -0600
@@ -0,0 +1,1 @@
+ 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/flask/flask.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/flask/flask.py  Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,37 @@
+import sys
+from xen.lowlevel import flask
+from xen.xend import sxp
+
+def err(msg):
+    """Raise XSM-Flask exception.
+    """
+    sys.stderr.write("XSM-FlaskError: " + msg + "\n")
+    raise XSMError(msg)
+
+def on():
+    return 1
+
+def ssidref2label(ssidref):
+    try:
+        return flask.flask_sid_to_context(ssidref)
+    except:
+        return ""
+
+def label2ssidref(label, policy, type):
+    try:
+        return flask.flask_context_to_sid(label)
+    except:
+        return ""
+
+def parse_security_label(security_label):
+    return security_label
+
+def calc_dom_ssidref_from_info(info):
+    ssidref = label2ssidref(info['security_label'], "", "")
+    return ssidref
+
+def set_security_label(policy, label):
+    return label
+
+def ssidref2security_label(ssidref):
+    return ssidref2label(ssidref)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/util/xsm/xsm_core.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/xsm_core.py     Thu Sep 06 12:05:15 2007 -0600
@@ -0,0 +1,7 @@
+import sys
+import xen.util.xsm.dummy.dummy as dummy
+
+def xsm_init(self):
+    for op in dir(dummy):
+        if not hasattr(self, op):
+            setattr(self, op, getattr(dummy, op, None))
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py   Thu Sep 06 12:05:15 2007 -0600
@@ -16,7 +16,7 @@ import xen.util.auxbin
 import xen.util.auxbin
 import xen.lowlevel.xc
 
-from xen.xend import balloon, sxp
+from xen.xend import balloon, sxp, image
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendLogging import log
 from xen.xend.XendConfig import XendConfig
@@ -181,8 +181,6 @@ def restore(xd, fd, dominfo = None, paus
     assert store_port
     assert console_port
 
-    nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 
-
     # if hvm, pass mem size to calculate the store_mfn
     image_cfg = dominfo.info.get('image', {})
     is_hvm = dominfo.info.is_hvm()
@@ -196,18 +194,31 @@ def restore(xd, fd, dominfo = None, paus
         pae  = 0
 
     try:
-        shadow = dominfo.info['shadow_memory']
+        restore_image = image.create(dominfo, dominfo.info)
+        memory = restore_image.getRequiredAvailableMemory(
+            dominfo.info['memory_dynamic_max'] / 1024)
+        maxmem = restore_image.getRequiredAvailableMemory(
+            dominfo.info['memory_static_max'] / 1024)
+        shadow = restore_image.getRequiredShadowMemory(
+            dominfo.info['shadow_memory'] / 1024,
+            dominfo.info['memory_static_max'] / 1024)
+
         log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, ",
                   dominfo.info['shadow_memory'],
                   dominfo.info['memory_static_max'],
                   dominfo.info['memory_static_min'])
 
-        balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024)
-
-        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow)
+        # Round shadow up to a multiple of a MiB, as shadow_mem_control
+        # takes MiB and we must not round down and end up under-providing.
+        shadow = ((shadow + 1023) / 1024) * 1024
+
+        # set memory limit
+        xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
+
+        balloon.free(memory + shadow)
+
+        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow / 1024)
         dominfo.info['shadow_memory'] = shadow_cur
-
-        xc.domain_setmaxmem(dominfo.getDomid(), dominfo.getMemoryMaximum())
 
         cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
                         fd, dominfo.getDomid(),
@@ -219,7 +230,7 @@ def restore(xd, fd, dominfo = None, paus
         forkHelper(cmd, fd, handler.handler, True)
 
         # We don't want to pass this fd to any other children -- we 
-        # might need to recover ths disk space that backs it.
+        # might need to recover the disk space that backs it.
         try:
             flags = fcntl.fcntl(fd, fcntl.F_GETFD)
             flags |= fcntl.FD_CLOEXEC
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py       Thu Sep 06 12:05:15 2007 -0600
@@ -28,9 +28,9 @@ from xen.xend.XendDevices import XendDev
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
 from xen.xend.XendConstants import DOM_STATE_HALTED
+from xen.xend.server.BlktapController import blktap_disk_types
 from xen.xend.server.netif import randomMAC
 from xen.util.blkif import blkdev_name_to_number
-from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
 from xen.util import xsconstants
 
 log = logging.getLogger("xend.XendConfig")
@@ -433,7 +433,8 @@ class XendConfig(dict):
         self['cpu_time'] = dominfo['cpu_time']/1e9
         if dominfo.get('ssidref'):
             ssidref = int(dominfo.get('ssidref'))
-            self['security_label'] = 
XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
+            import xen.util.xsm.xsm as security
+            self['security_label'] = security.ssidref2security_label(ssidref)
 
         self['shutdown_reason'] = dominfo['shutdown_reason']
 
@@ -651,7 +652,6 @@ class XendConfig(dict):
                 #                     ['ssidref', 196611]]
                 policy = ""
                 label = ""
-                policytype = xsconstants.ACM_POLICY_ID
                 for idx in range(0, len(secinfo)):
                     if secinfo[idx][0] == "access_control":
                         for aidx in range(1, len(secinfo[idx])):
@@ -659,9 +659,10 @@ class XendConfig(dict):
                                 policy = secinfo[idx][aidx][1]
                             if secinfo[idx][aidx][0] == "label":
                                 label  = secinfo[idx][aidx][1]
-                if label != "" and policy != "":
-                    cfg['security_label'] = "%s:%s:%s" % \
-                            (policytype, policy, label)
+                import xen.util.xsm.xsm as security
+                cfg['security_label'] = \
+                    security.set_security_label(policy, label)
+                if not sxp.child_value(sxp_cfg, 'security_label'):
                     del cfg['security']
 
         old_state = sxp.child_value(sxp_cfg, 'state')
@@ -1084,6 +1085,11 @@ class XendConfig(dict):
                 else:
                     dev_info['driver'] = 'paravirtualised'
 
+            if dev_type == 'tap':
+                if dev_info['uname'].split(':')[1] not in blktap_disk_types:
+                    raise XendConfigError("tap:%s not a valid disk type" %
+                                    dev_info['uname'].split(':')[1])
+
             if dev_type == 'vif':
                 if not dev_info.get('mac'):
                     dev_info['mac'] = randomMAC()
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Sep 06 12:05:15 2007 -0600
@@ -36,7 +36,7 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
-from xen.util import security
+import xen.util.xsm.xsm as security
 
 from xen.xend import balloon, sxp, uuid, image, arch, osdep
 from xen.xend import XendOptions, XendNode, XendConfig
@@ -607,6 +607,9 @@ class XendDomainInfo:
                     _, dev_info = sxprs[dev]
             else:  # 'vbd' or 'tap'
                 dev_info = self.getDeviceInfo_vbd(dev)
+                # To remove the UUID of the device from refs,
+                # deviceClass must be always 'vbd'.
+                deviceClass = 'vbd'
             if dev_info is None:
                 return rc
 
@@ -981,7 +984,7 @@ class XendDomainInfo:
             changed = True
 
         # Check if the rtc offset has changes
-        if vm_details.get("rtc/timeoffset", 0) != 
self.info["platform"].get("rtc_timeoffset", 0):
+        if vm_details.get("rtc/timeoffset", "0") != 
self.info["platform"].get("rtc_timeoffset", "0"):
             self.info["platform"]["rtc_timeoffset"] = 
vm_details.get("rtc/timeoffset", 0)
             changed = True
  
@@ -1770,7 +1773,8 @@ class XendDomainInfo:
 
         self._cleanupVm()
         if self.dompath is not None:
-            xc.domain_destroy_hook(self.domid)
+            if self.domid is not None:
+                xc.domain_destroy_hook(self.domid)
             self.destroyDomain()
 
         self._cleanup_phantom_devs(paths)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendVDI.py
--- a/tools/python/xen/xend/XendVDI.py  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/XendVDI.py  Thu Sep 06 12:05:15 2007 -0600
@@ -23,7 +23,8 @@ import os
 
 from xen.util.xmlrpclib2 import stringify
 from xmlrpclib import dumps, loads
-from xen.util import security, xsconstants
+from xen.util import xsconstants
+import xen.util.xsm.xsm as security
 from xen.xend.XendError import SecurityError
 
 KB = 1024
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendXSPolicy.py
--- a/tools/python/xen/xend/XendXSPolicy.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/XendXSPolicy.py     Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,8 @@ from xen.xend.XendBase import XendBase
 from xen.xend.XendBase import XendBase
 from xen.xend.XendError import *
 from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
-from xen.util import xsconstants, security
+from xen.util import xsconstants
+import xen.util.xsm.xsm as security
 import base64
 
 log = logging.getLogger("xend.XendXSPolicy")
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/XendXSPolicyAdmin.py
--- a/tools/python/xen/xend/XendXSPolicyAdmin.py        Thu Sep 06 09:05:26 
2007 -0600
+++ b/tools/python/xen/xend/XendXSPolicyAdmin.py        Thu Sep 06 12:05:15 
2007 -0600
@@ -22,7 +22,8 @@ from xml.dom import minidom, Node
 
 from xen.xend.XendLogging import log
 from xen.xend import uuid
-from xen.util import security, xsconstants, dictio, bootloader
+from xen.util import xsconstants, dictio, bootloader
+import xen.util.xsm.acm.acm as security
 from xen.util.xspolicy import XSPolicy
 from xen.util.acmpolicy import ACMPolicy
 from xen.xend.XendError import SecurityError
diff -r 12be90e2f831 -r 4ffca478e2f7 
tools/python/xen/xend/server/BlktapController.py
--- a/tools/python/xen/xend/server/BlktapController.py  Thu Sep 06 09:05:26 
2007 -0600
+++ b/tools/python/xen/xend/server/BlktapController.py  Thu Sep 06 12:05:15 
2007 -0600
@@ -6,6 +6,14 @@ from xen.xend.XendLogging import log
 
 phantomDev = 0;
 phantomId = 0;
+
+blktap_disk_types = [
+    'aio',
+    'sync',
+    'vmdk',
+    'ram',
+    'qcow'
+    ]
 
 class BlktapController(BlkifController):
     def __init__(self, vm):
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/server/blkif.py     Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,7 @@ import string
 import string
 
 from xen.util import blkif
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xend.XendError import VmError
 from xen.xend.server.DevController import DevController
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xend/server/netif.py     Thu Sep 06 12:05:15 2007 -0600
@@ -27,8 +27,8 @@ from xen.xend import XendOptions
 from xen.xend import XendOptions
 from xen.xend.server.DevController import DevController
 from xen.xend.XendError import VmError
-from xen.util import security
 from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+import xen.util.xsm.xsm as security
 
 from xen.xend.XendLogging import log
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/addlabel.py   Thu Sep 06 12:05:15 2007 -0600
@@ -23,7 +23,7 @@ import sys
 import sys
 
 from xen.util import dictio
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xm.opts import OptionError
 from xen.util import xsconstants
 from xen.xm import main as xm_main
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Thu Sep 06 12:05:15 2007 -0600
@@ -26,11 +26,11 @@ import shutil
 import shutil
 import string
 import re
-from xen.util.security import err
-from xen.util.security import policy_dir_prefix, xen_title_re
-from xen.util.security import boot_filename, altboot_filename
-from xen.util.security import any_title_re, xen_kernel_re, any_module_re
-from xen.util.security import empty_line_re, binary_name_re, policy_name_re
+from xen.util.xsm.xsm import err
+from xen.util.xsm.xsm import policy_dir_prefix, xen_title_re
+from xen.util.xsm.xsm import boot_filename, altboot_filename
+from xen.util.xsm.xsm import any_title_re, xen_kernel_re, any_module_re
+from xen.util.xsm.xsm import empty_line_re, binary_name_re, policy_name_re
 from xen.util import xsconstants
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/create.py     Thu Sep 06 12:05:15 2007 -0600
@@ -33,7 +33,7 @@ import xen.xend.XendClient
 import xen.xend.XendClient
 from xen.xend.XendBootloader import bootloader
 from xen.util import blkif
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
 
 from xen.xm.opts import *
@@ -725,7 +725,8 @@ def configure_hvm(config_image, vals):
     for a in args:
         if a in vals.__dict__ and vals.__dict__[a] is not None:
             config_image.append([a, vals.__dict__[a]])
-    config_image.append(['vncpasswd', vals.vncpasswd])
+    if vals.vncpasswd is not None:
+        config_image.append(['vncpasswd', vals.vncpasswd])
 
 
 def make_config(vals):
@@ -1220,7 +1221,7 @@ def config_security_check(config, verbos
             if verbose:
                 print "   %s: PERMITTED" % (resource)
 
-        except security.ACMError:
+        except security.XSMError:
             print "   %s: DENIED" % (resource)
             (poltype, res_label, res_policy) = security.get_res_label(resource)
             if not res_label:
@@ -1242,7 +1243,7 @@ def create_security_check(config):
                 passed = 1
         else:
             print "Checking resources: (skipped)"
-    except security.ACMError:
+    except security.XSMError:
         sys.exit(-1)
 
     return passed
@@ -1299,7 +1300,7 @@ def main(argv):
         map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
     elif not opts.is_xml:
         if not create_security_check(config):
-            raise security.ACMError(
+            raise security.XSMError(
                 'Security Configuration prevents domain from starting')
         dom = make_domain(opts, config)
         
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/dry-run.py
--- a/tools/python/xen/xm/dry-run.py    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/dry-run.py    Thu Sep 06 12:05:15 2007 -0600
@@ -19,7 +19,7 @@
 """Tests the security settings for a domain and its resources.
 """
 import sys
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xm import create
 from xen.xend import sxp
 from xen.xm.opts import OptionError
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/dumppolicy.py Thu Sep 06 12:05:15 2007 -0600
@@ -18,7 +18,7 @@
 """Display currently enforced policy (low-level hypervisor representation).
 """
 import sys
-from xen.util.security import ACMError, err, dump_policy
+from xen.util.xsm.xsm import XSMError, err, dump_policy
 from xen.xm.opts import OptionError
 
 def help():
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/getlabel.py   Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,7 @@
 """
 import sys, os, re
 from xen.util import dictio
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.util import xsconstants
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
@@ -62,7 +62,7 @@ def get_resource_label(resource):
                                     "Please relabel the resource.")
         print policytype+":"+policy+":"+label
     else:
-        raise security.ACMError("Resource not labeled")
+        raise security.XSMError("Resource not labeled")
 
 
 def get_domain_label(configfile):
@@ -95,7 +95,7 @@ def get_domain_label(configfile):
 
     # send error message if we didn't find anything
     if acline == "":
-        raise security.ACMError("Domain not labeled")
+        raise security.XSMError("Domain not labeled")
 
     # print out the label
     (title, data) = acline.split("=", 1)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/labels.py     Thu Sep 06 12:05:15 2007 -0600
@@ -21,8 +21,8 @@ import sys
 import sys
 import traceback
 import string
-from xen.util.security import ACMError, err, list_labels, active_policy
-from xen.util.security import vm_label_re, res_label_re, all_label_re
+from xen.util.xsm.xsm import XSMError, err, list_labels, active_policy
+from xen.util.xsm.xsm import vm_label_re, res_label_re, all_label_re
 from xen.xm.opts import OptionError
 from xen.util.acmpolicy import ACMPolicy
 from xen.util import xsconstants
@@ -78,7 +78,7 @@ def labels(policy, ptype):
         for label in labels:
             print label
 
-    except ACMError:
+    except XSMError:
         sys.exit(-1)
     except:
         traceback.print_exc(limit = 1)
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,7 @@
 """
 import sys
 import traceback
-from xen.util.security import ACMError, err, load_policy
+from xen.util.xsm.xsm import XSMError, err, load_policy
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
 from xen.util import xsconstants
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/main.py       Thu Sep 06 12:05:15 2007 -0600
@@ -49,7 +49,8 @@ from xen.xm.opts import OptionError, Opt
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
 from xen.util.xmlrpcclient import ServerProxy
-from xen.util.security import ACMError
+import xen.util.xsm.xsm as security
+from xen.util.xsm.xsm import XSMError
 from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
 
 import XenAPI
@@ -872,12 +873,7 @@ def parse_doms_info(info):
         }
 
     security_label = get_info('security_label', str, '')
-    tmp = security_label.split(":")
-    if len(tmp) != 3:
-        seclabel = ""
-    else:
-        seclabel = security_label
-    parsed_info['seclabel'] = seclabel
+    parsed_info['seclabel'] = security.parse_security_label(security_label)
 
     if serverType == SERVER_XEN_API:
         parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
@@ -935,14 +931,14 @@ def xm_brief_list(doms):
         print format % d
 
 def xm_label_list(doms):
-    print '%-32s %5s %5s %5s %10s %9s %-8s' % \
+    print '%-40s %3s %5s %5s %10s %9s %-10s' % \
           ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
-    
+
     output = []
-    format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
-             '%(cpu_time)8.1f %(seclabel)9s'
-
-    from xen.util import security
+    format = '%(name)-40s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
+             '%(cpu_time)8.1f %(seclabel)10s'
+
+    import xen.util.xsm.xsm as security
         
     for dom in doms:
         d = parse_doms_info(dom)
@@ -2580,12 +2576,12 @@ def _run_cmd(cmd, cmd_name, args):
         print e.usage
     except XenAPIUnsupportedException, e:
         err(str(e))
-    except ACMError, e:
+    except XSMError, e:
         err(str(e))
     except Exception, e:
         if serverType != SERVER_XEN_API:
-           from xen.util import security
-           if isinstance(e, security.ACMError):
+           import xen.util.xsm.xsm as security
+           if isinstance(e, security.XSMError):
                err(str(e))
                return False, 1
         print "Unexpected error:", sys.exc_info()[0]
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/makepolicy.py Thu Sep 06 12:05:15 2007 -0600
@@ -19,7 +19,7 @@
 """
 import sys
 import traceback
-from xen.util.security import ACMError, err, make_policy
+from xen.util.xsm.xsm import ACMError, err, make_policy
 from xen.util import xsconstants
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/resources.py  Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,7 @@
 """
 import sys
 from xen.util import dictio
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.util import xsconstants
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/rmlabel.py    Thu Sep 06 12:05:15 2007 -0600
@@ -20,7 +20,7 @@
 """
 import sys, os, re
 from xen.util import dictio
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xm.opts import OptionError
 from xen.xm import main as xm_main
 from xen.xm.main import server
@@ -108,7 +108,7 @@ def rm_domain_label(configfile):
 
     # send error message if we didn't find anything to remove
     if not removed:
-        raise security.ACMError('Domain not labeled')
+        raise security.XSMError('Domain not labeled')
 
     # write the data back out to the file
     fd = open(fil, "wb")
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/python/xen/xm/setpolicy.py
--- a/tools/python/xen/xm/setpolicy.py  Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/python/xen/xm/setpolicy.py  Thu Sep 06 12:05:15 2007 -0600
@@ -26,7 +26,7 @@ from xen.util import xsconstants
 from xen.util import xsconstants
 from xen.util.acmpolicy import ACMPolicy
 from xen.xm.opts import OptionError
-from xen.util.security import policy_dir_prefix
+from xen.util.xsm.acm.acm import policy_dir_prefix
 from xen.xm import main as xm_main
 from xen.xm.main import server
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/security/secpol_tool.c      Thu Sep 06 12:05:15 2007 -0600
@@ -34,8 +34,8 @@
 #include <string.h>
 #include <netinet/in.h>
 #include <stdint.h>
-#include <xen/acm.h>
-#include <xen/acm_ops.h>
+#include <xen/xsm/acm.h>
+#include <xen/xsm/acm_ops.h>
 
 #include <xenctrl.h>
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/security/secpol_xml2bin.c
--- a/tools/security/secpol_xml2bin.c   Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/security/secpol_xml2bin.c   Thu Sep 06 12:05:15 2007 -0600
@@ -22,6 +22,7 @@
  *
  * indent -i4 -kr -nut
  */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,7 +39,7 @@
 #include <libxml/tree.h>
 #include <libxml/xmlreader.h>
 #include <stdint.h>
-#include <xen/acm.h>
+#include <xen/xsm/acm.h>
 
 #include "secpol_xml2bin.h"
 
diff -r 12be90e2f831 -r 4ffca478e2f7 tools/xm-test/lib/XmTestLib/acm.py
--- a/tools/xm-test/lib/XmTestLib/acm.py        Thu Sep 06 09:05:26 2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/acm.py        Thu Sep 06 12:05:15 2007 -0600
@@ -18,7 +18,7 @@
 
 """
 from Test import *
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.xm.main import server
 from xen.util import xsconstants
 import re
diff -r 12be90e2f831 -r 4ffca478e2f7 
tools/xm-test/tests/security-acm/01_security-acm_basic.py
--- a/tools/xm-test/tests/security-acm/01_security-acm_basic.py Thu Sep 06 
09:05:26 2007 -0600
+++ b/tools/xm-test/tests/security-acm/01_security-acm_basic.py Thu Sep 06 
12:05:15 2007 -0600
@@ -14,7 +14,7 @@
 # - resources
 
 from XmTestLib import *
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.util import xsconstants
 import commands
 import os
diff -r 12be90e2f831 -r 4ffca478e2f7 
tools/xm-test/tests/security-acm/07_security-acm_pol_update.py
--- a/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py    Thu Sep 
06 09:05:26 2007 -0600
+++ b/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py    Thu Sep 
06 12:05:15 2007 -0600
@@ -9,7 +9,8 @@ from XmTestLib.XenAPIDomain import XmTes
 from XmTestLib.XenAPIDomain import XmTestAPIDomain
 from XmTestLib import *
 from xen.xend import XendAPIConstants
-from xen.util import acmpolicy, security, xsconstants
+import xen.util.xsm.xsm as security
+from xen.util import acmpolicy, xsconstants
 from xen.util.acmpolicy import ACMPolicy
 from xen.xend.XendDomain import DOM0_UUID
 from XmTestLib.acm import *
diff -r 12be90e2f831 -r 4ffca478e2f7 
tools/xm-test/tests/security-acm/08_security-acm_xapi.py
--- a/tools/xm-test/tests/security-acm/08_security-acm_xapi.py  Thu Sep 06 
09:05:26 2007 -0600
+++ b/tools/xm-test/tests/security-acm/08_security-acm_xapi.py  Thu Sep 06 
12:05:15 2007 -0600
@@ -9,7 +9,8 @@ from XmTestLib.XenAPIDomain import XmTes
 from XmTestLib.XenAPIDomain import XmTestAPIDomain
 from XmTestLib import *
 from xen.xend import XendAPIConstants
-from xen.util import acmpolicy, security, xsconstants
+import xen.util.xsm.xsm as security
+from xen.util import acmpolicy, xsconstants
 import commands
 import os
 
diff -r 12be90e2f831 -r 4ffca478e2f7 
tools/xm-test/tests/security-acm/09_security-acm_pol_update.py
--- a/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py    Thu Sep 
06 09:05:26 2007 -0600
+++ b/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py    Thu Sep 
06 12:05:15 2007 -0600
@@ -10,7 +10,8 @@ from XmTestLib.acm import *
 from XmTestLib.acm import *
 from XmTestLib import *
 from xen.xend import XendAPIConstants
-from xen.util import security, xsconstants
+import xen.util.xsm.xsm as security
+from xen.util import xsconstants
 from xen.util.acmpolicy import ACMPolicy
 from xen.xend.XendDomain import DOM0_UUID
 import base64
diff -r 12be90e2f831 -r 4ffca478e2f7 
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
--- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Thu Sep 
06 09:05:26 2007 -0600
+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Thu Sep 
06 12:05:15 2007 -0600
@@ -108,12 +108,21 @@ extern char *kasprintf(gfp_t gfp, const 
 #endif
 
 #if defined(_LINUX_NETDEVICE_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-#define netif_tx_lock_bh(dev) (spin_lock_bh(&(dev)->xmit_lock))
-#define netif_tx_unlock_bh(dev) (spin_unlock_bh(&(dev)->xmit_lock))
+#define netif_tx_lock_bh(dev) spin_lock_bh(&(dev)->xmit_lock)
+#define netif_tx_unlock_bh(dev) spin_unlock_bh(&(dev)->xmit_lock)
 #endif
 
 #if defined(__LINUX_SEQLOCK_H) && !defined(DEFINE_SEQLOCK)
 #define DEFINE_SEQLOCK(x) seqlock_t x = SEQLOCK_UNLOCKED
 #endif
 
+/* Bug in RHEL4-U3: rw_lock_t is mistakenly defined in DEFINE_RWLOCK() macro */
+#if defined(__LINUX_SPINLOCK_H) && defined(DEFINE_RWLOCK)
+#define rw_lock_t rwlock_t
 #endif
+
+#if defined(__LINUX_SPINLOCK_H) && !defined(DEFINE_RWLOCK)
+#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
+#endif
+
+#endif
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/Makefile
--- a/xen/Makefile      Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/Makefile      Thu Sep 06 12:05:15 2007 -0600
@@ -1,7 +1,7 @@
 # This is the correct place to edit the build version.
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 3
-export XEN_SUBVERSION    = 0
+export XEN_SUBVERSION    = 2
 export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
@@ -55,7 +55,7 @@ _clean: delete-unfresh-files
        $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean
        $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
        $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
-       $(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
+       $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
        $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
        rm -f include/asm *.o $(TARGET)* *~ core
        rm -f include/asm-*/asm-offsets.h
@@ -122,7 +122,7 @@ build-headers:
 build-headers:
        $(MAKE) -C include/public/foreign
 
-SUBDIRS = acm arch/$(TARGET_ARCH) common drivers 
+SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers
 define all_sources
     ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
       find include -name 'asm-*' -prune -o -name '*.h' -print; \
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/Rules.mk
--- a/xen/Rules.mk      Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/Rules.mk      Thu Sep 06 12:05:15 2007 -0600
@@ -52,11 +52,14 @@ HDRS  := $(filter-out %/asm-offsets.h,$(
 # Note that link order matters!
 ALL_OBJS-y               += $(BASEDIR)/common/built_in.o
 ALL_OBJS-y               += $(BASEDIR)/drivers/built_in.o
-ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
+ALL_OBJS-y               += $(BASEDIR)/xsm/built_in.o
 ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
 
 CFLAGS-y                += -g -D__XEN__
-CFLAGS-$(ACM_SECURITY)  += -DACM_SECURITY
+CFLAGS-$(XSM_ENABLE)    += -DXSM_ENABLE
+CFLAGS-$(FLASK_ENABLE)  += -DFLASK_ENABLE -DXSM_MAGIC=0xf97cff8c
+CFLAGS-$(FLASK_ENABLE)  += -DFLASK_DEVELOP -DFLASK_BOOTPARAM -DFLASK_AVC_STATS
+CFLAGS-$(ACM_SECURITY)  += -DACM_SECURITY -DXSM_MAGIC=0xbcde0100
 CFLAGS-$(verbose)       += -DVERBOSE
 CFLAGS-$(crash_debug)   += -DCRASH_DEBUG
 CFLAGS-$(perfc)         += -DPERF_COUNTERS
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/Makefile
--- a/xen/acm/Makefile  Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-obj-y += acm_core.o 
-obj-y += acm_policy.o
-obj-y += acm_simple_type_enforcement_hooks.o
-obj-y += acm_chinesewall_hooks.o
-obj-y += acm_null_hooks.o
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c   Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/****************************************************************
- * acm_chinesewall_hooks.c
- * 
- * Copyright (C) 2005 IBM Corporation
- *
- * Author:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * Contributions:
- * Stefan Berger <stefanb@xxxxxxxxxxxxxx>
- *
- * 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.
- *
- * sHype Chinese Wall Policy for Xen
- *    This code implements the hooks that are called
- *    throughout Xen operations and decides authorization
- *    based on domain types and Chinese Wall conflict type 
- *    sets. The CHWALL policy decides if a new domain can be started
- *    based on the types of running domains and the type of the
- *    new domain to be started. If the new domain's type is in
- *    conflict with types of running domains, then this new domain
- *    is not allowed to be created. A domain can have multiple types,
- *    in which case all types of a new domain must be conflict-free
- *    with all types of already running domains.
- *
- * indent -i4 -kr -nut
- *
- */
-
-#include <xen/config.h>
-#include <xen/errno.h>
-#include <xen/types.h>
-#include <xen/lib.h>
-#include <xen/delay.h>
-#include <xen/sched.h>
-#include <public/acm.h>
-#include <asm/atomic.h>
-#include <acm/acm_core.h>
-#include <acm/acm_hooks.h>
-#include <acm/acm_endian.h>
-#include <acm/acm_core.h>
-
-ssidref_t dom0_chwall_ssidref = 0x0001;
-
-/* local cache structures for chinese wall policy */
-struct chwall_binary_policy chwall_bin_pol;
-
-/*
- * Initializing chinese wall policy (will be filled by policy partition
- * using setpolicy command)
- */
-int acm_init_chwall_policy(void)
-{
-    /* minimal startup policy; policy write-locked already */
-    chwall_bin_pol.max_types = 1;
-    chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref;
-    chwall_bin_pol.max_conflictsets = 1;
-    chwall_bin_pol.ssidrefs =
-        (domaintype_t *) xmalloc_array(domaintype_t,
-                                       chwall_bin_pol.max_ssidrefs *
-                                       chwall_bin_pol.max_types);
-    chwall_bin_pol.conflict_sets =
-        (domaintype_t *) xmalloc_array(domaintype_t,
-                                       chwall_bin_pol.max_conflictsets *
-                                       chwall_bin_pol.max_types);
-    chwall_bin_pol.running_types =
-        (domaintype_t *) xmalloc_array(domaintype_t,
-                                       chwall_bin_pol.max_types);
-    chwall_bin_pol.conflict_aggregate_set =
-        (domaintype_t *) xmalloc_array(domaintype_t,
-                                       chwall_bin_pol.max_types);
-
-    if ( (chwall_bin_pol.conflict_sets == NULL)
-        || (chwall_bin_pol.running_types == NULL)
-        || (chwall_bin_pol.ssidrefs == NULL)
-        || (chwall_bin_pol.conflict_aggregate_set == NULL) )
-        return ACM_INIT_SSID_ERROR;
-
-    /* initialize state */
-    memset((void *) chwall_bin_pol.ssidrefs, 0,
-           chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types *
-           sizeof(domaintype_t));
-    memset((void *) chwall_bin_pol.conflict_sets, 0,
-           chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types *
-           sizeof(domaintype_t));
-    memset((void *) chwall_bin_pol.running_types, 0,
-           chwall_bin_pol.max_types * sizeof(domaintype_t));
-    memset((void *) chwall_bin_pol.conflict_aggregate_set, 0,
-           chwall_bin_pol.max_types * sizeof(domaintype_t));
-    return ACM_OK;
-}
-
-
-static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
-{
-    struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
-    traceprintk("%s.\n", __func__);
-
-    if ( chwall_ssidp == NULL )
-        return ACM_INIT_SSID_ERROR;
-
-    chwall_ssidp->chwall_ssidref =
-        GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-
-    if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
-    {
-        printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset "
-                "(0).\n",
-                __func__, chwall_ssidp->chwall_ssidref);
-        xfree(chwall_ssidp);
-        return ACM_INIT_SSID_ERROR;
-    }
-    (*chwall_ssid) = chwall_ssidp;
-    printkd("%s: determined chwall_ssidref to %x.\n",
-            __func__, chwall_ssidp->chwall_ssidref);
-    return ACM_OK;
-}
-
-
-static void chwall_free_domain_ssid(void *chwall_ssid)
-{
-    xfree(chwall_ssid);
-    return;
-}
-
-
-/* dump chinese wall cache; policy read-locked already */
-static int chwall_dump_policy(u8 * buf, u32 buf_size)
-{
-    struct acm_chwall_policy_buffer *chwall_buf =
-        (struct acm_chwall_policy_buffer *) buf;
-    int ret = 0;
-
-    if ( buf_size < sizeof(struct acm_chwall_policy_buffer) )
-        return -EINVAL;
-
-    chwall_buf->chwall_max_types = cpu_to_be32(chwall_bin_pol.max_types);
-    chwall_buf->chwall_max_ssidrefs = cpu_to_be32(chwall_bin_pol.max_ssidrefs);
-    chwall_buf->policy_code = cpu_to_be32(ACM_CHINESE_WALL_POLICY);
-    chwall_buf->chwall_ssid_offset =
-        cpu_to_be32(sizeof(struct acm_chwall_policy_buffer));
-    chwall_buf->chwall_max_conflictsets =
-        cpu_to_be32(chwall_bin_pol.max_conflictsets);
-    chwall_buf->chwall_conflict_sets_offset =
-        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_ssid_offset) +
-              sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs *
-              chwall_bin_pol.max_types);
-    chwall_buf->chwall_running_types_offset =
-        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_conflict_sets_offset) +
-              sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
-              chwall_bin_pol.max_types);
-    chwall_buf->chwall_conflict_aggregate_offset =
-        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_running_types_offset) +
-              sizeof(domaintype_t) * chwall_bin_pol.max_types);
-
-    ret = be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset) +
-        sizeof(domaintype_t) * chwall_bin_pol.max_types;
-
-    ret = (ret + 7) & ~7;
-
-    if ( buf_size < ret )
-        return -EINVAL;
-
-    /* now copy buffers over */
-    arrcpy16((u16 *) (buf + be32_to_cpu(chwall_buf->chwall_ssid_offset)),
-             chwall_bin_pol.ssidrefs,
-             chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
-
-    arrcpy16((u16 *) (buf +
-                      be32_to_cpu(chwall_buf->chwall_conflict_sets_offset)),
-             chwall_bin_pol.conflict_sets,
-             chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
-
-    arrcpy16((u16 *) (buf +
-                      be32_to_cpu(chwall_buf->chwall_running_types_offset)),
-             chwall_bin_pol.running_types, chwall_bin_pol.max_types);
-
-    arrcpy16((u16 *) (buf +
-                      
be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset)),
-             chwall_bin_pol.conflict_aggregate_set,
-             chwall_bin_pol.max_types);
-    return ret;
-}
-
-/*
- * Adapt security state (running_types and conflict_aggregate_set) to all
- * running domains; chwall_init_state is called when a policy is changed
- * to bring the security information into a consistent state and to detect
- * violations (return != 0) from a security point of view, we simulate
- * that all running domains are re-started
- */
-static int
-chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
-                  domaintype_t * ssidrefs,
-                  domaintype_t * conflict_sets,
-                  domaintype_t * running_types,
-                  domaintype_t * conflict_aggregate_set,
-                  struct acm_sized_buffer *errors /* may be NULL */)
-{
-    int violation = 0, i, j;
-    struct chwall_ssid *chwall_ssid;
-    ssidref_t chwall_ssidref;
-    struct acm_ssid_domain *rawssid;
-
-    read_lock(&ssid_list_rwlock);
-
-    /* go through all domains and adjust policy as if this domain was
-     * started now
-     */
-    for_each_acmssid( rawssid )
-    {
-        chwall_ssid =
-            GET_SSIDP(ACM_CHINESE_WALL_POLICY, rawssid);
-        chwall_ssidref = chwall_ssid->chwall_ssidref;
-        traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
-                    __func__, d->domain_id, chwall_ssidref);
-        /* a) adjust types ref-count for running domains */
-        for ( i = 0; i < chwall_buf->chwall_max_types; i++ )
-            running_types[i] +=
-                ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i];
-
-        /* b) check for conflict */
-        for ( i = 0; i < chwall_buf->chwall_max_types; i++ )
-            if ( conflict_aggregate_set[i] &&
-                 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i] )
-            {
-                printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
-                       __func__, i);
-                violation = 1;
-
-                acm_array_append_tuple(errors, ACM_CHWALL_CONFLICT, i);
-
-                goto out;
-            }
-
-        /* set violation and break out of the loop */
-        /* c) adapt conflict aggregate set for this domain
-         *    (notice conflicts)
-         */
-        for ( i = 0; i < chwall_buf->chwall_max_conflictsets; i++ )
-        {
-            int common = 0;
-            /* check if conflict_set_i and ssidref have common types */
-            for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
-                if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
-                     ssidrefs[chwall_ssidref *
-                              chwall_buf->chwall_max_types + j] )
-                {
-                    common = 1;
-                    break;
-                }
-
-            if ( common == 0 )
-                continue;       /* try next conflict set */
-
-            /* now add types of the conflict set to conflict_aggregate_set
-             * (except types in chwall_ssidref)
-             */
-            for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
-                if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
-                     !ssidrefs[chwall_ssidref *
-                               chwall_buf->chwall_max_types + j] )
-                    conflict_aggregate_set[j]++;
-        }
-    }
- out:
-    read_unlock(&ssid_list_rwlock);
-    return violation;
-    /* returning "violation != 0" means that the currently running set of
-     * domains would not be possible if the new policy had been enforced
-     * before starting them; for chinese wall, this means that the new
-     * policy includes at least one conflict set of which more than one
-     * type is currently running
-     */
-}
-
-
-int
-do_chwall_init_state_curr(struct acm_sized_buffer *errors)
-{
-    struct acm_chwall_policy_buffer chwall_buf =
-    {
-         /* only these two are important */
-         .chwall_max_types        = chwall_bin_pol.max_types,
-         .chwall_max_conflictsets = chwall_bin_pol.max_conflictsets,
-    };
-    /* reset running_types and aggregate set for recalculation */
-    memset(chwall_bin_pol.running_types,
-           0x0,
-           sizeof(domaintype_t) * chwall_bin_pol.max_types);
-    memset(chwall_bin_pol.conflict_aggregate_set,
-           0x0,
-           sizeof(domaintype_t) * chwall_bin_pol.max_types);
-    return chwall_init_state(&chwall_buf,
-                             chwall_bin_pol.ssidrefs,
-                             chwall_bin_pol.conflict_sets,
-                             chwall_bin_pol.running_types,
-                             chwall_bin_pol.conflict_aggregate_set,
-                             errors);
-}
-
-/*
- * Attempt to set the policy. This function must be called in test_only
- * mode first to only perform checks. A second call then does the
- * actual changes.
- */
-static int _chwall_update_policy(u8 *buf, u32 buf_size, int test_only,
-                                 struct acm_sized_buffer *errors)
-{
-    int rc = -EFAULT;
-    /* policy write-locked already */
-    struct acm_chwall_policy_buffer *chwall_buf =
-        (struct acm_chwall_policy_buffer *) buf;
-    void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL,
-         *conflict_aggregate_set = NULL;
-
-    /* 1. allocate new buffers */
-    ssids =
-        xmalloc_array(domaintype_t,
-                      chwall_buf->chwall_max_types *
-                      chwall_buf->chwall_max_ssidrefs);
-    conflict_sets =
-        xmalloc_array(domaintype_t,
-                      chwall_buf->chwall_max_conflictsets *
-                      chwall_buf->chwall_max_types);
-    running_types =
-        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
-    conflict_aggregate_set =
-        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
-
-    if ( (ssids == NULL) || (conflict_sets == NULL) ||
-         (running_types == NULL) || (conflict_aggregate_set == NULL) )
-        goto error_free;
-
-    /* 2. set new policy */
-    if ( chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
-         chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs >
-         buf_size )
-        goto error_free;
-
-    arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
-           sizeof(domaintype_t),
-           chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
-
-    if ( chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
-         chwall_buf->chwall_max_types *
-         chwall_buf->chwall_max_conflictsets > buf_size )
-        goto error_free;
-
-    arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
-           sizeof(domaintype_t),
-           chwall_buf->chwall_max_types *
-           chwall_buf->chwall_max_conflictsets);
-
-    /* we also use new state buffers since max_types can change */
-    memset(running_types, 0,
-           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
-    memset(conflict_aggregate_set, 0,
-           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
-
-    /* 3. now re-calculate the state for the new policy based on
-     *    running domains; this can fail if new policy is conflicting
-     *    with running domains
-     */
-    if ( chwall_init_state(chwall_buf, ssids,
-                           conflict_sets, running_types,
-                           conflict_aggregate_set,
-                           errors))
-    {
-        printk("%s: New policy conflicts with running domains. Policy load 
aborted.\n",
-               __func__);
-        goto error_free;        /* new policy conflicts with running domains */
-    }
-
-    /* if this was only a test run, exit with ACM_OK */
-    if ( test_only )
-    {
-        rc = ACM_OK;
-        goto error_free;
-    }
-
-    /* 4. free old policy buffers, replace with new ones */
-    chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
-    chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
-    chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
-    xfree(chwall_bin_pol.ssidrefs);
-    xfree(chwall_bin_pol.conflict_aggregate_set);
-    xfree(chwall_bin_pol.running_types);
-    xfree(chwall_bin_pol.conflict_sets);
-    chwall_bin_pol.ssidrefs = ssids;
-    chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
-    chwall_bin_pol.running_types = running_types;
-    chwall_bin_pol.conflict_sets = conflict_sets;
-
-    return ACM_OK;
-
- error_free:
-    if ( !test_only )
-        printk("%s: ERROR setting policy.\n", __func__);
-
-    xfree(ssids);
-    xfree(conflict_sets);
-    xfree(running_types);
-    xfree(conflict_aggregate_set);
-    return rc;
-}
-
-/*
- * This function MUST be called before the chwall_ste_policy function!
- */
-static int chwall_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
-                              struct acm_sized_buffer *errors)
-{
-    struct acm_chwall_policy_buffer *chwall_buf =
-        (struct acm_chwall_policy_buffer *) buf;
-
-    if ( buf_size < sizeof(struct acm_chwall_policy_buffer) )
-        return -EINVAL;
-
-    /* rewrite the policy due to endianess */
-    chwall_buf->policy_code = be32_to_cpu(chwall_buf->policy_code);
-    chwall_buf->policy_version = be32_to_cpu(chwall_buf->policy_version);
-    chwall_buf->chwall_max_types =
-        be32_to_cpu(chwall_buf->chwall_max_types);
-    chwall_buf->chwall_max_ssidrefs =
-        be32_to_cpu(chwall_buf->chwall_max_ssidrefs);
-    chwall_buf->chwall_max_conflictsets =
-        be32_to_cpu(chwall_buf->chwall_max_conflictsets);
-    chwall_buf->chwall_ssid_offset =
-        be32_to_cpu(chwall_buf->chwall_ssid_offset);
-    chwall_buf->chwall_conflict_sets_offset =
-        be32_to_cpu(chwall_buf->chwall_conflict_sets_offset);
-    chwall_buf->chwall_running_types_offset =
-        be32_to_cpu(chwall_buf->chwall_running_types_offset);
-    chwall_buf->chwall_conflict_aggregate_offset =
-        be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset);
-
-    /* policy type and version checks */
-    if ( (chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
-         (chwall_buf->policy_version != ACM_CHWALL_VERSION) )
-        return -EINVAL;
-
-    /* during boot dom0_chwall_ssidref is set */
-    if ( is_bootpolicy &&
-         (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs) )
-        return -EINVAL;
-
-    return _chwall_update_policy(buf, buf_size, 1, errors);
-}
-
-static int chwall_set_policy(u8 *buf, u32 buf_size)
-{
-    return _chwall_update_policy(buf, buf_size, 0, NULL);
-}
-
-static int chwall_dump_stats(u8 * buf, u16 len)
-{
-    /* no stats for Chinese Wall Policy */
-    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
- ***************************/
-
-/* -------- DOMAIN OPERATION HOOKS -----------*/
-
-static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
-{
-    ssidref_t chwall_ssidref;
-    int i, j;
-
-    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-
-    if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
-    {
-        printk("%s: ERROR chwall_ssidref > max(%x).\n",
-               __func__, chwall_bin_pol.max_ssidrefs - 1);
-        return ACM_ACCESS_DENIED;
-    }
-
-    /* A: chinese wall check for conflicts */
-    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
-        if ( chwall_bin_pol.conflict_aggregate_set[i] &&
-             chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                     chwall_bin_pol.max_types + i] )
-        {
-            printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
-            return ACM_ACCESS_DENIED;
-        }
-
-    /* B: chinese wall conflict set adjustment (so that other
-     *    other domains simultaneously created are evaluated against
-     *    this new set)
-     */
-    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
-    {
-        int common = 0;
-        /* check if conflict_set_i and ssidref have common types */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.
-                 conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                            chwall_bin_pol.max_types + j] )
-            {
-                common = 1;
-                break;
-            }
-        if ( common == 0 )
-            continue;           /* try next conflict set */
-        /* now add types of the conflict set to conflict_aggregate_set (except 
types in chwall_ssidref) */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.
-                 conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                             chwall_bin_pol.max_types + j])
-                 chwall_bin_pol.conflict_aggregate_set[j]++;
-    }
-    return ACM_ACCESS_PERMITTED;
-}
-
-
-static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
-{
-    int i, j;
-    ssidref_t chwall_ssidref;
-
-    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-    /* adjust types ref-count for running domains */
-    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
-        chwall_bin_pol.running_types[i] +=
-            chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                   chwall_bin_pol.max_types + i];
-    if ( domid )
-        return;
-
-    /* Xen does not call pre-create hook for DOM0;
-     * to consider type conflicts of any domain with DOM0, we need
-     * to adjust the conflict_aggregate for DOM0 here the same way it
-     * is done for non-DOM0 domains in the pre-hook */
-    printkd("%s: adjusting security state for DOM0 (ssidref=%x, 
chwall_ssidref=%x).\n",
-            __func__, ssidref, chwall_ssidref);
-
-    /* chinese wall conflict set adjustment (so that other
-     *      other domains simultaneously created are evaluated against this 
new set)*/
-    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
-    {
-        int common = 0;
-        /* check if conflict_set_i and ssidref have common types */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.
-                 conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                            chwall_bin_pol.max_types + j] )
-            {
-                common = 1;
-                break;
-            }
-
-        if ( common == 0 )
-        {
-            /* try next conflict set */
-            continue;
-        }
-
-        /* now add types of the conflict set to conflict_aggregate_set
-           (except types in chwall_ssidref) */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.
-                 conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                             chwall_bin_pol.max_types + j] )
-                chwall_bin_pol.conflict_aggregate_set[j]++;
-    }
-    return;
-}
-
-
-/*
- * To be called when creating a domain. If this call is unsuccessful,
- * no state changes have occurred (adjustments of counters etc.). If it
- * was successful, state was changed and can be undone using
- * chwall_domain_destroy.
- */
-static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref,
-                                domid_t domid)
-{
-    int rc;
-    read_lock(&acm_bin_pol_rwlock);
-
-    rc = _chwall_pre_domain_create(subject_ssid, ssidref);
-    if ( rc == ACM_ACCESS_PERMITTED )
-        _chwall_post_domain_create(domid, ssidref);
-
-    read_unlock(&acm_bin_pol_rwlock);
-    return rc;
-}
-
-/*
- * This function undoes everything a successful call to
- * chwall_domain_create has done.
- */
-static void chwall_domain_destroy(void *object_ssid, struct domain *d)
-{
-    int i, j;
-    struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
-                                                 (struct acm_ssid_domain *)
-                                                 object_ssid);
-    ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
-
-    read_lock(&acm_bin_pol_rwlock);
-
-    /* adjust running types set */
-    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
-        chwall_bin_pol.running_types[i] -=
-            chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                   chwall_bin_pol.max_types + i];
-
-    /* roll-back: re-adjust conflicting types aggregate */
-    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
-    {
-        int common = 0;
-        /* check if conflict_set_i and ssidref have common types */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                            chwall_bin_pol.max_types + j])
-            {
-                common = 1;
-                break;
-            }
-        if ( common == 0 )
-        {
-            /* try next conflict set, this one does not include
-               any type of chwall_ssidref */
-            continue;
-        }
-
-        /* now add types of the conflict set to conflict_aggregate_set
-           (except types in chwall_ssidref) */
-        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
-            if ( chwall_bin_pol.
-                 conflict_sets[i * chwall_bin_pol.max_types + j]
-                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
-                                             chwall_bin_pol.max_types + j])
-                chwall_bin_pol.conflict_aggregate_set[j]--;
-    }
-
-    read_unlock(&acm_bin_pol_rwlock);
-
-    return;
-}
-
-
-static int chwall_is_default_policy(void)
-{
-    return ( (chwall_bin_pol.max_types    == 1 ) &&
-             (chwall_bin_pol.max_ssidrefs == 2 ) );
-}
-
-struct acm_operations acm_chinesewall_ops = {
-    /* policy management services */
-    .init_domain_ssid = chwall_init_domain_ssid,
-    .free_domain_ssid = chwall_free_domain_ssid,
-    .dump_binary_policy = chwall_dump_policy,
-    .test_binary_policy = chwall_test_policy,
-    .set_binary_policy = chwall_set_policy,
-    .dump_statistics = chwall_dump_stats,
-    .dump_ssid_types = chwall_dump_ssid_types,
-    /* domain management control hooks */
-    .domain_create = chwall_domain_create,
-    .domain_destroy = chwall_domain_destroy,
-    /* event channel control hooks */
-    .pre_eventchannel_unbound = NULL,
-    .fail_eventchannel_unbound = NULL,
-    .pre_eventchannel_interdomain = NULL,
-    .fail_eventchannel_interdomain = NULL,
-    /* grant table control hooks */
-    .pre_grant_map_ref = NULL,
-    .fail_grant_map_ref = NULL,
-    .pre_grant_setup = NULL,
-    .fail_grant_setup = NULL,
-    /* generic domain-requested decision hooks */
-    .sharing = NULL,
-    .authorization = NULL,
-
-    .is_default_policy = chwall_is_default_policy,
-};
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-/****************************************************************
- * acm_core.c
- * 
- * Copyright (C) 2005 IBM Corporation
- *
- * Author:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * Contributors:
- * Stefan Berger <stefanb@xxxxxxxxxxxxxx>
- *
- * 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.
- *
- * sHype access control module (ACM)
- *       This file handles initialization of the ACM
- *       as well as initializing/freeing security 
- *       identifiers for domains (it calls on active
- *       policy hook functions).
- *
- */
-
-#include <xen/config.h>
-#include <xen/errno.h>
-#include <xen/types.h>
-#include <xen/lib.h>
-#include <xen/delay.h>
-#include <xen/sched.h>
-#include <xen/multiboot.h>
-#include <acm/acm_hooks.h>
-#include <acm/acm_endian.h>
-
-/* debug: 
- *   include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
- *   define/undefine this constant to receive / suppress any
- *   security hook debug output of sHype
- *
- *   include/public/acm.h defines a constant ACM_DEBUG
- *   define/undefine this constant to receive non-hook-related
- *   debug output.
- */
-
-/* function prototypes */
-void acm_init_chwall_policy(void);
-void acm_init_ste_policy(void);
-
-extern struct acm_operations acm_chinesewall_ops, 
-    acm_simple_type_enforcement_ops, acm_null_ops;
-
-/* global ACM policy  (now dynamically determined at boot time) */
-u16 acm_active_security_policy = ACM_POLICY_UNDEFINED;
-
-/* global ops structs called by the hooks */
-struct acm_operations *acm_primary_ops = NULL;
-/* called in hook if-and-only-if primary succeeds */
-struct acm_operations *acm_secondary_ops = NULL;
-
-/* acm global binary policy (points to 'local' primary and secondary policies 
*/
-struct acm_binary_policy acm_bin_pol;
-/* acm binary policy lock */
-DEFINE_RWLOCK(acm_bin_pol_rwlock);
-
-/* ACM's only accepted policy name during boot */
-char polname[80];
-char *acm_accepted_boot_policy_name = NULL;
-
-/* a lits of all chained ssid structures */
-LIST_HEAD(ssid_list);
-DEFINE_RWLOCK(ssid_list_rwlock);
-
-static void __init set_dom0_ssidref(const char *val)
-{
-    /* expected format:
-         ssidref=<hex number>:<policy name>
-         Policy name must not have a 'space'.
-     */
-    const char *c;
-    int lo, hi;
-    int i;
-    int dom0_ssidref = simple_strtoull(val, &c, 0);
-
-    if (!strncmp(&c[0],":ACM:", 5)) {
-        lo = dom0_ssidref & 0xffff;
-        if (lo < ACM_MAX_NUM_TYPES && lo >= 1)
-            dom0_chwall_ssidref = lo;
-        hi = dom0_ssidref >> 16;
-        if (hi < ACM_MAX_NUM_TYPES && hi >= 1)
-            dom0_ste_ssidref = hi;
-        for (i = 0; i < sizeof(polname); i++) {
-            polname[i] = c[5+i];
-            if (polname[i] == '\0' || polname[i] == '\t' ||
-                polname[i] == '\n' || polname[i] == ' '  ||
-                polname[i] == ':') {
-                break;
-            }
-        }
-        polname[i] = 0;
-        acm_accepted_boot_policy_name = polname;
-    }
-}
-
-custom_param("ssidref", set_dom0_ssidref);
-
-int
-acm_set_policy_reference(u8 *buf, u32 buf_size)
-{
-    char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer));
-    struct acm_policy_reference_buffer *pr = (struct 
acm_policy_reference_buffer *)buf;
-
-    if (acm_accepted_boot_policy_name != NULL) {
-        if (strcmp(acm_accepted_boot_policy_name, name)) {
-            printk("Policy's name '%s' is not the expected one '%s'.\n",
-                   name, acm_accepted_boot_policy_name);
-            return ACM_ERROR;
-        }
-    }
-
-    acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, 
be32_to_cpu(pr->len));
-
-    if (!acm_bin_pol.policy_reference_name)
-        return -ENOMEM;
-    strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len));
-
-    printk("%s: Activating policy %s\n", __func__,
-           acm_bin_pol.policy_reference_name);
-    return 0;
-}
-
-int
-acm_dump_policy_reference(u8 *buf, u32 buf_size)
-{
-    struct acm_policy_reference_buffer *pr_buf = (struct 
acm_policy_reference_buffer *)buf;
-    int ret = sizeof(struct acm_policy_reference_buffer) + 
strlen(acm_bin_pol.policy_reference_name) + 1;
-
-    ret = (ret + 7) & ~7;
-    if (buf_size < ret)
-        return -EINVAL;
-
-    memset(buf, 0, ret);
-    pr_buf->len = cpu_to_be32(strlen(acm_bin_pol.policy_reference_name) + 1); 
/* including stringend '\0' */
-    strlcpy((char *)(buf + sizeof(struct acm_policy_reference_buffer)),
-            acm_bin_pol.policy_reference_name,
-            be32_to_cpu(pr_buf->len));
-    return ret;
-}
-
-int
-acm_init_binary_policy(u32 policy_code)
-{
-    int ret = ACM_OK;
-
-    acm_bin_pol.primary_policy_code = (policy_code & 0x0f);
-    acm_bin_pol.secondary_policy_code = (policy_code >> 4) & 0x0f;
-
-    write_lock(&acm_bin_pol_rwlock);
-
-    /* set primary policy component */
-    switch ((policy_code) & 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;
-
-    case ACM_NULL_POLICY:
-        acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
-        acm_primary_ops = &acm_null_ops;
-        break;
-
-    default:
-        /* Unknown policy not allowed primary */
-        ret = -EINVAL;
-        goto out;
-    }
-
-    /* secondary policy component part */
-    switch ((policy_code) >> 4)
-    {
-
-    case ACM_NULL_POLICY:
-        acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
-        acm_secondary_ops = &acm_null_ops;
-        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.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-        acm_secondary_ops = &acm_simple_type_enforcement_ops;
-        break;
-
-    default:
-        ret = -EINVAL;
-        goto out;
-    }
-
- out:
-    write_unlock(&acm_bin_pol_rwlock);
-    return ret;
-}
-
-int
-acm_is_policy(char *buf, unsigned long len)
-{
-    struct acm_policy_buffer *pol;
-
-    if (buf == NULL || len < sizeof(struct acm_policy_buffer))
-        return 0;
-
-    pol = (struct acm_policy_buffer *)buf;
-    return be32_to_cpu(pol->magic) == ACM_MAGIC;
-}
-
-
-static int
-acm_setup(char *policy_start,
-          unsigned long policy_len,
-          int is_bootpolicy)
-{
-    int rc = ACM_OK;
-    struct acm_policy_buffer *pol;
-
-    if (policy_start == NULL || policy_len < sizeof(struct acm_policy_buffer))
-        return rc;
-
-    pol = (struct acm_policy_buffer *)policy_start;
-    if (be32_to_cpu(pol->magic) != ACM_MAGIC)
-        return rc;
-
-    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len,
-                           is_bootpolicy,
-                           NULL, NULL, NULL);
-    if (rc == ACM_OK)
-    {
-        printkd("Policy len  0x%lx, start at %p.\n",policy_len,policy_start);
-    }
-    else
-    {
-        printk("Invalid policy.\n");
-        /* load default policy later */
-        acm_active_security_policy = ACM_POLICY_UNDEFINED;
-    }
-    return rc;
-}
-
-
-int __init
-acm_init(char *policy_start,
-         unsigned long policy_len)
-{
-    int ret = ACM_OK;
-
-    /* first try to load the boot policy (uses its own locks) */
-    acm_setup(policy_start, policy_len, 1);
-
-    /* a user-provided policy may have any name; only matched during boot */
-    acm_accepted_boot_policy_name = NULL;
-
-    if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
-    {
-        printk("%s: Enforcing %s boot policy.\n", __func__,
-               ACM_POLICY_NAME(acm_active_security_policy));
-        goto out;
-    }
-    /* else continue with the minimal hardcoded default startup policy */
-    printk("%s: Loading default policy (%s).\n",
-           __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
-
-    /* (re-)set dom-0 ssidref to default */
-    dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001;
-
-    if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
-        ret = -EINVAL;
-        goto out;
-    }
-    acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY;
-    if (acm_active_security_policy != ACM_NULL_POLICY)
-        acm_bin_pol.policy_reference_name = "DEFAULT";
-    else
-        acm_bin_pol.policy_reference_name = "NULL";
-
- out:
-    if (ret != ACM_OK)
-    {
-        printk("%s: Error initializing policies.\n", __func__);
-        /* here one could imagine a clean panic */
-        return -EINVAL;
-    }
-    return ret;
-}
-
-int acm_init_domain_ssid(struct domain *subj, ssidref_t ssidref)
-{
-    struct acm_ssid_domain *ssid;
-    int ret1, ret2;
-    if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
-    {
-        return ACM_INIT_SSID_ERROR;
-    }
-
-    INIT_LIST_HEAD(&ssid->node);
-    ssid->datatype       = ACM_DATATYPE_domain;
-    ssid->subject        = subj;
-    ssid->domainid       = subj->domain_id;
-    ssid->primary_ssid   = NULL;
-    ssid->secondary_ssid = NULL;
-
-    if (acm_active_security_policy != ACM_NULL_POLICY)
-        ssid->ssidref = ssidref;
-    else
-        ssid->ssidref = ACM_DEFAULT_SSID;
-
-    subj->ssid           = ssid;
-    /* now fill in primary and secondary parts; we only get here through hooks 
*/
-    if (acm_primary_ops->init_domain_ssid != NULL)
-        ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), 
ssidref);
-    else
-        ret1 = ACM_OK;
-
-    if (acm_secondary_ops->init_domain_ssid != NULL)
-        ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), 
ssidref);
-    else
-        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);
-        return ACM_INIT_SSID_ERROR;
-    }
-
-    printkd("%s: assigned domain %x the ssidref=%x.\n",
-           __func__, subj->domain_id, ssid->ssidref);
-    return ACM_OK;
-}
-
-
-void
-acm_free_domain_ssid(struct acm_ssid_domain *ssid)
-{
-    /* domain is already gone, just ssid is left */
-    if (ssid == NULL)
-        return;
-
-    ssid->subject = NULL;
-    if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
-        acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
-    ssid->primary_ssid = NULL;
-    if (acm_secondary_ops->free_domain_ssid != NULL)
-        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);
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c  Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/****************************************************************
- * acm_null_hooks.c
- * 
- * Copyright (C) 2005 IBM Corporation
- *
- * Author:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * 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.
- */
-
-#include <acm/acm_hooks.h>
-
-static int
-null_init_domain_ssid(void **ssid, ssidref_t ssidref)
-{
-    return ACM_OK;
-}
-
-static void
-null_free_domain_ssid(void *ssid)
-{
-    return;
-}
-
-static int
-null_dump_binary_policy(u8 *buf, u32 buf_size)
-{ 
-    return 0;
-}
-
-static int
-null_test_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
-                        struct acm_sized_buffer *errors)
-{
-    return ACM_OK;
-}
-
-static int
-null_set_binary_policy(u8 *buf, u32 buf_size)
-{ 
-    return ACM_OK;
-}
- 
-static int 
-null_dump_stats(u8 *buf, u16 buf_size)
-{
-    /* no stats for NULL policy */
-    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,
-    .free_domain_ssid = null_free_domain_ssid,
-    .dump_binary_policy = null_dump_binary_policy,
-    .test_binary_policy = null_test_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 */
-    .domain_create = NULL,
-    .domain_destroy = NULL,
-    /* event channel control hooks */
-    .pre_eventchannel_unbound = NULL,
-    .fail_eventchannel_unbound = NULL,
-    .pre_eventchannel_interdomain = NULL,
-    .fail_eventchannel_interdomain = NULL,
-    /* grant table control hooks */
-    .pre_grant_map_ref = NULL,
-    .fail_grant_map_ref = NULL,
-    .pre_grant_setup = NULL,
-    .fail_grant_setup = NULL
-};
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,876 +0,0 @@
-/****************************************************************
- * acm_policy.c
- * 
- * Copyright (C) 2005-2007 IBM Corporation
- *
- * Author:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * Contributors:
- * Stefan Berger <stefanb@xxxxxxxxxxxxxx>
- *
- * 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.
- *
- * sHype access control policy management for Xen.
- *       This interface allows policy tools in authorized
- *       domains to interact with the Xen access control module
- * 
- */
-
-#include <xen/config.h>
-#include <xen/errno.h>
-#include <xen/types.h>
-#include <xen/lib.h>
-#include <xen/delay.h>
-#include <xen/sched.h>
-#include <xen/guest_access.h>
-#include <public/xen.h>
-#include <acm/acm_core.h>
-#include <public/acm_ops.h>
-#include <acm/acm_hooks.h>
-#include <acm/acm_endian.h>
-#include <asm/current.h>
-
-static int acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels,
-                                      struct acm_sized_buffer *errors);
-static void acm_doms_change_ssidref(ssidref_t (*translator)
-                                   (const struct acm_ssid_domain *,
-                                    const struct acm_sized_buffer *),
-                                    struct acm_sized_buffer *translation_map);
-static void acm_doms_restore_ssidref(void);
-static ssidref_t oldssid_to_newssid(const struct acm_ssid_domain *,
-                                    const struct acm_sized_buffer *map);
-
-
-int
-acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
-{
-    u8 *policy_buffer = NULL;
-    int ret = -EFAULT;
-
-    if ( buf_size < sizeof(struct acm_policy_buffer) )
-        return -EFAULT;
-
-    /* copy buffer from guest domain */
-    if ( (policy_buffer = xmalloc_array(u8, buf_size)) == NULL )
-        return -ENOMEM;
-
-    if ( copy_from_guest(policy_buffer, buf, buf_size) )
-    {
-        printk("%s: Error copying!\n",__func__);
-        goto error_free;
-    }
-    ret = do_acm_set_policy(policy_buffer, buf_size, 0,
-                            NULL, NULL, NULL);
-
- error_free:
-    xfree(policy_buffer);
-    return ret;
-}
-
-
-/*
- * Update the policy of the running system by:
- * - deleting ssidrefs that are not in the new policy anymore
- *   -> no running domain may use such an ssidref
- * - assign new ssidrefs to domains based on their old ssidrefs
- *
- */
-static int
-_acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy,
-                   struct acm_policy_buffer *pol,
-                   struct acm_sized_buffer *deletions,
-                   struct acm_sized_buffer *ssidchanges,
-                   struct acm_sized_buffer *errors)
-{
-    uint32_t offset, length;
-    static int require_update = 0;
-
-    write_lock(&acm_bin_pol_rwlock);
-
-    if (  require_update != 0 &&
-        ( deletions == NULL || ssidchanges == NULL ) )
-        goto error_lock_free;
-
-    require_update = 1;
-    /*
-       first some tests to check compatibility of new policy with
-       current state of system/domains
-     */
-
-    /* if ssidrefs are to be deleted, make sure no domain is using them */
-    if ( deletions != NULL )
-        if ( acm_check_deleted_ssidrefs(deletions, errors) )
-            goto error_lock_free;
-
-    if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) )
-        /* assign all running domains new ssidrefs as requested */
-        acm_doms_change_ssidref(oldssid_to_newssid, ssidchanges);
-
-    /* test primary policy data with the new ssidrefs */
-    offset = be32_to_cpu(pol->primary_buffer_offset);
-    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
-
-    if ( (offset + length) > buf_size ||
-         acm_primary_ops->test_binary_policy(buf + offset, length,
-                                             is_bootpolicy,
-                                             errors))
-        goto error_lock_free;
-
-    /* test secondary policy data with the new ssidrefs */
-    offset = be32_to_cpu(pol->secondary_buffer_offset);
-    length = be32_to_cpu(pol->len) - offset;
-    if ( (offset + length) > buf_size ||
-         acm_secondary_ops->test_binary_policy(buf + offset, length,
-                                               is_bootpolicy,
-                                               errors))
-        goto error_lock_free;
-
-    /* end of testing --- now real updates */
-
-    offset = be32_to_cpu(pol->policy_reference_offset);
-    length = be32_to_cpu(pol->primary_buffer_offset) - offset;
-
-    /* set label reference name */
-    if ( (offset + length) > buf_size ||
-         acm_set_policy_reference(buf + offset, length) )
-        goto error_lock_free;
-
-    /* set primary policy data */
-    offset = be32_to_cpu(pol->primary_buffer_offset);
-    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
-
-    if ( acm_primary_ops->set_binary_policy(buf + offset, length) )
-        goto error_lock_free;
-
-    /* set secondary policy data */
-    offset = be32_to_cpu(pol->secondary_buffer_offset);
-    length = be32_to_cpu(pol->len) - offset;
-    if ( acm_secondary_ops->set_binary_policy(buf + offset, length) )
-        goto error_lock_free;
-
-    memcpy(&acm_bin_pol.xml_pol_version,
-           &pol->xml_pol_version,
-           sizeof(acm_bin_pol.xml_pol_version));
-
-    if ( acm_primary_ops->is_default_policy() &&
-         acm_secondary_ops->is_default_policy() )
-        require_update = 0;
-
-    write_unlock(&acm_bin_pol_rwlock);
-
-    return ACM_OK;
-
-error_lock_free:
-    if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) )
-    {
-        acm_doms_restore_ssidref();
-    }
-    do_chwall_init_state_curr(NULL);
-    write_unlock(&acm_bin_pol_rwlock);
-
-    return -EFAULT;
-}
-
-
-int
-do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy,
-                  struct acm_sized_buffer *deletions,
-                  struct acm_sized_buffer *ssidchanges,
-                  struct acm_sized_buffer *errors)
-{
-    struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
-
-    /* some sanity checking */
-    if ( (be32_to_cpu(pol->magic) != ACM_MAGIC) ||
-         (buf_size != be32_to_cpu(pol->len)) ||
-         (be32_to_cpu(pol->policy_version) != ACM_POLICY_VERSION) )
-    {
-        printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
-        goto error_free;
-    }
-
-    if ( acm_active_security_policy == ACM_POLICY_UNDEFINED )
-    {
-        /* setup the policy with the boot policy */
-        if ( acm_init_binary_policy(
-                             (be32_to_cpu(pol->secondary_policy_code) << 4) |
-                              be32_to_cpu(pol->primary_policy_code)) )
-        {
-            goto error_free;
-        }
-        acm_active_security_policy = (acm_bin_pol.secondary_policy_code << 4) |
-                                      acm_bin_pol.primary_policy_code;
-    }
-
-    /* once acm_active_security_policy is set, it cannot be changed */
-    if ( (be32_to_cpu(pol->primary_policy_code) !=
-                                        acm_bin_pol.primary_policy_code) ||
-         (be32_to_cpu(pol->secondary_policy_code) !=
-                                        acm_bin_pol.secondary_policy_code) )
-    {
-        printkd("%s: Wrong policy type in boot policy!\n", __func__);
-        goto error_free;
-    }
-
-    return _acm_update_policy(buf, buf_size, is_bootpolicy,
-                              pol,
-                              deletions, ssidchanges,
-                              errors);
-
- error_free:
-    printk("%s: Error setting policy.\n", __func__);
-    return -EFAULT;
-}
-
-int
-acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
-{ 
-    u8 *policy_buffer;
-    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);
-
-    bin_pol = (struct acm_policy_buffer *)policy_buffer;
-    bin_pol->magic = cpu_to_be32(ACM_MAGIC);
-    bin_pol->primary_policy_code =
-                                cpu_to_be32(acm_bin_pol.primary_policy_code);
-    bin_pol->secondary_policy_code =
-                                cpu_to_be32(acm_bin_pol.secondary_policy_code);
-
-    bin_pol->len = cpu_to_be32(sizeof(struct acm_policy_buffer));
-    bin_pol->policy_reference_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
-    bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
-    bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
-
-    memcpy(&bin_pol->xml_pol_version,
-           &acm_bin_pol.xml_pol_version,
-           sizeof(struct acm_policy_version));
-
-    ret = acm_dump_policy_reference(
-               policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset),
-               buf_size - be32_to_cpu(bin_pol->policy_reference_offset));
-
-    if ( ret < 0 )
-        goto error_free_unlock;
-
-    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
-    bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
-
-    ret = acm_primary_ops->dump_binary_policy(
-                 policy_buffer + be32_to_cpu(bin_pol->primary_buffer_offset),
-                 buf_size - be32_to_cpu(bin_pol->primary_buffer_offset));
-
-    if ( ret < 0 )
-        goto error_free_unlock;
-
-    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
-    bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
-
-    ret = acm_secondary_ops->dump_binary_policy(
-               policy_buffer + be32_to_cpu(bin_pol->secondary_buffer_offset),
-               buf_size - be32_to_cpu(bin_pol->secondary_buffer_offset));
-
-    if ( ret < 0 )
-        goto error_free_unlock;
-
-    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
-    if ( copy_to_guest(buf, policy_buffer, be32_to_cpu(bin_pol->len)) )
-        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
-acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size)
-{ 
-    /* send stats to user space */
-    u8 *stats_buffer;
-    int len1, len2;
-    struct acm_stats_buffer acm_stats;
-
-    if ( (stats_buffer = xmalloc_array(u8, buf_size)) == NULL )
-        return -ENOMEM;
-
-    read_lock(&acm_bin_pol_rwlock);
-     
-    len1 = acm_primary_ops->dump_statistics(
-                             stats_buffer + sizeof(struct acm_stats_buffer),
-                             buf_size - sizeof(struct acm_stats_buffer));
-    if ( len1 < 0 )
-        goto error_lock_free;
-      
-    len2 = acm_secondary_ops->dump_statistics(
-                      stats_buffer + sizeof(struct acm_stats_buffer) + len1,
-                      buf_size - sizeof(struct acm_stats_buffer) - len1);
-    if ( len2 < 0 )
-        goto error_lock_free;
-
-    acm_stats.magic = cpu_to_be32(ACM_MAGIC);
-    acm_stats.primary_policy_code =
-                           cpu_to_be32(acm_bin_pol.primary_policy_code);
-    acm_stats.secondary_policy_code =
-                           cpu_to_be32(acm_bin_pol.secondary_policy_code);
-    acm_stats.primary_stats_offset =
-                           cpu_to_be32(sizeof(struct acm_stats_buffer));
-    acm_stats.secondary_stats_offset =
-                           cpu_to_be32(sizeof(struct acm_stats_buffer) + len1);
-    acm_stats.len = cpu_to_be32(sizeof(struct acm_stats_buffer) + len1 + len2);
-
-    memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
-
-    if ( copy_to_guest(buf,
-                       stats_buffer,
-                       sizeof(struct acm_stats_buffer) + len1 + len2) )
-        goto error_lock_free;
-
-    read_unlock(&acm_bin_pol_rwlock);
-    xfree(stats_buffer);
-
-    return ACM_OK;
-
- error_lock_free:
-    read_unlock(&acm_bin_pol_rwlock);
-    xfree(stats_buffer);
-
-    return -EFAULT;
-}
-
-
-int
-acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) 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->policy_reference_offset = acm_ssid->len;
-    ret = acm_dump_policy_reference(
-                          ssid_buffer + acm_ssid->policy_reference_offset,
-                          buf_size - acm_ssid->policy_reference_offset);
-    if ( ret < 0 )
-        goto error_free_unlock;
-
-    acm_ssid->len += ret;
-    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_guest(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;
-}
-
-int
-acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook)
-{
-    int ret = ACM_ACCESS_DENIED;
-    switch ( hook )
-    {
-
-    case ACMHOOK_sharing:
-        /* Sharing hook restricts access in STE policy only */
-        ret = acm_sharing(ssidref1, ssidref2);
-        break;
-
-    case ACMHOOK_authorization:
-        ret = acm_authorization(ssidref1, ssidref2);
-        break;
-
-    default:
-        /* deny */
-        break;
-    }
-
-    printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
-            __func__, ssidref1, ssidref2,
-            (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
-
-    return ret;
-}
-
-
-
-/*
-   Check if an ssidref of the current policy type is being used by any
-   domain.
- */
-static int
-acm_check_used_ssidref(uint32_t policy_type, uint32_t search_ssidref,
-                       struct acm_sized_buffer *errors)
-{
-    int rc = 0;
-    struct acm_ssid_domain *rawssid;
-
-    read_lock(&ssid_list_rwlock);
-
-    for_each_acmssid( rawssid )
-    {
-        ssidref_t ssidref;
-        void *s = GET_SSIDP(policy_type, rawssid);
-
-        if ( policy_type == ACM_CHINESE_WALL_POLICY )
-        {
-            ssidref = ((struct chwall_ssid *)s)->chwall_ssidref;
-        } else {
-            ssidref = ((struct ste_ssid *)s)->ste_ssidref;
-        }
-        gdprintk(XENLOG_INFO,"domid=%d: search ssidref=%d, ssidref=%d\n",
-                 rawssid->domainid,search_ssidref,ssidref);
-        if ( ssidref == search_ssidref )
-        {
-            /* one is enough */
-            acm_array_append_tuple(errors, ACM_SSIDREF_IN_USE, search_ssidref);
-            rc = 1;
-            break;
-        }
-    }
-
-    read_unlock(&ssid_list_rwlock);
-
-    return rc;
-}
-
-
-/*
- * Translate a current ssidref into its future representation under
- * the new policy.
- * The map provides translation of ssidrefs from old to new in tuples
- * of (old ssidref, new ssidref).
- */
-static ssidref_t
-oldssid_to_newssid(const struct acm_ssid_domain *rawssid,
-                   const struct acm_sized_buffer *map)
-{
-    uint i;
-
-    if ( rawssid != NULL )
-    {
-        ssidref_t ssid = rawssid->ssidref & 0xffff;
-        for ( i = 0; i + 1 < map->num_items; i += 2 )
-        {
-            if ( map->array[i] == ssid )
-            {
-                return (map->array[i+1] << 16 | map->array[i+1]);
-            }
-        }
-    }
-    return ACM_INVALID_SSIDREF;
-}
-
-
-/*
- * Assign an ssidref to the CHWALL policy component of the domain
- */
-static void
-acm_pri_policy_assign_ssidref(struct acm_ssid_domain *rawssid,
-                              ssidref_t new_ssid)
-{
-    struct chwall_ssid *chwall = (struct chwall_ssid *)rawssid->primary_ssid;
-    chwall->chwall_ssidref = new_ssid;
-}
-
-
-/*
- * Assign an ssidref to the STE policy component of the domain
- */
-static void
-acm_sec_policy_assign_ssidref(struct acm_ssid_domain *rawssid,
-                              ssidref_t new_ssid)
-{
-    struct ste_ssid *ste = (struct ste_ssid *)rawssid->secondary_ssid;
-    ste->ste_ssidref = new_ssid;
-}
-
-/*
-   Change the ssidrefs on each domain using a passed translation function;
- */
-static void
-acm_doms_change_ssidref(ssidref_t (*translator_fn)
-                          (const struct acm_ssid_domain *,
-                           const struct acm_sized_buffer *),
-                        struct acm_sized_buffer *translation_map)
-{
-    struct acm_ssid_domain *rawssid;
-
-    write_lock(&ssid_list_rwlock);
-
-    for_each_acmssid( rawssid )
-    {
-        ssidref_t new_ssid;
-
-        rawssid->old_ssidref = rawssid->ssidref;
-
-        new_ssid = translator_fn(rawssid, translation_map);
-        if ( new_ssid == ACM_INVALID_SSIDREF )
-        {
-            /* means no mapping found, so no change -- old = new */
-            continue;
-        }
-
-        acm_pri_policy_assign_ssidref(rawssid, ACM_PRIMARY  (new_ssid) );
-        acm_sec_policy_assign_ssidref(rawssid, ACM_SECONDARY(new_ssid) );
-
-        rawssid->ssidref = new_ssid;
-    }
-
-    write_unlock(&ssid_list_rwlock);
-}
-
-/*
- * Restore the previous ssidref values on all domains
- */
-static void
-acm_doms_restore_ssidref(void)
-{
-    struct acm_ssid_domain *rawssid;
-
-    write_lock(&ssid_list_rwlock);
-
-    for_each_acmssid( rawssid )
-    {
-        ssidref_t old_ssid;
-
-        if ( rawssid->old_ssidref == rawssid->ssidref )
-            continue;
-
-        old_ssid = rawssid->old_ssidref & 0xffff;
-        rawssid->ssidref = rawssid->old_ssidref;
-
-        acm_pri_policy_assign_ssidref(rawssid, old_ssid);
-        acm_sec_policy_assign_ssidref(rawssid, old_ssid);
-    }
-
-    write_unlock(&ssid_list_rwlock);
-}
-
-
-/*
-   Check the list of domains whether either one of them uses a
-   to-be-deleted ssidref.
- */
-static int
-acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels,
-                           struct acm_sized_buffer *errors)
-{
-    int rc = 0;
-    uint idx;
-    /* check for running domains that should not be there anymore */
-    for ( idx = 0; idx < dels->num_items; idx++ )
-    {
-        if ( acm_check_used_ssidref(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
-                                    dels->array[idx],
-                                    errors) > 0 ||
-             acm_check_used_ssidref(ACM_CHINESE_WALL_POLICY,
-                                    dels->array[idx],
-                                    errors) > 0)
-        {
-            rc = ACM_ERROR;
-            break;
-        }
-    }
-    return rc;
-}
-
-
-/*
- * Change the policy of the system.
- */
-int
-acm_change_policy(struct acm_change_policy *chgpolicy)
-{
-    int rc = 0;
-    u8 *binpolicy = NULL;
-    struct acm_sized_buffer dels =
-    {
-        .array = NULL,
-    };
-    struct acm_sized_buffer ssidmap =
-    {
-        .array = NULL,
-    };
-    struct acm_sized_buffer errors =
-    {
-        .array = NULL,
-    };
-
-    gdprintk(XENLOG_INFO, "change policy operation\n");
-
-    if ( (chgpolicy->delarray_size > 4096) ||
-         (chgpolicy->chgarray_size > 4096) ||
-         (chgpolicy->errarray_size > 4096))
-    {
-        return ACM_ERROR;
-    }
-
-    dels.num_items = chgpolicy->delarray_size / sizeof(uint32_t);
-    if ( dels.num_items > 0 )
-    {
-        dels.array = xmalloc_array(uint32_t, dels.num_items);
-        if ( dels.array == NULL )
-        {
-            rc = -ENOMEM;
-            goto acm_chg_policy_exit;
-        }
-    }
-
-    ssidmap.num_items = chgpolicy->chgarray_size / sizeof(uint32_t);
-    if ( ssidmap.num_items > 0 )
-    {
-        ssidmap.array = xmalloc_array(uint32_t, ssidmap.num_items);
-        if ( ssidmap.array == NULL )
-        {
-            rc = -ENOMEM;
-            goto acm_chg_policy_exit;
-        }
-    }
-
-    errors.num_items = chgpolicy->errarray_size / sizeof(uint32_t);
-    if ( errors.num_items > 0 )
-    {
-        errors.array = xmalloc_array(uint32_t, errors.num_items);
-        if ( errors.array == NULL )
-        {
-            rc = -ENOMEM;
-            goto acm_chg_policy_exit;
-        }
-        memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items);
-    }
-
-    binpolicy = xmalloc_array(u8,
-                              chgpolicy->policy_pushcache_size);
-    if ( binpolicy == NULL )
-    {
-        rc = -ENOMEM;
-        goto acm_chg_policy_exit;
-    }
-
-    if ( copy_from_guest(dels.array,
-                         chgpolicy->del_array,
-                         dels.num_items) ||
-         copy_from_guest(ssidmap.array,
-                         chgpolicy->chg_array,
-                         ssidmap.num_items) ||
-         copy_from_guest(binpolicy,
-                         chgpolicy->policy_pushcache,
-                         chgpolicy->policy_pushcache_size ))
-    {
-        rc = -EFAULT;
-        goto acm_chg_policy_exit;
-    }
-
-    rc = do_acm_set_policy(binpolicy,
-                           chgpolicy->policy_pushcache_size,
-                           0,
-                           &dels, &ssidmap, &errors);
-
-    if ( (errors.num_items > 0) &&
-         copy_to_guest(chgpolicy->err_array,
-                       errors.array,
-                       errors.num_items ) )
-    {
-        rc = -EFAULT;
-        goto acm_chg_policy_exit;
-    }
-
-
-acm_chg_policy_exit:
-    xfree(dels.array);
-    xfree(ssidmap.array);
-    xfree(errors.array);
-    xfree(binpolicy);
-
-    return rc;
-}
-
-
-/*
- * Lookup the new ssidref given the domain's id.
- * The translation map provides a list of tuples in the format
- * (domid, new ssidref).
- */
-static ssidref_t
-domid_to_newssid(const struct acm_ssid_domain *rawssid,
-                 const struct acm_sized_buffer *map)
-{
-    domid_t domid = rawssid->domainid;
-    uint i;
-    for ( i = 0; (i+1) < map->num_items; i += 2 )
-    {
-        if ( map->array[i] == domid )
-            return (ssidref_t)map->array[i+1];
-    }
-    return ACM_INVALID_SSIDREF;
-}
-
-
-int
-do_acm_relabel_doms(struct acm_sized_buffer *relabel_map,
-                    struct acm_sized_buffer *errors)
-{
-    int rc = 0, irc;
-
-    write_lock(&acm_bin_pol_rwlock);
-
-    acm_doms_change_ssidref(domid_to_newssid, relabel_map);
-
-    /* run tests; collect as much error info as possible */
-    irc =  do_chwall_init_state_curr(errors);
-    irc += do_ste_init_state_curr(errors);
-    if ( irc != 0 )
-    {
-        rc = -EFAULT;
-        goto acm_relabel_doms_lock_err_exit;
-    }
-
-    write_unlock(&acm_bin_pol_rwlock);
-
-    return rc;
-
-acm_relabel_doms_lock_err_exit:
-    /* revert the new ssidref assignment */
-    acm_doms_restore_ssidref();
-    do_chwall_init_state_curr(NULL);
-
-    write_unlock(&acm_bin_pol_rwlock);
-
-    return rc;
-}
-
-
-int
-acm_relabel_domains(struct acm_relabel_doms *relabel)
-{
-    int rc = ACM_OK;
-    struct acm_sized_buffer relabels =
-    {
-        .array = NULL,
-    };
-    struct acm_sized_buffer errors =
-    {
-        .array = NULL,
-    };
-
-    if ( relabel->relabel_map_size > 4096 )
-    {
-        return ACM_ERROR;
-    }
-
-    relabels.num_items = relabel->relabel_map_size / sizeof(uint32_t);
-    if ( relabels.num_items > 0 )
-    {
-        relabels.array = xmalloc_array(uint32_t, relabels.num_items);
-        if ( relabels.array == NULL )
-        {
-            rc = -ENOMEM;
-            goto acm_relabel_doms_exit;
-        }
-    }
-
-    errors.num_items = relabel->errarray_size / sizeof(uint32_t);
-    if ( errors.num_items > 0 )
-    {
-        errors.array = xmalloc_array(uint32_t, errors.num_items);
-        if ( errors.array == NULL )
-        {
-            rc = -ENOMEM;
-            goto acm_relabel_doms_exit;
-        }
-        memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items);
-    }
-
-    if ( copy_from_guest(relabels.array,
-                         relabel->relabel_map,
-                         relabels.num_items) )
-    {
-        rc = -EFAULT;
-        goto acm_relabel_doms_exit;
-    }
-
-    rc = do_acm_relabel_doms(&relabels, &errors);
-
-    if ( copy_to_guest(relabel->err_array,
-                       errors.array,
-                       errors.num_items ) )
-        rc = -EFAULT;
-
-acm_relabel_doms_exit:
-    xfree(relabels.array);
-    xfree(errors.array);
-    return rc;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Thu Sep 06 09:05:26 
2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,914 +0,0 @@
-/****************************************************************
- * acm_simple_type_enforcement_hooks.c
- * 
- * Copyright (C) 2005 IBM Corporation
- *
- * Author:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * Contributors:
- * Stefan Berger <stefanb@xxxxxxxxxxxxxx>
- *         support for network order binary policies
- *
- * 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.
- *
- * sHype Simple Type Enforcement for Xen
- *     STE allows to control which domains can setup sharing
- *     (eventchannels right now) with which other domains. Hooks
- *     are defined and called throughout Xen when domains bind to
- *     shared resources (setup eventchannels) and a domain is allowed
- *     to setup sharing with another domain if and only if both domains
- *     share at least on common type.
- *
- */
-
-#include <xen/lib.h>
-#include <asm/types.h>
-#include <asm/current.h>
-#include <acm/acm_hooks.h>
-#include <asm/atomic.h>
-#include <acm/acm_endian.h>
-#include <acm/acm_core.h>
-
-ssidref_t dom0_ste_ssidref = 0x0001;
-
-/* local cache structures for STE policy */
-struct ste_binary_policy ste_bin_pol;
-
-static inline int have_common_type (ssidref_t ref1, ssidref_t ref2)
-{
-    int i;
-
-    if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs &&
-         ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs )
-    {
-        for( i = 0; i< ste_bin_pol.max_types; i++ )
-            if ( ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] &&
-                 ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i])
-            {
-                printkd("%s: common type #%02x.\n", __func__, i);
-                return 1;
-            }
-    }
-    return 0;
-}
-
-static inline int is_superset(ssidref_t ref1, ssidref_t ref2)
-{
-    int i;
-
-    if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs &&
-         ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs )
-    {
-        for( i = 0; i< ste_bin_pol.max_types; i++ )
-            if (!ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] &&
-                 ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i])
-            {
-                return 0;
-            }
-    } else {
-        return 0;
-    }
-    return 1;
-}
-
-
-/* Helper function: return = (subj and obj share a common type) */
-static int share_common_type(struct domain *subj, struct domain *obj)
-{
-    ssidref_t ref_s, ref_o;
-    int ret;
-
-    if ( (subj == NULL) || (obj == NULL) ||
-         (subj->ssid == NULL) || (obj->ssid == NULL) )
-        return 0;
-
-    read_lock(&acm_bin_pol_rwlock);
-
-    /* lookup the policy-local ssids */
-    ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
-                       (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref;
-    ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                       (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref;
-    /* check whether subj and obj share a common ste type */
-    ret = have_common_type(ref_s, ref_o);
-
-    read_unlock(&acm_bin_pol_rwlock);
-
-    return ret;
-}
-
-/*
- * Initializing STE policy (will be filled by policy partition
- * using setpolicy command)
- */
-int acm_init_ste_policy(void)
-{
-    /* minimal startup policy; policy write-locked already */
-    ste_bin_pol.max_types = 1;
-    ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref;
-    ste_bin_pol.ssidrefs =
-            (domaintype_t *)xmalloc_array(domaintype_t,
-                                          ste_bin_pol.max_types *
-                                          ste_bin_pol.max_ssidrefs);
-
-    if (ste_bin_pol.ssidrefs == NULL)
-        return ACM_INIT_SSID_ERROR;
-
-    memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) *
-                                    ste_bin_pol.max_types *
-                                    ste_bin_pol.max_ssidrefs);
-
-    /* initialize state so that dom0 can start up and communicate with itself 
*/
-    ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1;
-
-    /* init stats */
-    atomic_set(&(ste_bin_pol.ec_eval_count), 0);
-    atomic_set(&(ste_bin_pol.ec_denied_count), 0);
-    atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
-    atomic_set(&(ste_bin_pol.gt_eval_count), 0);
-    atomic_set(&(ste_bin_pol.gt_denied_count), 0);
-    atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
-
-    return ACM_OK;
-}
-
-
-/* ste initialization function hooks */
-static int
-ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
-{
-    int i;
-    struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid);
-
-    if ( ste_ssidp == NULL )
-        return ACM_INIT_SSID_ERROR;
-
-    /* get policy-local ssid reference */
-    ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
-                                         ssidref);
-
-    if ( (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) )
-    {
-        printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n",
-                __func__, ste_ssidp->ste_ssidref);
-        xfree(ste_ssidp);
-        return ACM_INIT_SSID_ERROR;
-    }
-    /* clean ste cache */
-    for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
-        ste_ssidp->ste_cache[i].valid = ACM_STE_free;
-
-    (*ste_ssid) = ste_ssidp;
-    printkd("%s: determined ste_ssidref to %x.\n", 
-            __func__, ste_ssidp->ste_ssidref);
-
-    return ACM_OK;
-}
-
-
-static void
-ste_free_domain_ssid(void *ste_ssid)
-{
-    xfree(ste_ssid);
-    return;
-}
-
-/* dump type enforcement cache; policy read-locked already */
-static int 
-ste_dump_policy(u8 *buf, u32 buf_size) {
-    struct acm_ste_policy_buffer *ste_buf =
-                                  (struct acm_ste_policy_buffer *)buf;
-    int ret = 0;
-
-    if ( buf_size < sizeof(struct acm_ste_policy_buffer) )
-        return -EINVAL;
-
-    ste_buf->ste_max_types = cpu_to_be32(ste_bin_pol.max_types);
-    ste_buf->ste_max_ssidrefs = cpu_to_be32(ste_bin_pol.max_ssidrefs);
-    ste_buf->policy_code = cpu_to_be32(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
-    ste_buf->ste_ssid_offset =
-                           cpu_to_be32(sizeof(struct acm_ste_policy_buffer));
-    ret = be32_to_cpu(ste_buf->ste_ssid_offset) +
-        sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
-
-    ret = (ret + 7) & ~7;
-
-    if (buf_size < ret)
-        return -EINVAL;
-
-    /* now copy buffer over */
-    arrcpy(buf + be32_to_cpu(ste_buf->ste_ssid_offset),
-           ste_bin_pol.ssidrefs,
-           sizeof(domaintype_t),
-           ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
-
-    return ret;
-}
-
-/*
- * ste_init_state is called when a policy is changed to detect violations
- * (return != 0). from a security point of view, we simulate that all
- * running domains are re-started and all sharing decisions are replayed
- * to detect violations or current sharing behavior (right now:
- * event_channels, future: also grant_tables)
- */ 
-static int
-ste_init_state(struct acm_sized_buffer *errors)
-{
-    int violation = 1;
-    struct ste_ssid *ste_ssid, *ste_rssid;
-    ssidref_t ste_ssidref, ste_rssidref;
-    struct domain *d, *rdom;
-    domid_t rdomid;
-    struct active_grant_entry *act;
-    int port, i;
-
-    rcu_read_lock(&domlist_read_lock);
-    read_lock(&ssid_list_rwlock);
-
-    /* go through all domains and adjust policy as if this domain was
-       started now */
-
-    for_each_domain ( d )
-    {
-        struct evtchn *ports;
-        unsigned int bucket;
-
-        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                             (struct acm_ssid_domain *)d->ssid);
-        ste_ssidref = ste_ssid->ste_ssidref;
-        traceprintk("%s: validating policy for eventch domain %x 
(ste-Ref=%x).\n",
-                    __func__, d->domain_id, ste_ssidref);
-        /* a) check for event channel conflicts */
-        for ( bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++ )
-        {
-            spin_lock(&d->evtchn_lock);
-            ports = d->evtchn[bucket];
-            if ( ports == NULL)
-            {
-                spin_unlock(&d->evtchn_lock);
-                break;
-            }
-
-            for ( port = 0; port < EVTCHNS_PER_BUCKET; port++ )
-            {
-                if ( ports[port].state == ECS_INTERDOMAIN )
-                {
-                    rdom = ports[port].u.interdomain.remote_dom;
-                    rdomid = rdom->domain_id;
-                } else {
-                    continue; /* port unused */
-                }
-
-                /* rdom now has remote domain */
-                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
-                                      (struct acm_ssid_domain *)(rdom->ssid));
-                ste_rssidref = ste_rssid->ste_ssidref;
-                traceprintk("%s: eventch: domain %x (ssidref %x) --> "
-                            "domain %x (rssidref %x) used (port %x).\n",
-                            __func__, d->domain_id, ste_ssidref,
-                            rdom->domain_id, ste_rssidref, port);
-                /* check whether on subj->ssid, obj->ssid share a common type*/
-                if ( ! have_common_type(ste_ssidref, ste_rssidref) )
-                {
-                    printkd("%s: Policy violation in event channel domain "
-                            "%x -> domain %x.\n",
-                            __func__, d->domain_id, rdomid);
-                    spin_unlock(&d->evtchn_lock);
-
-                    acm_array_append_tuple(errors,
-                                           ACM_EVTCHN_SHARING_VIOLATION,
-                                           d->domain_id << 16 | rdomid);
-                    goto out;
-                }
-            }
-            spin_unlock(&d->evtchn_lock);
-        } 
-
-
-        /* b) check for grant table conflicts on shared pages */
-        spin_lock(&d->grant_table->lock);
-        for ( i = 0; i < nr_active_grant_frames(d->grant_table); i++ )
-        {
-#define APP (PAGE_SIZE / sizeof(struct active_grant_entry))
-            act = &d->grant_table->active[i/APP][i%APP];
-            if ( act->pin != 0 ) {
-                printkd("%s: grant dom (%hu) SHARED (%d) pin (%d)  "
-                        "dom:(%hu) frame:(%lx)\n",
-                        __func__, d->domain_id, i, act->pin,
-                        act->domid, (unsigned long)act->frame);
-                rdomid = act->domid;
-                if ( (rdom = rcu_lock_domain_by_id(rdomid)) == NULL )
-                {
-                    spin_unlock(&d->grant_table->lock);
-                    printkd("%s: domain not found ERROR!\n", __func__);
-
-                    acm_array_append_tuple(errors,
-                                           ACM_DOMAIN_LOOKUP,
-                                           rdomid);
-                    goto out;
-                }
-                /* rdom now has remote domain */
-                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
-                                      (struct acm_ssid_domain *)(rdom->ssid));
-                ste_rssidref = ste_rssid->ste_ssidref;
-                rcu_unlock_domain(rdom);
-                if ( ! have_common_type(ste_ssidref, ste_rssidref) )
-                {
-                    spin_unlock(&d->grant_table->lock);
-                    printkd("%s: Policy violation in grant table "
-                            "sharing domain %x -> domain %x.\n",
-                            __func__, d->domain_id, rdomid);
-
-                    acm_array_append_tuple(errors,
-                                           ACM_GNTTAB_SHARING_VIOLATION,
-                                           d->domain_id << 16 | rdomid);
-                    goto out;
-                }
-            }
-        }
-        spin_unlock(&d->grant_table->lock);
-    }
-    violation = 0;
- out:
-    read_unlock(&ssid_list_rwlock);
-    rcu_read_unlock(&domlist_read_lock);
-    return violation;
-    /*
-       returning "violation != 0" means that existing sharing between domains
-       would not have been allowed if the new policy had been enforced before
-       the sharing; for ste, this means that there are at least 2 domains
-       that have established sharing through event-channels or grant-tables
-       but these two domains don't have no longer a common type in their
-       typesets referenced by their ssidrefs
-      */
-}
-
-
-/*
- * Call ste_init_state with the current policy.
- */
-int
-do_ste_init_state_curr(struct acm_sized_buffer *errors)
-{
-    return ste_init_state(errors);
-}
-
-
-/* set new policy; policy write-locked already */
-static int
-_ste_update_policy(u8 *buf, u32 buf_size, int test_only,
-                   struct acm_sized_buffer *errors)
-{
-    int rc = -EFAULT;
-    struct acm_ste_policy_buffer *ste_buf =
-                                 (struct acm_ste_policy_buffer *)buf;
-    void *ssidrefsbuf;
-    struct ste_ssid *ste_ssid;
-    struct acm_ssid_domain *rawssid;
-    int i;
-
-
-    /* 1. create and copy-in new ssidrefs buffer */
-    ssidrefsbuf = xmalloc_array(u8,
-                                sizeof(domaintype_t) *
-                                 ste_buf->ste_max_types *
-                                 ste_buf->ste_max_ssidrefs);
-    if ( ssidrefsbuf == NULL ) {
-        return -ENOMEM;
-    }
-    if ( ste_buf->ste_ssid_offset +
-         sizeof(domaintype_t) *
-         ste_buf->ste_max_ssidrefs *
-         ste_buf->ste_max_types > buf_size )
-        goto error_free;
-
-    arrcpy(ssidrefsbuf, 
-           buf + ste_buf->ste_ssid_offset,
-           sizeof(domaintype_t),
-           ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
-
-
-    /*
-     * 3. in test mode: re-calculate sharing decisions based on running
-     *    domains; this can fail if new policy is conflicting with sharing
-     *    of running domains
-     *    now: reject violating new policy; future: adjust sharing through
-     *    revoking sharing
-     */
-
-    if ( test_only ) {
-        /* temporarily replace old policy with new one for the testing */
-        struct ste_binary_policy orig_ste_bin_pol = ste_bin_pol;
-        ste_bin_pol.max_types = ste_buf->ste_max_types;
-        ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
-        ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
-
-        if ( ste_init_state(errors) )
-        {
-            /* new policy conflicts with sharing of running domains */
-            printk("%s: New policy conflicts with running domains. "
-                   "Policy load aborted.\n", __func__);
-        } else {
-            rc = ACM_OK;
-        }
-        /* revert changes, no matter whether testing was successful or not */
-        ste_bin_pol = orig_ste_bin_pol;
-        goto error_free;
-    }
-
-    /* 3. replace old policy (activate new policy) */
-    ste_bin_pol.max_types = ste_buf->ste_max_types;
-    ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
-    xfree(ste_bin_pol.ssidrefs);
-    ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
-
-    /* clear all ste caches */
-    read_lock(&ssid_list_rwlock);
-
-    for_each_acmssid( rawssid )
-    {
-        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid);
-        for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
-            ste_ssid->ste_cache[i].valid = ACM_STE_free;
-    }
-
-    read_unlock(&ssid_list_rwlock);
-
-    return ACM_OK;
-
- error_free:
-    if ( !test_only )
-        printk("%s: ERROR setting policy.\n", __func__);
-    xfree(ssidrefsbuf);
-    return rc;
-}
-
-static int
-ste_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
-                struct acm_sized_buffer *errors)
-{
-    struct acm_ste_policy_buffer *ste_buf =
-             (struct acm_ste_policy_buffer *)buf;
-
-    if ( buf_size < sizeof(struct acm_ste_policy_buffer) )
-        return -EINVAL;
-
-    /* Convert endianess of policy */
-    ste_buf->policy_code = be32_to_cpu(ste_buf->policy_code);
-    ste_buf->policy_version = be32_to_cpu(ste_buf->policy_version);
-    ste_buf->ste_max_types = be32_to_cpu(ste_buf->ste_max_types);
-    ste_buf->ste_max_ssidrefs = be32_to_cpu(ste_buf->ste_max_ssidrefs);
-    ste_buf->ste_ssid_offset = be32_to_cpu(ste_buf->ste_ssid_offset);
-
-    /* policy type and version checks */
-    if ( (ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ||
-         (ste_buf->policy_version != ACM_STE_VERSION) )
-        return -EINVAL;
-
-    /* during boot dom0_chwall_ssidref is set */
-    if ( is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs) )
-        return -EINVAL;
-
-    return _ste_update_policy(buf, buf_size, 1, errors);
-}
-
-static int
-ste_set_policy(u8 *buf, u32 buf_size)
-{
-    return _ste_update_policy(buf, buf_size, 0, NULL);
-}
-
-static int 
-ste_dump_stats(u8 *buf, u16 buf_len)
-{
-    struct acm_ste_stats_buffer stats;
-
-    /* now send the hook counts to user space */
-    stats.ec_eval_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_eval_count));
-    stats.gt_eval_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_eval_count));
-    stats.ec_denied_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_denied_count));
-    stats.gt_denied_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_denied_count));
-    stats.ec_cachehit_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_cachehit_count));
-    stats.gt_cachehit_count =
-                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_cachehit_count));
-
-    if ( buf_len < sizeof(struct acm_ste_stats_buffer) )
-        return -ENOMEM;
-
-    memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));
-
-    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 */
-static int inline
-check_cache(struct domain *dom, domid_t rdom)
-{
-    struct ste_ssid *ste_ssid;
-    int i;
-
-    printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
-
-    if (dom->ssid == NULL)
-        return 0;
-    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                         (struct acm_ssid_domain *)(dom->ssid));
-
-    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
-    {
-        if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
-             (ste_ssid->ste_cache[i].id == rdom) )
-        {
-            printkd("cache hit (entry %x, id= %x!\n",
-                    i,
-                    ste_ssid->ste_cache[i].id);
-            return 1;
-        }
-    }
-    return 0;
-}
-
-
-/* we only get here if there is NO entry yet; no duplication check! */
-static void inline
-cache_result(struct domain *subj, struct domain *obj) {
-    struct ste_ssid *ste_ssid;
-    int i;
-
-    printkd("caching from doms: %x --> %x.\n",
-            subj->domain_id, obj->domain_id);
-
-    if ( subj->ssid == NULL )
-        return;
-
-    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                         (struct acm_ssid_domain *)(subj)->ssid);
-
-    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
-        if ( ste_ssid->ste_cache[i].valid == ACM_STE_free )
-            break;
-    if ( i < ACM_TE_CACHE_SIZE )
-    {
-        ste_ssid->ste_cache[i].valid = ACM_STE_valid;
-        ste_ssid->ste_cache[i].id = obj->domain_id;
-    } else
-        printk ("Cache of dom %x is full!\n", subj->domain_id);
-}
-
-/* deletes entries for domain 'id' from all caches (re-use) */
-static void inline
-clean_id_from_cache(domid_t id) 
-{
-    struct ste_ssid *ste_ssid;
-    int i;
-    struct acm_ssid_domain *rawssid;
-
-    printkd("deleting cache for dom %x.\n", id);
-
-    read_lock(&ssid_list_rwlock);
-    /* look through caches of all domains */
-
-    for_each_acmssid ( rawssid )
-    {
-        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid);
-
-        if ( !ste_ssid )
-        {
-            printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n",
-                   __func__);
-            goto out;
-        }
-        for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
-            if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
-                 (ste_ssid->ste_cache[i].id == id) )
-                ste_ssid->ste_cache[i].valid = ACM_STE_free;
-    }
-
- out:
-    read_unlock(&ssid_list_rwlock);
-}
-
-/***************************
- * Authorization functions
- **************************/
-static int 
-ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
-{      
-    /* check for ssidref in range for policy */
-    ssidref_t ste_ssidref;
-
-    traceprintk("%s.\n", __func__);
-
-    read_lock(&acm_bin_pol_rwlock);
-
-    ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
-
-    if ( ste_ssidref >= ste_bin_pol.max_ssidrefs )
-    {
-        printk("%s: ERROR ste_ssidref > max(%x).\n", 
-               __func__, ste_bin_pol.max_ssidrefs-1);
-        read_unlock(&acm_bin_pol_rwlock);
-        return ACM_ACCESS_DENIED;
-    }
-
-    read_unlock(&acm_bin_pol_rwlock);
-
-    return ACM_ACCESS_PERMITTED;
-}
-
-static int
-ste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t  domid)
-{
-    return ste_pre_domain_create(subject_ssid, ssidref);
-}
-
-
-static void 
-ste_domain_destroy(void *subject_ssid, struct domain *d)
-{
-    /* clean all cache entries for destroyed domain (might be re-used) */
-    clean_id_from_cache(d->domain_id);
-}
-
-/* -------- EVENTCHANNEL OPERATIONS -----------*/
-static int
-ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) {
-    struct domain *subj, *obj;
-    int ret;
-    traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
-                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
-
-    if ( id1 == DOMID_SELF )
-        id1 = current->domain->domain_id;
-    if ( id2 == DOMID_SELF )
-        id2 = current->domain->domain_id;
-
-    subj = rcu_lock_domain_by_id(id1);
-    obj  = rcu_lock_domain_by_id(id2);
-    if ( (subj == NULL) || (obj == NULL) )
-    {
-        ret = ACM_ACCESS_DENIED;
-        goto out;
-    }
-    /* cache check late */
-    if ( check_cache(subj, obj->domain_id) )
-    {
-        atomic_inc(&ste_bin_pol.ec_cachehit_count);
-        ret = ACM_ACCESS_PERMITTED;
-        goto out;
-    }
-    atomic_inc(&ste_bin_pol.ec_eval_count);
-
-    if ( share_common_type(subj, obj) )
-    {
-        cache_result(subj, obj);
-        ret = ACM_ACCESS_PERMITTED;
-    }
-    else
-    {
-        atomic_inc(&ste_bin_pol.ec_denied_count);
-        ret = ACM_ACCESS_DENIED;
-    }
-
-  out:
-    if ( obj != NULL )
-        rcu_unlock_domain(obj);
-    if ( subj != NULL )
-        rcu_unlock_domain(subj);
-    return ret;
-}
-
-static int
-ste_pre_eventchannel_interdomain(domid_t id)
-{
-    struct domain *subj=NULL, *obj=NULL;
-    int ret;
-
-    traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                current->domain->domain_id,
-                (id == DOMID_SELF) ? current->domain->domain_id : id);
-
-    /* following is a bit longer but ensures that we
-     * "put" only domains that we where "find"-ing 
-     */
-    if ( id == DOMID_SELF )
-        id = current->domain->domain_id;
-
-    subj = current->domain;
-    obj  = rcu_lock_domain_by_id(id);
-    if ( obj == NULL )
-    {
-        ret = ACM_ACCESS_DENIED;
-        goto out;
-    }
-
-    /* cache check late, but evtchn is not on performance critical path */
-    if ( check_cache(subj, obj->domain_id) )
-    {
-        atomic_inc(&ste_bin_pol.ec_cachehit_count);
-        ret = ACM_ACCESS_PERMITTED;
-        goto out;
-    }
-
-    atomic_inc(&ste_bin_pol.ec_eval_count);
-
-    if ( share_common_type(subj, obj) )
-    {
-        cache_result(subj, obj);
-        ret = ACM_ACCESS_PERMITTED;
-    }
-    else
-    {
-        atomic_inc(&ste_bin_pol.ec_denied_count);
-        ret = ACM_ACCESS_DENIED;
-    }
-
- out:
-    if ( obj != NULL )
-        rcu_unlock_domain(obj);
-    return ret;
-}
-
-/* -------- SHARED MEMORY OPERATIONS -----------*/
-
-static int
-ste_pre_grant_map_ref (domid_t id)
-{
-    struct domain *obj, *subj;
-    int ret;
-    traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                current->domain->domain_id, id);
-
-    if ( check_cache(current->domain, id) )
-    {
-        atomic_inc(&ste_bin_pol.gt_cachehit_count);
-        return ACM_ACCESS_PERMITTED;
-    }
-    atomic_inc(&ste_bin_pol.gt_eval_count);
-    subj = current->domain;
-    obj = rcu_lock_domain_by_id(id);
-
-    if ( share_common_type(subj, obj) )
-    {
-        cache_result(subj, obj);
-        ret = ACM_ACCESS_PERMITTED;
-    }
-    else
-    {
-        atomic_inc(&ste_bin_pol.gt_denied_count);
-        printkd("%s: ACCESS DENIED!\n", __func__);
-        ret = ACM_ACCESS_DENIED;
-    }
-    if ( obj != NULL )
-        rcu_unlock_domain(obj);
-    return ret;
-}
-
-
-/* since setting up grant tables involves some implicit information
-   flow from the creating domain to the domain that is setup, we 
-   check types in addition to the general authorization */
-static int
-ste_pre_grant_setup (domid_t id)
-{
-    struct domain *obj, *subj;
-    int ret;
-    traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                current->domain->domain_id, id);
-
-    if ( check_cache(current->domain, id) )
-    {
-        atomic_inc(&ste_bin_pol.gt_cachehit_count);
-        return ACM_ACCESS_PERMITTED;
-    }
-    atomic_inc(&ste_bin_pol.gt_eval_count);
-    /* a) check authorization (eventually use specific capabilities) */
-    if ( !IS_PRIV(current->domain) )
-    {
-        printk("%s: Grant table management authorization denied ERROR!\n",
-               __func__);
-        return ACM_ACCESS_DENIED;
-    }
-    /* b) check types */
-    subj = current->domain;
-    obj = rcu_lock_domain_by_id(id);
-
-    if ( share_common_type(subj, obj) )
-    {
-        cache_result(subj, obj);
-        ret = ACM_ACCESS_PERMITTED;
-    }
-    else
-    {
-        atomic_inc(&ste_bin_pol.gt_denied_count);
-        ret = ACM_ACCESS_DENIED;
-    }
-    if ( obj != NULL )
-        rcu_unlock_domain(obj);
-    return ret;
-}
-
-/* -------- DOMAIN-Requested Decision hooks -----------*/
-
-static int
-ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
-{
-    int hct = have_common_type(
-        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),
-        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));
-    return (hct ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);
-}
-
-static int
-ste_authorization(ssidref_t ssidref1, ssidref_t ssidref2)
-{
-    int iss = is_superset(
-        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),
-        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));
-    return (iss ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);
-}
-
-static int
-ste_is_default_policy(void)
-{
-    return ((ste_bin_pol.max_types    == 1) &&
-            (ste_bin_pol.max_ssidrefs == 2));
-}
-
-/* now define the hook structure similarly to LSM */
-struct acm_operations acm_simple_type_enforcement_ops = {
-
-    /* policy management services */
-    .init_domain_ssid       = ste_init_domain_ssid,
-    .free_domain_ssid       = ste_free_domain_ssid,
-    .dump_binary_policy     = ste_dump_policy,
-    .test_binary_policy     = ste_test_policy,
-    .set_binary_policy      = ste_set_policy,
-    .dump_statistics        = ste_dump_stats,
-    .dump_ssid_types        = ste_dump_ssid_types,
-
-    /* domain management control hooks */
-    .domain_create          = ste_domain_create,
-    .domain_destroy         = ste_domain_destroy,
-
-    /* event channel control hooks */
-    .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,
-    .sharing                = ste_sharing,
-    .authorization          = ste_authorization,
-
-    .is_default_policy      = ste_is_default_policy,
-};
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c        Thu Sep 06 12:05:15 2007 -0600
@@ -563,6 +563,7 @@ int arch_domain_create(struct domain *d)
                goto fail_nomem;
 
        memset(&d->arch.mm, 0, sizeof(d->arch.mm));
+       d->arch.mm_teardown_offset = 0;
 
        if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
            goto fail_nomem;
@@ -936,14 +937,17 @@ static void relinquish_memory(struct dom
     spin_unlock_recursive(&d->page_alloc_lock);
 }
 
-void domain_relinquish_resources(struct domain *d)
-{
+int domain_relinquish_resources(struct domain *d)
+{
+    int ret;
     /* Relinquish guest resources for VT-i domain. */
     if (d->arch.is_vti)
            vmx_relinquish_guest_resources(d);
 
     /* Tear down shadow mode stuff. */
-    mm_teardown(d);
+    ret = mm_teardown(d);
+    if (ret != 0)
+        return ret;
 
     /* Relinquish every page of memory. */
     relinquish_memory(d, &d->xenpage_list);
@@ -954,6 +958,8 @@ void domain_relinquish_resources(struct 
 
     /* Free page used by xen oprofile buffer */
     free_xenoprof_pages(d);
+
+    return 0;
 }
 
 unsigned long
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/ia64/xen/mm.c    Thu Sep 06 12:05:15 2007 -0600
@@ -215,6 +215,18 @@ alloc_dom_xen_and_dom_io(void)
     BUG_ON(dom_io == NULL);
 }
 
+static int
+mm_teardown_can_skip(struct domain* d, unsigned long offset)
+{
+    return d->arch.mm_teardown_offset > offset;
+}
+
+static void
+mm_teardown_update_offset(struct domain* d, unsigned long offset)
+{
+    d->arch.mm_teardown_offset = offset;
+}
+
 static void
 mm_teardown_pte(struct domain* d, volatile pte_t* pte, unsigned long offset)
 {
@@ -252,46 +264,73 @@ mm_teardown_pte(struct domain* d, volati
     }
 }
 
-static void
+static int
 mm_teardown_pmd(struct domain* d, volatile pmd_t* pmd, unsigned long offset)
 {
     unsigned long i;
     volatile pte_t* pte = pte_offset_map(pmd, offset);
 
     for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
-        if (!pte_present(*pte)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PAGE_SHIFT);
+        if (mm_teardown_can_skip(d, cur_offset + PAGE_SIZE))
             continue;
-        mm_teardown_pte(d, pte, offset + (i << PAGE_SHIFT));
-    }
-}
-
-static void
+        if (!pte_present(*pte)) { // acquire semantics
+            mm_teardown_update_offset(d, cur_offset);
+            continue;
+        }
+        mm_teardown_update_offset(d, cur_offset);
+        mm_teardown_pte(d, pte, cur_offset);
+        if (hypercall_preempt_check())
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+static int
 mm_teardown_pud(struct domain* d, volatile pud_t *pud, unsigned long offset)
 {
     unsigned long i;
     volatile pmd_t *pmd = pmd_offset(pud, offset);
 
     for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
-        if (!pmd_present(*pmd)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PMD_SHIFT);
+        if (mm_teardown_can_skip(d, cur_offset + PMD_SIZE))
             continue;
-        mm_teardown_pmd(d, pmd, offset + (i << PMD_SHIFT));
-    }
-}
-
-static void
+        if (!pmd_present(*pmd)) { // acquire semantics
+            mm_teardown_update_offset(d, cur_offset);
+            continue;
+        }
+        if (mm_teardown_pmd(d, pmd, cur_offset))
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+static int
 mm_teardown_pgd(struct domain* d, volatile pgd_t *pgd, unsigned long offset)
 {
     unsigned long i;
     volatile pud_t *pud = pud_offset(pgd, offset);
 
     for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
-        if (!pud_present(*pud)) // acquire semantics
+        unsigned long cur_offset = offset + (i << PUD_SHIFT);
+#ifndef __PAGETABLE_PUD_FOLDED
+        if (mm_teardown_can_skip(d, cur_offset + PUD_SIZE))
             continue;
-        mm_teardown_pud(d, pud, offset + (i << PUD_SHIFT));
-    }
-}
-
-void
+#endif
+        if (!pud_present(*pud)) { // acquire semantics
+#ifndef __PAGETABLE_PUD_FOLDED
+            mm_teardown_update_offset(d, cur_offset);
+#endif
+            continue;
+        }
+        if (mm_teardown_pud(d, pud, cur_offset))
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+int
 mm_teardown(struct domain* d)
 {
     struct mm_struct* mm = &d->arch.mm;
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/ia64/xen/xensetup.c      Thu Sep 06 12:05:15 2007 -0600
@@ -28,7 +28,7 @@
 #include <asm/iosapic.h>
 #include <xen/softirq.h>
 #include <xen/rcupdate.h>
-#include <acm/acm_hooks.h>
+#include <xsm/acm/acm_hooks.h>
 #include <asm/sn/simulator.h>
 
 unsigned long xenheap_phys_end, total_pages;
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/powerpc/domain.c Thu Sep 06 12:05:15 2007 -0600
@@ -313,13 +313,13 @@ static void relinquish_memory(struct dom
     spin_unlock_recursive(&d->page_alloc_lock);
 }
 
-void domain_relinquish_resources(struct domain *d)
+int domain_relinquish_resources(struct domain *d)
 {
     relinquish_memory(d, &d->xenpage_list);
     relinquish_memory(d, &d->page_list);
     xfree(d->arch.foreign_mfns);
     xfree(d->arch.p2m);
-    return;
+    return 0;
 }
 
 void arch_dump_domain_info(struct domain *d)
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/powerpc/setup.c  Thu Sep 06 12:05:15 2007 -0600
@@ -38,7 +38,7 @@
 #include <xen/numa.h>
 #include <xen/rcupdate.h>
 #include <xen/version.h>
-#include <acm/acm_hooks.h>
+#include <xsm/acm/acm_hooks.h>
 #include <public/version.h>
 #include <asm/mpic.h>
 #include <asm/processor.h>
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/Makefile
--- a/xen/arch/x86/cpu/Makefile Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/cpu/Makefile Thu Sep 06 12:05:15 2007 -0600
@@ -8,5 +8,4 @@ obj-y += intel_cacheinfo.o
 
 obj-$(x86_32) += centaur.o
 obj-$(x86_32) += cyrix.o
-obj-$(x86_32) += rise.o
 obj-$(x86_32) += transmeta.o
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/centaur.c
--- a/xen/arch/x86/cpu/centaur.c        Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/cpu/centaur.c        Thu Sep 06 12:05:15 2007 -0600
@@ -6,248 +6,6 @@
 #include <asm/msr.h>
 #include <asm/e820.h>
 #include "cpu.h"
-
-#ifdef CONFIG_X86_OOSTORE
-
-static u32 __init power2(u32 x)
-{
-       u32 s=1;
-       while(s<=x)
-               s<<=1;
-       return s>>=1;
-}
-
-
-/*
- *     Set up an actual MCR
- */
- 
-static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key)
-{
-       u32 lo, hi;
-       
-       hi = base & ~0xFFF;
-       lo = ~(size-1);         /* Size is a power of 2 so this makes a mask */
-       lo &= ~0xFFF;           /* Remove the ctrl value bits */
-       lo |= key;              /* Attribute we wish to set */
-       wrmsr(reg+MSR_IDT_MCR0, lo, hi);
-       mtrr_centaur_report_mcr(reg, lo, hi);   /* Tell the mtrr driver */
-}
-
-/*
- *     Figure what we can cover with MCR's
- *
- *     Shortcut: We know you can't put 4Gig of RAM on a winchip
- */
-
-static u32 __init ramtop(void)         /* 16388 */
-{
-       int i;
-       u32 top = 0;
-       u32 clip = 0xFFFFFFFFUL;
-       
-       for (i = 0; i < e820.nr_map; i++) {
-               unsigned long start, end;
-
-               if (e820.map[i].addr > 0xFFFFFFFFUL)
-                       continue;
-               /*
-                *      Don't MCR over reserved space. Ignore the ISA hole
-                *      we frob around that catastrophy already
-                */
-                                       
-               if (e820.map[i].type == E820_RESERVED)
-               {
-                       if(e820.map[i].addr >= 0x100000UL && e820.map[i].addr < 
clip)
-                               clip = e820.map[i].addr;
-                       continue;
-               }
-               start = e820.map[i].addr;
-               end = e820.map[i].addr + e820.map[i].size;
-               if (start >= end)
-                       continue;
-               if (end > top)
-                       top = end;
-       }
-       /* Everything below 'top' should be RAM except for the ISA hole.
-          Because of the limited MCR's we want to map NV/ACPI into our
-          MCR range for gunk in RAM 
-          
-          Clip might cause us to MCR insufficient RAM but that is an
-          acceptable failure mode and should only bite obscure boxes with
-          a VESA hole at 15Mb
-          
-          The second case Clip sometimes kicks in is when the EBDA is marked
-          as reserved. Again we fail safe with reasonable results
-       */
-       
-       if(top>clip)
-               top=clip;
-               
-       return top;
-}
-
-/*
- *     Compute a set of MCR's to give maximum coverage
- */
-
-static int __init centaur_mcr_compute(int nr, int key)
-{
-       u32 mem = ramtop();
-       u32 root = power2(mem);
-       u32 base = root;
-       u32 top = root;
-       u32 floor = 0;
-       int ct = 0;
-       
-       while(ct<nr)
-       {
-               u32 fspace = 0;
-
-               /*
-                *      Find the largest block we will fill going upwards
-                */
-
-               u32 high = power2(mem-top);     
-
-               /*
-                *      Find the largest block we will fill going downwards
-                */
-
-               u32 low = base/2;
-
-               /*
-                *      Don't fill below 1Mb going downwards as there
-                *      is an ISA hole in the way.
-                */             
-                
-               if(base <= 1024*1024)
-                       low = 0;
-                       
-               /*
-                *      See how much space we could cover by filling below
-                *      the ISA hole
-                */
-                
-               if(floor == 0)
-                       fspace = 512*1024;
-               else if(floor ==512*1024)
-                       fspace = 128*1024;
-
-               /* And forget ROM space */
-               
-               /*
-                *      Now install the largest coverage we get
-                */
-                
-               if(fspace > high && fspace > low)
-               {
-                       centaur_mcr_insert(ct, floor, fspace, key);
-                       floor += fspace;
-               }
-               else if(high > low)
-               {
-                       centaur_mcr_insert(ct, top, high, key);
-                       top += high;
-               }
-               else if(low > 0)
-               {
-                       base -= low;
-                       centaur_mcr_insert(ct, base, low, key);
-               }
-               else break;
-               ct++;
-       }
-       /*
-        *      We loaded ct values. We now need to set the mask. The caller
-        *      must do this bit.
-        */
-        
-       return ct;
-}
-
-static void __init centaur_create_optimal_mcr(void)
-{
-       int i;
-       /*
-        *      Allocate up to 6 mcrs to mark as much of ram as possible
-        *      as write combining and weak write ordered.
-        *
-        *      To experiment with: Linux never uses stack operations for 
-        *      mmio spaces so we could globally enable stack operation wc
-        *
-        *      Load the registers with type 31 - full write combining, all
-        *      writes weakly ordered.
-        */
-       int used = centaur_mcr_compute(6, 31);
-
-       /*
-        *      Wipe unused MCRs
-        */
-        
-       for(i=used;i<8;i++)
-               wrmsr(MSR_IDT_MCR0+i, 0, 0);
-}
-
-static void __init winchip2_create_optimal_mcr(void)
-{
-       u32 lo, hi;
-       int i;
-
-       /*
-        *      Allocate up to 6 mcrs to mark as much of ram as possible
-        *      as write combining, weak store ordered.
-        *
-        *      Load the registers with type 25
-        *              8       -       weak write ordering
-        *              16      -       weak read ordering
-        *              1       -       write combining
-        */
-
-       int used = centaur_mcr_compute(6, 25);
-       
-       /*
-        *      Mark the registers we are using.
-        */
-        
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       for(i=0;i<used;i++)
-               lo|=1<<(9+i);
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       
-       /*
-        *      Wipe unused MCRs
-        */
-        
-       for(i=used;i<8;i++)
-               wrmsr(MSR_IDT_MCR0+i, 0, 0);
-}
-
-/*
- *     Handle the MCR key on the Winchip 2.
- */
-
-static void __init winchip2_unprotect_mcr(void)
-{
-       u32 lo, hi;
-       u32 key;
-       
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       lo&=~0x1C0;     /* blank bits 8-6 */
-       key = (lo>>17) & 7;
-       lo |= key<<6;   /* replace with unlock key */
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-
-static void __init winchip2_protect_mcr(void)
-{
-       u32 lo, hi;
-       
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       lo&=~0x1C0;     /* blank bits 8-6 */
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-#endif /* CONFIG_X86_OOSTORE */
 
 #define ACE_PRESENT    (1 << 6)
 #define ACE_ENABLED    (1 << 7)
@@ -305,146 +63,12 @@ static void __init init_c3(struct cpuinf
 
 static void __init init_centaur(struct cpuinfo_x86 *c)
 {
-       enum {
-               ECX8=1<<1,
-               EIERRINT=1<<2,
-               DPM=1<<3,
-               DMCE=1<<4,
-               DSTPCLK=1<<5,
-               ELINEAR=1<<6,
-               DSMC=1<<7,
-               DTLOCK=1<<8,
-               EDCTLB=1<<8,
-               EMMX=1<<9,
-               DPDC=1<<11,
-               EBRPRED=1<<12,
-               DIC=1<<13,
-               DDC=1<<14,
-               DNA=1<<15,
-               ERETSTK=1<<16,
-               E2MMX=1<<19,
-               EAMD3D=1<<20,
-       };
-
-       char *name;
-       u32  fcr_set=0;
-       u32  fcr_clr=0;
-       u32  lo,hi,newlo;
-       u32  aa,bb,cc,dd;
-
        /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
        clear_bit(0*32+31, c->x86_capability);
 
-       switch (c->x86) {
-
-               case 5:
-                       switch(c->x86_model) {
-                       case 4:
-                               name="C6";
-                               fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
-                               fcr_clr=DPDC;
-                               printk(KERN_NOTICE "Disabling bugged TSC.\n");
-                               clear_bit(X86_FEATURE_TSC, c->x86_capability);
-#ifdef CONFIG_X86_OOSTORE
-                               centaur_create_optimal_mcr();
-                               /* Enable
-                                       write combining on non-stack, non-string
-                                       write combining on string, all types
-                                       weak write ordering 
-                                       
-                                  The C6 original lacks weak read order 
-                                  
-                                  Note 0x120 is write only on Winchip 1 */
-                                  
-                               wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);
-#endif                         
-                               break;
-                       case 8:
-                               switch(c->x86_mask) {
-                               default:
-                                       name="2";
-                                       break;
-                               case 7 ... 9:
-                                       name="2A";
-                                       break;
-                               case 10 ... 15:
-                                       name="2B";
-                                       break;
-                               }
-                               
fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D;
-                               fcr_clr=DPDC;
-#ifdef CONFIG_X86_OOSTORE
-                               winchip2_unprotect_mcr();
-                               winchip2_create_optimal_mcr();
-                               rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                               /* Enable
-                                       write combining on non-stack, non-string
-                                       write combining on string, all types
-                                       weak write ordering 
-                               */
-                               lo|=31;                         
-                               wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                               winchip2_protect_mcr();
-#endif
-                               break;
-                       case 9:
-                               name="3";
-                               
fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D;
-                               fcr_clr=DPDC;
-#ifdef CONFIG_X86_OOSTORE
-                               winchip2_unprotect_mcr();
-                               winchip2_create_optimal_mcr();
-                               rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                               /* Enable
-                                       write combining on non-stack, non-string
-                                       write combining on string, all types
-                                       weak write ordering 
-                               */
-                               lo|=31;                         
-                               wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                               winchip2_protect_mcr();
-#endif
-                               break;
-                       case 10:
-                               name="4";
-                               /* no info on the WC4 yet */
-                               break;
-                       default:
-                               name="??";
-                       }
-
-                       rdmsr(MSR_IDT_FCR1, lo, hi);
-                       newlo=(lo|fcr_set) & (~fcr_clr);
-
-                       if (newlo!=lo) {
-                               printk(KERN_INFO "Centaur FCR was 0x%X now 
0x%X\n", lo, newlo );
-                               wrmsr(MSR_IDT_FCR1, newlo, hi );
-                       } else {
-                               printk(KERN_INFO "Centaur FCR is 0x%X\n",lo);
-                       }
-                       /* Emulate MTRRs using Centaur's MCR. */
-                       set_bit(X86_FEATURE_CENTAUR_MCR, c->x86_capability);
-                       /* Report CX8 */
-                       set_bit(X86_FEATURE_CX8, c->x86_capability);
-                       /* Set 3DNow! on Winchip 2 and above. */
-                       if (c->x86_model >=8)
-                               set_bit(X86_FEATURE_3DNOW, c->x86_capability);
-                       /* See if we can find out some more. */
-                       if ( cpuid_eax(0x80000000) >= 0x80000005 ) {
-                               /* Yes, we can. */
-                               cpuid(0x80000005,&aa,&bb,&cc,&dd);
-                               /* Add L1 data and code cache sizes. */
-                               c->x86_cache_size = (cc>>24)+(dd>>24);
-                       }
-                       snprintf( c->x86_model_id, sizeof(c->x86_model_id),
-                               "WinChip %s", name );
-                       break;
-
-               case 6:
-                       init_c3(c);
-                       break;
-       }
+       if (c->x86 == 6)
+               init_c3(c);
 }
 
 static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int 
size)
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/cpu/common.c Thu Sep 06 12:05:15 2007 -0600
@@ -524,7 +524,6 @@ extern int amd_init_cpu(void);
 extern int amd_init_cpu(void);
 extern int centaur_init_cpu(void);
 extern int transmeta_init_cpu(void);
-extern int rise_init_cpu(void);
 
 void __init early_cpu_init(void)
 {
@@ -535,7 +534,6 @@ void __init early_cpu_init(void)
        nsc_init_cpu();
        centaur_init_cpu();
        transmeta_init_cpu();
-       rise_init_cpu();
 #endif
        early_cpu_detect();
 }
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/mtrr/Makefile
--- a/xen/arch/x86/cpu/mtrr/Makefile    Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/cpu/mtrr/Makefile    Thu Sep 06 12:05:15 2007 -0600
@@ -1,5 +1,4 @@ obj-$(x86_32) += amd.o
 obj-$(x86_32) += amd.o
-obj-$(x86_32) += centaur.o
 obj-$(x86_32) += cyrix.o
 obj-y += generic.o
 obj-y += main.o
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/mtrr/centaur.c
--- a/xen/arch/x86/cpu/mtrr/centaur.c   Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-#include <xen/init.h>
-#include <xen/mm.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
-#include "mtrr.h"
-
-static struct {
-       unsigned long high;
-       unsigned long low;
-} centaur_mcr[8];
-
-static u8 centaur_mcr_reserved;
-static u8 centaur_mcr_type;    /* 0 for winchip, 1 for winchip2 */
-
-/*
- *     Report boot time MCR setups 
- */
-
-static int
-centaur_get_free_region(unsigned long base, unsigned long size)
-/*  [SUMMARY] Get a free MTRR.
-    <base> The starting (base) address of the region.
-    <size> The size (in bytes) of the region.
-    [RETURNS] The index of the region on success, else -1 on error.
-*/
-{
-       int i, max;
-       mtrr_type ltype;
-       unsigned long lbase;
-       unsigned int lsize;
-
-       max = num_var_ranges;
-       for (i = 0; i < max; ++i) {
-               if (centaur_mcr_reserved & (1 << i))
-                       continue;
-               mtrr_if->get(i, &lbase, &lsize, &ltype);
-               if (lsize == 0)
-                       return i;
-       }
-       return -ENOSPC;
-}
-
-void
-mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
-{
-       centaur_mcr[mcr].low = lo;
-       centaur_mcr[mcr].high = hi;
-}
-
-static void
-centaur_get_mcr(unsigned int reg, unsigned long *base,
-               unsigned int *size, mtrr_type * type)
-{
-       *base = centaur_mcr[reg].high >> PAGE_SHIFT;
-       *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
-       *type = MTRR_TYPE_WRCOMB;       /*  If it is there, it is 
write-combining  */
-       if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2))
-               *type = MTRR_TYPE_UNCACHABLE;
-       if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25)
-               *type = MTRR_TYPE_WRBACK;
-       if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31)
-               *type = MTRR_TYPE_WRBACK;
-
-}
-
-static void centaur_set_mcr(unsigned int reg, unsigned long base,
-                           unsigned long size, mtrr_type type)
-{
-       unsigned long low, high;
-
-       if (size == 0) {
-               /*  Disable  */
-               high = low = 0;
-       } else {
-               high = base << PAGE_SHIFT;
-               if (centaur_mcr_type == 0)
-                       low = -size << PAGE_SHIFT | 0x1f;       /* only support 
write-combining... */
-               else {
-                       if (type == MTRR_TYPE_UNCACHABLE)
-                               low = -size << PAGE_SHIFT | 0x02;       /* NC */
-                       else
-                               low = -size << PAGE_SHIFT | 0x09;       /* 
WWO,WC */
-               }
-       }
-       centaur_mcr[reg].high = high;
-       centaur_mcr[reg].low = low;
-       wrmsr(MSR_IDT_MCR0 + reg, low, high);
-}
-
-#if 0
-/*
- *     Initialise the later (saner) Winchip MCR variant. In this version
- *     the BIOS can pass us the registers it has used (but not their values)
- *     and the control register is read/write
- */
-
-static void __init
-centaur_mcr1_init(void)
-{
-       unsigned i;
-       u32 lo, hi;
-
-       /* Unfortunately, MCR's are read-only, so there is no way to
-        * find out what the bios might have done.
-        */
-
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       if (((lo >> 17) & 7) == 1) {    /* Type 1 Winchip2 MCR */
-               lo &= ~0x1C0;   /* clear key */
-               lo |= 0x040;    /* set key to 1 */
-               wrmsr(MSR_IDT_MCR_CTRL, lo, hi);        /* unlock MCR */
-       }
-
-       centaur_mcr_type = 1;
-
-       /*
-        *  Clear any unconfigured MCR's.
-        */
-
-       for (i = 0; i < 8; ++i) {
-               if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) {
-                       if (!(lo & (1 << (9 + i))))
-                               wrmsr(MSR_IDT_MCR0 + i, 0, 0);
-                       else
-                               /*
-                                *      If the BIOS set up an MCR we cannot see 
it
-                                *      but we don't wish to obliterate it
-                                */
-                               centaur_mcr_reserved |= (1 << i);
-               }
-       }
-       /*  
-        *  Throw the main write-combining switch... 
-        *  However if OOSTORE is enabled then people have already done far
-        *  cleverer things and we should behave. 
-        */
-
-       lo |= 15;               /* Write combine enables */
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-
-/*
- *     Initialise the original winchip with read only MCR registers
- *     no used bitmask for the BIOS to pass on and write only control
- */
-
-static void __init
-centaur_mcr0_init(void)
-{
-       unsigned i;
-
-       /* Unfortunately, MCR's are read-only, so there is no way to
-        * find out what the bios might have done.
-        */
-
-       /* Clear any unconfigured MCR's.
-        * This way we are sure that the centaur_mcr array contains the actual
-        * values. The disadvantage is that any BIOS tweaks are thus undone.
-        *
-        */
-       for (i = 0; i < 8; ++i) {
-               if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0)
-                       wrmsr(MSR_IDT_MCR0 + i, 0, 0);
-       }
-
-       wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); /* Write only */
-}
-
-/*
- *     Initialise Winchip series MCR registers
- */
-
-static void __init
-centaur_mcr_init(void)
-{
-       struct set_mtrr_context ctxt;
-
-       set_mtrr_prepare_save(&ctxt);
-       set_mtrr_cache_disable(&ctxt);
-
-       if (boot_cpu_data.x86_model == 4)
-               centaur_mcr0_init();
-       else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9)
-               centaur_mcr1_init();
-
-       set_mtrr_done(&ctxt);
-}
-#endif
-
-static int centaur_validate_add_page(unsigned long base, 
-                                    unsigned long size, unsigned int type)
-{
-       /*
-        *  FIXME: Winchip2 supports uncached
-        */
-       if (type != MTRR_TYPE_WRCOMB && 
-           (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
-               printk(KERN_WARNING
-                      "mtrr: only write-combining%s supported\n",
-                      centaur_mcr_type ? " and uncacheable are"
-                      : " is");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static struct mtrr_ops centaur_mtrr_ops = {
-       .vendor            = X86_VENDOR_CENTAUR,
-//     .init              = centaur_mcr_init,
-       .set               = centaur_set_mcr,
-       .get               = centaur_get_mcr,
-       .get_free_region   = centaur_get_free_region,
-       .validate_add_page = centaur_validate_add_page,
-       .have_wrcomb       = positive_have_wrcomb,
-};
-
-int __init centaur_init_mtrr(void)
-{
-       set_mtrr_ops(&centaur_mtrr_ops);
-       return 0;
-}
-
-//arch_initcall(centaur_init_mtrr);
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/mtrr/main.c
--- a/xen/arch/x86/cpu/mtrr/main.c      Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/cpu/mtrr/main.c      Thu Sep 06 12:05:15 2007 -0600
@@ -539,14 +539,12 @@ EXPORT_SYMBOL(mtrr_del);
  */
 extern void amd_init_mtrr(void);
 extern void cyrix_init_mtrr(void);
-extern void centaur_init_mtrr(void);
 
 static void __init init_ifs(void)
 {
 #ifndef CONFIG_X86_64
        amd_init_mtrr();
        cyrix_init_mtrr();
-       centaur_init_mtrr();
 #endif
 }
 
@@ -609,13 +607,6 @@ void __init mtrr_bp_init(void)
                                size_and_mask = 0;
                        }
                        break;
-               case X86_VENDOR_CENTAUR:
-                       if (cpu_has_centaur_mcr) {
-                               mtrr_if = mtrr_ops[X86_VENDOR_CENTAUR];
-                               size_or_mask = 0xfff00000;      /* 32 bits */
-                               size_and_mask = 0;
-                       }
-                       break;
                case X86_VENDOR_CYRIX:
                        if (cpu_has_cyrix_arr) {
                                mtrr_if = mtrr_ops[X86_VENDOR_CYRIX];
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/cpu/rise.c
--- a/xen/arch/x86/cpu/rise.c   Thu Sep 06 09:05:26 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#include <xen/config.h>
-#include <xen/lib.h>
-#include <xen/init.h>
-#include <xen/bitops.h>
-#include <asm/processor.h>
-
-#include "cpu.h"
-
-static void __init init_rise(struct cpuinfo_x86 *c)
-{
-       printk("CPU: Rise iDragon");
-       if (c->x86_model > 2)
-               printk(" II");
-       printk("\n");
-
-       /* Unhide possibly hidden capability flags
-          The mp6 iDragon family don't have MSRs.
-          We switch on extra features with this cpuid weirdness: */
-       __asm__ (
-               "movl $0x6363452a, %%eax\n\t"
-               "movl $0x3231206c, %%ecx\n\t"
-               "movl $0x2a32313a, %%edx\n\t"
-               "cpuid\n\t"
-               "movl $0x63634523, %%eax\n\t"
-               "movl $0x32315f6c, %%ecx\n\t"
-               "movl $0x2333313a, %%edx\n\t"
-               "cpuid\n\t" : : : "eax", "ebx", "ecx", "edx"
-       );
-       set_bit(X86_FEATURE_CX8, c->x86_capability);
-}
-
-static struct cpu_dev rise_cpu_dev __initdata = {
-       .c_vendor       = "Rise",
-       .c_ident        = { "RiseRiseRise" },
-       .c_models = {
-               { .vendor = X86_VENDOR_RISE, .family = 5, .model_names = 
-                 { 
-                         [0] = "iDragon", 
-                         [2] = "iDragon", 
-                         [8] = "iDragon II", 
-                         [9] = "iDragon II"
-                 }
-               },
-       },
-       .c_init         = init_rise,
-};
-
-int __init rise_init_cpu(void)
-{
-       cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev;
-       return 0;
-}
-
-//early_arch_initcall(rise_init_cpu);
diff -r 12be90e2f831 -r 4ffca478e2f7 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Sep 06 09:05:26 2007 -0600
+++ b/xen/arch/x86/domain.c     Thu Sep 06 12:05:15 2007 -0600
@@ -437,6 +437,9 @@ int arch_domain_create(struct domain *d)
     int vcpuid, pdpt_order, paging_initialised = 0;
     int rc = -ENOMEM;
 
+    d->arch.relmem = RELMEM_not_started;
+    INIT_LIST_HEAD(&d->arch.relmem_list);
+
     pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
     d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
     if ( d->arch.mm_perdomain_pt == NULL )
@@ -1599,12 +1602,13 @@ int hypercall_xlat_continuation(unsigned
 }
 #endif
 
-static void relinquish_memory(struct domain *d, struct list_head *list,
-                              unsigned long type)
+static int relinquish_memory(
+    struct domain *d, struct list_head *list, unsigned long type)
 {
     struct list_head *ent;
     struct page_info  *page;
     unsigned long     x, y;
+    int               ret = 0;
 
     /* Use a recursive lock, as we may enter 'free_domheap_page'. */
     spin_lock_recursive(&d->page_alloc_lock);
@@ -1619,6 +1623,7 @@ static void relinquish_memory(struct dom
         {
             /* Couldn't get a reference -- someone is freeing this page. */
             ent = ent->next;
+            list_move_tail(&page->list, &d->arch.relmem_list);
             continue;
         }
 
@@ -1653,10 +1658,21 @@ static void relinquish_memory(struct dom
 
         /* Follow the list chain and /then/ potentially free the page. */
         ent = ent->next;
+        list_move_tail(&page->list, &d->arch.relmem_list);
         put_page(page);
-    }
-
+
+        if ( hypercall_preempt_check() )
+        {
+            ret = -EAGAIN;
+            goto out;
+        }
+    }
+
+    list_splice_init(&d->arch.relmem_list, list);
+
+ out:
     spin_unlock_recursive(&d->page_alloc_lock);
+    return ret;
 }
 
 static void vcpu_destroy_pagetables(struct vcpu *v)
@@ -1717,43 +1733,91 @@ static void vcpu_destroy_pagetables(stru
     v->arch.cr3 = 0;
 }
 
-void domain_relinquish_resources(struct domain *d)
-{
+int domain_relinquish_resources(struct domain *d)
+{
+    int ret;
     struct vcpu *v;
 
     BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
 
-    /* Drop the in-use references to page-table bases. */
-    for_each_vcpu ( d, v )
-        vcpu_destroy_pagetables(v);
-
-    /* Tear down paging-assistance stuff. */
-    paging_teardown(d);
-
-    /*
-     * Relinquish GDT mappings. No need for explicit unmapping of the LDT as
-     * it automatically gets squashed when the guest's mappings go away.
-     */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>