merge with xen-unstable.hg

This commit is contained in:
Alex Williamson committed 2007-08-12 14:50:02 -06:00
commit 087b48842b
57 files changed
+3016 -720

No files matched your search

+4
View File
@@ -123,3 +123,7 @@ cscope:
tags:
$(all_sources) | xargs ctags
.PHONY: TAGS
TAGS:
$(all_sources) | xargs etags
+3
View File
@@ -3,6 +3,9 @@
# It's is used for x86_32, x86_32y and x86_64
#
XEN_ROOT = ../../../..
include $(XEN_ROOT)/Config.mk
# include arch.mk has to be before mini-os.mk!
include arch.mk
+3 -3
View File
@@ -405,9 +405,9 @@ void *map_frames(unsigned long *f, unsigned long n)
void arch_init_p2m(unsigned long max_pfn)
{
#define L1_P2M_SHIFT 10
#define L2_P2M_SHIFT 20
#define L3_P2M_SHIFT 30
#define L1_P2M_SHIFT 9
#define L2_P2M_SHIFT 18
#define L3_P2M_SHIFT 27
#define L1_P2M_ENTRIES (1 << L1_P2M_SHIFT)
#define L2_P2M_ENTRIES (1 << (L2_P2M_SHIFT - L1_P2M_SHIFT))
#define L3_P2M_ENTRIES (1 << (L3_P2M_SHIFT - L2_P2M_SHIFT))
+3
View File
@@ -6,3 +6,6 @@ and for stricter DHCP spec compliance.
Rom-o-matic.net will provide this image at the following URL:
http://rom-o-matic.net/5.4.3/build.php?version=5.4.3&F=ignore&nic=rtl8139%3Artl8139+--+%5B0x10ec%2C0x8139%5D&ofmt=Binary+ROM+Image%28.zrom%29&arch=i386&ASK_BOOT=-1&BOOT_FIRST=BOOT_NIC&BOOT_SECOND=BOOT_NOTHING&BOOT_THIRD=BOOT_NOTHING&BOOT_INDEX=0&STATIC_CLIENT_IP=&STATIC_SUBNET_MASK=&STATIC_SERVER_IP=&STATIC_GATEWAY_IP=&STATIC_BOOTFILE=&EXIT_ON_FILE_LOAD_ERROR=on&DHCP_CLIENT_ID=&DHCP_CLIENT_ID_LEN=&DHCP_CLIENT_ID_TYPE=&DHCP_USER_CLASS=&DHCP_USER_CLASS_LEN=&ALLOW_ONLY_ENCAPSULATED=on&DEFAULT_BOOTFILE=&CONGESTED=on&BACKOFF_LIMIT=7&TIMEOUT=180&TRY_FLOPPY_FIRST=0&EXIT_IF_NO_OFFER=on&TAGGED_IMAGE=on&ELF_IMAGE=on&PXE_IMAGE=on&DOWNLOAD_PROTO_TFTP=on&COMCONSOLE=0x3F8&CONSPEED=9600&COMPARM=0x03&PXE_EXPORT=on&CONFIG_PCI=on&CONFIG_ISA=on&BUILD_ID=&PCBIOS=on&PXE_DHCP_STRICT=on&A=Get+ROM
and the mkhex script in tools/firmware/hvmloader will make the header
file from the downloaded image.
Binary file not shown.
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -51,12 +51,12 @@ hvmloader: roms.h acpi/acpi.a $(SRCS)
acpi/acpi.a:
$(MAKE) -C acpi
roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin ../etherboot/eb-rtl8139.zrom
roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin ../etherboot/eb-rtl8139.zrom.h
sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
sh ./mkhex etherboot ../etherboot/eb-rtl8139.zrom >> roms.h
cat ../etherboot/eb-rtl8139.zrom.h >> roms.h
.PHONY: clean
clean:
+2
View File
@@ -417,6 +417,7 @@ static int start_info_x86_32(struct xc_dom_image *dom)
xc_dom_printf("%s: called\n", __FUNCTION__);
memset(start_info, 0, sizeof(*start_info));
sprintf(start_info->magic, dom->guest_type);
start_info->nr_pages = dom->total_pages;
start_info->shared_info = shinfo << PAGE_SHIFT_X86;
@@ -455,6 +456,7 @@ static int start_info_x86_64(struct xc_dom_image *dom)
xc_dom_printf("%s: called\n", __FUNCTION__);
memset(start_info, 0, sizeof(*start_info));
sprintf(start_info->magic, dom->guest_type);
start_info->nr_pages = dom->total_pages;
start_info->shared_info = shinfo << PAGE_SHIFT_X86;
+21 -3
View File
@@ -18,12 +18,13 @@ class LiloImage(object):
" initrd: %s\n" %(self.title, self.root, self.kernel,
self.args, self.initrd))
def reset(self, lines, path):
self._root = self._initrd = self._kernel = self._args = None
self._initrd = self._kernel = self._readonly = None
self._args = ""
self.title = ""
self.lines = []
self.path = path
self.root = ""
map(self.set_from_line, lines)
self.root = "" # dummy
def set_from_line(self, line, replace = None):
(com, arg) = GrubConf.grub_exact_split(line, 2)
@@ -55,6 +56,23 @@ class LiloImage(object):
return self._initrd
initrd = property(get_initrd, set_initrd)
def set_args(self, val):
self._args = val
def get_args(self):
args = self._args
if self.root:
args += " root=" + self.root
if self.readonly:
args += " ro"
return args
args = property(get_args, set_args)
def set_readonly(self, val):
self._readonly = 1
def get_readonly(self):
return self._readonly
readonly = property(get_readonly, set_readonly)
# set up command handlers
commands = { "label": "self.title",
"root": "self.root",
@@ -62,7 +80,7 @@ class LiloImage(object):
"image": "self.kernel",
"initrd": "self.initrd",
"append": "self.args",
"read-only": None,
"read-only": "self.readonly",
"chainloader": None,
"module": None}
+69 -27
View File
@@ -47,6 +47,9 @@ ACM_POLICY_UNDEFINED = 15
ACM_SCHEMA_FILE = "/etc/xen/acm-security/policies/security_policy.xsd"
ACM_LABEL_UNLABELED = "__UNLABELED__"
ACM_LABEL_UNLABELED_DISPLAY = "unlabeled"
class ACMPolicy(XSPolicy):
"""
ACMPolicy class. Implements methods for getting information from
@@ -139,6 +142,21 @@ class ACMPolicy(XSPolicy):
return xsconstants.XSERR_SUCCESS
def is_default_policy(self):
"""
Determine whether this is the default policy
"""
default = ['SystemManagement']
if self.policy_get_virtualmachinelabel_names() == default and \
self.policy_get_bootstrap_vmlabel() == default[0] and \
self.policy_get_stetypes_types() == default and \
self.policy_get_stes_of_vmlabel(default[0]) == default and \
self.policy_get_resourcelabel_names() == [] and \
self.policy_get_chwall_types() == default and \
self.get_name() == "DEFAULT":
return True
return False
def update(self, xml_new):
"""
Update the policy with the new XML. The hypervisor decides
@@ -153,27 +171,18 @@ class ACMPolicy(XSPolicy):
return -xsconstants.XSERR_XML_PROCESSING, errors
vmlabel_map = acmpol_new.policy_get_vmlabel_translation_map()
# An update requires version information in the current
# and new policy. The version number of the current policy
# must be the same as what is in the FromPolicy/Version node
# in the new one and the current policy's name must be the
# same as in FromPolicy/PolicyName
now_vers = acmpol_old.policy_dom_get_hdr_item("Version")
now_name = acmpol_old.policy_dom_get_hdr_item("PolicyName")
req_oldvers = acmpol_new.policy_dom_get_frompol_item("Version")
req_oldname = acmpol_new.policy_dom_get_frompol_item("PolicyName")
if now_vers == "" or \
now_vers != req_oldvers or \
now_name != req_oldname:
log.info("Policy rejected: %s != %s or %s != %s" % \
(now_vers,req_oldvers,now_name,req_oldname))
return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE, errors
if not self.isVersionUpdate(acmpol_new):
log.info("Policy rejected since new version is not an update.")
return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE, errors
# The default policy when it is set skips this step.
if not acmpol_new.is_default_policy() and \
not acmpol_old.is_default_policy():
irc = self.__do_update_version_check(acmpol_new)
if irc != xsconstants.XSERR_SUCCESS:
return irc, errors
if self.isloaded():
newvmnames = \
@@ -255,6 +264,29 @@ class ACMPolicy(XSPolicy):
self.compile()
return rc, errors
def __do_update_version_check(self, acmpol_new):
acmpol_old = self
now_vers = acmpol_old.policy_dom_get_hdr_item("Version")
now_name = acmpol_old.policy_dom_get_hdr_item("PolicyName")
req_oldvers = acmpol_new.policy_dom_get_frompol_item("Version")
req_oldname = acmpol_new.policy_dom_get_frompol_item("PolicyName")
if now_vers == "" or \
now_vers != req_oldvers or \
now_name != req_oldname:
log.info("Policy rejected: %s != %s or %s != %s" % \
(now_vers,req_oldvers,now_name,req_oldname))
return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE
if not self.isVersionUpdate(acmpol_new):
log.info("Policy rejected since new version is not an update.")
return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE
return xsconstants.XSERR_SUCCESS
def compareVersions(self, v1, v2):
"""
Compare two policy versions given their tuples of major and
@@ -845,8 +877,7 @@ class ACMPolicy(XSPolicy):
if self.isloaded():
return -xsconstants.XSERR_POLICY_LOADED
files = [ self.get_filename(".map",""),
self.get_filename(".bin",""),
self.path_from_policy_name(self.get_name())]
self.get_filename(".bin","") ]
for f in files:
try:
os.unlink(f)
@@ -925,11 +956,13 @@ class ACMPolicy(XSPolicy):
return -xsconstants.XSERR_POLICY_INCONSISTENT, "", ""
vms_with_chws = []
chws_by_vm = {}
chws_by_vm = { ACM_LABEL_UNLABELED : [] }
for v in vms:
if v.has_key("chws"):
vms_with_chws.append(v["name"])
chws_by_vm[v["name"]] = v["chws"]
if bootstrap in vms_with_chws:
vms_with_chws.remove(bootstrap)
vms_with_chws.sort()
@@ -937,12 +970,16 @@ class ACMPolicy(XSPolicy):
else:
vms_with_chws.sort()
if ACM_LABEL_UNLABELED in vms_with_chws:
vms_with_chws.remove(ACM_LABEL_UNLABELED) ; # @1
vms_with_stes = []
stes_by_vm = {}
stes_by_vm = { ACM_LABEL_UNLABELED : [] }
for v in vms:
if v.has_key("stes"):
vms_with_stes.append(v["name"])
stes_by_vm[v["name"]] = v["stes"]
if bootstrap in vms_with_stes:
vms_with_stes.remove(bootstrap)
vms_with_stes.sort()
@@ -950,6 +987,9 @@ class ACMPolicy(XSPolicy):
else:
vms_with_stes.sort()
if ACM_LABEL_UNLABELED in vms_with_stes:
vms_with_stes.remove(ACM_LABEL_UNLABELED) ; # @2
resnames = self.policy_get_resourcelabel_names()
resnames.sort()
stes_by_res = {}
@@ -958,6 +998,9 @@ class ACMPolicy(XSPolicy):
if r.has_key("stes"):
stes_by_res[r["name"]] = r["stes"]
if ACM_LABEL_UNLABELED in resnames:
resnames.remove(ACM_LABEL_UNLABELED)
max_chw_ssids = 1 + len(vms_with_chws)
max_chw_types = 1 + len(vms_with_chws)
max_ste_ssids = 1 + len(vms_with_stes) + len(resnames)
@@ -1083,6 +1126,8 @@ class ACMPolicy(XSPolicy):
pr_bin += "\x00"
# Build chinese wall part
vms_with_chws.insert(0, ACM_LABEL_UNLABELED)
cfses_names = self.policy_get_chwall_cfses_names_sorted()
cfses = self.policy_get_chwall_cfses()
@@ -1105,9 +1150,7 @@ class ACMPolicy(XSPolicy):
chw_running_types_offset,
chw_conf_agg_offset)
chw_bin_body = ""
# simulate __NULL_LABEL__
for c in chws:
chw_bin_body += struct.pack("!h",0)
# VMs that are listed and their chinese walls
for v in vms_with_chws:
for c in chws:
@@ -1143,6 +1186,8 @@ class ACMPolicy(XSPolicy):
chw_bin += "\x00"
# Build STE part
vms_with_stes.insert(0, ACM_LABEL_UNLABELED) # Took out in @2
steformat="!iiiii"
ste_bin = struct.pack(steformat,
ACM_STE_VERSION,
@@ -1152,10 +1197,7 @@ class ACMPolicy(XSPolicy):
struct.calcsize(steformat))
ste_bin_body = ""
if stes:
# Simulate __NULL_LABEL__
for s in stes:
ste_bin_body += struct.pack("!h",0)
# VMs that are listed and their chinese walls
# VMs that are listed and their STE types
for v in vms_with_stes:
unknown_ste |= (set(stes_by_vm[v]) - set(stes))
for s in stes:
+34 -6
View File
@@ -146,7 +146,7 @@ def calc_dom_ssidref_from_info(info):
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' not supported." % typ)
raise VmError("Policy type '%s' must be changed." % typ)
refresh_security_policy()
if active_policy != policyname:
raise VmError("Active policy '%s' different than "
@@ -155,7 +155,7 @@ def calc_dom_ssidref_from_info(info):
ssidref = label2ssidref(vmlabel, policyname, "dom")
return ssidref
else:
return 0
return 0x0
raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
"not supported." % type(info))
@@ -232,6 +232,10 @@ def ssidref2label(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()
@@ -498,7 +502,7 @@ def hv_chg_policy(bin_pol, del_array, chg_array):
rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
except Exception, e:
pass
if (len(errors) > 0):
if len(errors) > 0:
rc = -xsconstants.XSERR_HV_OP_FAILED
return rc, errors
@@ -781,6 +785,24 @@ def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
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
@@ -805,10 +827,16 @@ def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
return -xsconstants.XSERR_BAD_LABEL_FORMAT
otyp, opolicyref, olabel = tmp
# Only ACM is supported
if otyp != xsconstants.ACM_POLICY_ID:
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):
""" Investigate all running domains whether they use this device """
from xen.xend import XendDomain
@@ -867,7 +895,7 @@ def get_domain_resources(dominfo):
resources[typ].append("%s:%s:%s" %
(xsconstants.ACM_POLICY_ID,
active_policy,
"unlabeled"))
ACM_LABEL_UNLABELED))
return resources
@@ -1224,7 +1252,7 @@ def change_acm_policy(bin_pol, del_array, chg_array,
sec_lab, new_seclab = labels
if sec_lab != new_seclab:
log.info("Updating domain %s to new label '%s'." % \
(new_seclab, sec_lab))
(sec_lab, new_seclab))
# This better be working!
dominfo.set_security_label(new_seclab,
sec_lab,
+2 -14
View File
@@ -559,18 +559,8 @@ class XendDomainInfo:
self.getDeviceController(devclass).waitForDevices()
def destroyDevice(self, deviceClass, devid, force = False):
try:
dev = int(devid)
except ValueError:
# devid is not a number but a string containing either device
# name (e.g. xvda) or device_type/device_id (e.g. vbd/51728)
dev = type(devid) is str and devid.split('/')[-1] or None
if dev == None:
log.debug("Could not find the device %s", devid)
return None
log.debug("dev = %s", dev)
return self.getDeviceController(deviceClass).destroyDevice(dev, force)
log.debug("dev = %s", devid)
return self.getDeviceController(deviceClass).destroyDevice(devid, force)
def getDeviceSxprs(self, deviceClass):
if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
@@ -1463,8 +1453,6 @@ class XendDomainInfo:
ssidref = 0
if security.on():
ssidref = security.calc_dom_ssidref_from_info(self.info)
if ssidref == 0:
raise VmError('VM is not properly labeled.')
if security.has_authorization(ssidref) == False:
raise VmError("VM is not authorized to run.")
+14 -9
View File
@@ -203,27 +203,32 @@ class DevController:
The implementation here simply deletes the appropriate paths from the
store. This may be overridden by subclasses who need to perform other
tasks on destruction. Further, the implementation here can only
accept integer device IDs, or values that can be converted to
integers. Subclasses may accept other values and convert them to
integers before passing them here.
tasks on destruction. The implementation here accepts integer device
IDs or paths containg integer deviceIDs, e.g. vfb/0. Subclasses may
accept other values and convert them to integers before passing them
here.
"""
devid = int(devid)
try:
dev = int(devid)
except ValueError:
# Does devid contain devicetype/deviceid?
# Propogate exception if unable to find an integer devid
dev = int(type(devid) is str and devid.split('/')[-1] or None)
# Modify online status /before/ updating state (latter is watched by
# drivers, so this ordering avoids a race).
self.writeBackend(devid, 'online', "0")
self.writeBackend(devid, 'state', str(xenbusState['Closing']))
self.writeBackend(dev, 'online', "0")
self.writeBackend(dev, 'state', str(xenbusState['Closing']))
if force:
frontpath = self.frontendPath(devid)
frontpath = self.frontendPath(dev)
backpath = xstransact.Read(frontpath, "backend")
if backpath:
xstransact.Remove(backpath)
xstransact.Remove(frontpath)
self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid))
self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
def configurations(self):
return map(self.configuration, self.deviceIDs())
+25 -17
View File
@@ -73,17 +73,7 @@ class BlkifController(DevController):
back['uuid'] = uuid
if security.on():
(label, ssidref, policy) = \
security.get_res_security_details(uname)
domain_label = self.vm.get_security_label()
if domain_label:
rc = security.res_security_check_xapi(label, ssidref, policy,
domain_label)
if rc == 0:
raise VmError("VM's access to block device '%s' denied." %
uname)
else:
raise VmError("VM must have a security label.")
self.do_access_control(config, uname)
devid = blkif.blkdev_name_to_number(dev)
if devid is None:
@@ -95,6 +85,21 @@ class BlkifController(DevController):
return (devid, back, front)
def do_access_control(self, config, uname):
(label, ssidref, policy) = \
security.get_res_security_details(uname)
domain_label = self.vm.get_security_label()
if domain_label:
rc = security.res_security_check_xapi(label, ssidref, policy,
domain_label)
if rc == 0:
raise VmError("VM's access to block device '%s' denied" %
uname)
else:
from xen.util.acmpolicy import ACM_LABEL_UNLABELED
if label != ACM_LABEL_UNLABELED:
raise VmError("VM must have a security label to access "
"block device '%s'" % uname)
def reconfigureDevice(self, _, config):
"""@see DevController.reconfigureDevice"""
@@ -149,13 +154,16 @@ class BlkifController(DevController):
def destroyDevice(self, devid, force):
"""@see DevController.destroyDevice"""
# If we are given a device name, then look up the device ID from it,
# and destroy that ID instead. If what we are given is an integer,
# then assume it's a device ID and pass it straight through to our
# superclass's method.
# vbd device IDs can be either string or integer. Further, the
# following string values are possible:
# - devicetype/deviceid (vbd/51728)
# - devicetype/devicename (/dev/xvdb)
# - devicename (xvdb)
# Let our superclass handle integer or devicetype/deviceid forms.
# If we are given a device name form, then look up the device ID
# from it, and destroy that ID instead.
try:
DevController.destroyDevice(self, int(devid), force)
DevController.destroyDevice(self, devid, force)
except ValueError:
devid_end = type(devid) is str and devid.split('/')[-1] or None
+26 -1
View File
@@ -23,7 +23,7 @@ import sys
from xen.util import xsconstants
from xml.dom import minidom
from xen.xm.opts import OptionError
from xen.xm import getpolicy
from xen.xm import getpolicy, setpolicy
from xen.xm import main as xm_main
from xen.xm.main import server
@@ -38,6 +38,9 @@ def help():
--boot Have the system boot with the policy. Changes the default
title in grub.conf.
--noboot Remove the policy from the default entry in grub.conf.
--remove Attempt to remove the current policy by installing the
default policy; this works only if no domains are
running.
"""
def activate_policy(flags):
@@ -56,6 +59,25 @@ def activate_policy(flags):
def remove_bootpolicy():
server.xenapi.XSPolicy.rm_xsbootpolicy()
def install_default_policy():
if xm_main.serverType != xm_main.SERVER_XEN_API:
raise OptionError('xm needs to be configured to use the xen-api.')
xs_type = int(server.xenapi.XSPolicy.get_xstype())
if xs_type & xsconstants.XS_POLICY_ACM == 0:
raise OptionError('ACM policy type not supported on system.')
policystate = server.xenapi.XSPolicy.get_xspolicy()
if int(policystate['type']) == 0:
print 'No policy is installed.'
return
if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
print "Unknown policy type '%s'." % policystate['type']
flags = int(policystate['flags'])
if flags & xsconstants.XS_INST_LOAD == 0:
print "Default policy is already loaded."
return
setpolicy.setpolicy(xsconstants.ACM_POLICY_ID, 'default', flags, True,
False)
def main(argv):
if xm_main.serverType != xm_main.SERVER_XEN_API:
raise OptionError('xm needs to be configured to use the xen-api.')
@@ -69,6 +91,9 @@ def main(argv):
flags |= xsconstants.XS_INST_LOAD
elif '--noboot' == argv[c]:
remove_bootpolicy()
elif '--remove' == argv[c]:
install_default_policy()
return
else:
raise OptionError("Unknown command line option '%s'" % argv[c])
c += 1
+3 -2
View File
@@ -25,7 +25,6 @@ import atexit
import cmd
import os
import pprint
import readline
import shlex
import sys
import re
@@ -51,6 +50,7 @@ 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
from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
import XenAPI
@@ -615,6 +615,7 @@ class Shell(cmd.Cmd):
def preloop(self):
cmd.Cmd.preloop(self)
import readline
readline.set_completer_delims(' ')
def default(self, line):
@@ -947,7 +948,7 @@ def xm_label_list(doms):
d = parse_doms_info(dom)
if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
if not d['seclabel']:
d['seclabel'] = 'ERROR'
d['seclabel'] = ACM_LABEL_UNLABELED_DISPLAY
elif security.active_policy in ['DEFAULT']:
d['seclabel'] = 'DEFAULT'
else:
+2 -1
View File
@@ -75,7 +75,8 @@ def main(argv):
doc = sxp2xml_inst.convert_sxp_to_xml(config)
xenapi_create_inst = xenapi_create()
vm_refs = xenapi_create_inst.create(document = doc)
vm_refs = xenapi_create_inst.create(document = doc,
skipdtd=opts.vals.skipdtd)
else:
make_unstarted_domain(opts, config)
-1
View File
@@ -58,7 +58,6 @@ def main (argv):
try:
filename = security.res_label_filename
access_control = dictio.dict_read("resources", filename)
print access_control
except:
raise OptionError("Resource file not found")
+38 -2
View File
@@ -24,6 +24,7 @@ import struct
import sys
import string
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.xm import main as xm_main
@@ -40,9 +41,38 @@ def help():
The following options are defined
--load Load the policy immediately
--boot Have the system load the policy during boot
--update Automatically adapt the policy so that it will be
treated as an update to the current policy
"""
def setpolicy(policytype, policy_name, flags, overwrite):
def create_update_xml(xml):
"""
Adapt the new policy's xml header to be a simple type of an
update to the currently enforce policy on the remote system.
Increases the minor number by '1'.
"""
policystate = server.xenapi.XSPolicy.get_xspolicy()
if int(policystate['type']) == 0:
return xml
curpol = ACMPolicy(xml = policystate['repr'])
curpol_version = curpol.get_version()
tmp = curpol_version.split('.')
if len(tmp) == 2:
maj = int(tmp[0])
min = int(tmp[1])
else:
maj = int(tmp)
min = 0
min += 1
newpol_version = ""+str(maj)+"."+str(min)
newpol = ACMPolicy(xml = xml)
newpol.set_frompolicy_name(curpol.get_name())
newpol.set_frompolicy_version(curpol.get_version())
newpol.set_policy_version(newpol_version)
return newpol.toxml()
def setpolicy(policytype, policy_name, flags, overwrite, is_update=False):
if xm_main.serverType != xm_main.SERVER_XEN_API:
raise OptionError('xm needs to be configured to use the xen-api.')
if policytype != xsconstants.ACM_POLICY_ID:
@@ -61,6 +91,9 @@ def setpolicy(policytype, policy_name, flags, overwrite):
except:
raise OptionError("Not a valid policy file")
if is_update:
xml = create_update_xml(xml)
try:
policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type,
xml,
@@ -96,18 +129,21 @@ def main(argv):
policytype = argv[1]
policy_name = argv[2]
is_update = False
flags = 0
if '--load' in argv:
flags |= xsconstants.XS_INST_LOAD
if '--boot' in argv:
flags |= xsconstants.XS_INST_BOOT
if '--update' in argv:
is_update = True
overwrite = True
if '--nooverwrite' in argv:
overwrite = False
setpolicy(policytype, policy_name, flags, overwrite)
setpolicy(policytype, policy_name, flags, overwrite, is_update)
if __name__ == '__main__':
try:
+4 -7
View File
@@ -13,13 +13,6 @@ CFLAGS += $(shell xml2-config --cflags )
CFLAGS += $(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else echo "-DVALIDATE_SCHEMA"; fi )
LDFLAGS += $(shell xml2-config --libs ) # if this does not work, try -L/usr/lib -lxml2 -lz -lpthread -lm
ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_NULL_POLICY)
POLICY=null
endif
ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)
POLICY=chwall_ste
endif
SRCS_TOOL = secpol_tool.c
OBJS_TOOL := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_TOOL)))
SRCS_XML2BIN = secpol_xml2bin.c secpol_xml2bin.h
@@ -41,6 +34,7 @@ ACM_SECGEN_CGIDIR = $(ACM_SECGEN_HTMLDIR)/cgi-bin
ACM_SCHEMA = security_policy.xsd
ACM_EXAMPLES = client_v1 test
ACM_DEF_POLICIES = default default-ul
ACM_POLICY_SUFFIX = security_policy.xml
ifeq ($(ACM_SECURITY),y)
@@ -62,6 +56,9 @@ install: all $(ACM_CONFIG_FILE)
for i in $(ACM_EXAMPLES); do \
$(INSTALL_DATA) policies/example/$$i-$(ACM_POLICY_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/example/; \
done
for i in $(ACM_DEF_POLICIES); do \
$(INSTALL_DATA) policies/$$i-$(ACM_POLICY_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR); \
done
$(INSTALL_DIR) $(DESTDIR)$(ACM_SCRIPT_DIR)
$(INSTALL_PROG) $(ACM_SCRIPTS) $(DESTDIR)$(ACM_SCRIPT_DIR)
$(INSTALL_DIR) $(DESTDIR)$(ACM_SECGEN_HTMLDIR)
@@ -0,0 +1,30 @@
<?xml version="1.0" ?>
<SecurityPolicyDefinition xmlns="http://www.ibm.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com ../../security_policy.xsd">
<PolicyHeader>
<PolicyName>DEFAULT</PolicyName>
<Version>1.0</Version>
</PolicyHeader>
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
<ChineseWall>
<ChineseWallTypes>
<Type>SystemManagement</Type>
</ChineseWallTypes>
</ChineseWall>
<SecurityLabelTemplate>
<SubjectLabels bootstrap="SystemManagement">
<VirtualMachineLabel>
<Name>SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<Type>SystemManagement</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type/>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
</SecurityLabelTemplate>
</SecurityPolicyDefinition>
@@ -0,0 +1,41 @@
<?xml version="1.0" ?>
<SecurityPolicyDefinition xmlns="http://www.ibm.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com ../../security_policy.xsd">
<PolicyHeader>
<PolicyName>DEFAULT-UL</PolicyName>
<Version>1.0</Version>
</PolicyHeader>
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>SystemManagement</Type>
<Type>__UNLABELED__</Type>
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
<ChineseWall>
<ChineseWallTypes>
<Type>SystemManagement</Type>
</ChineseWallTypes>
</ChineseWall>
<SecurityLabelTemplate>
<SubjectLabels bootstrap="SystemManagement">
<VirtualMachineLabel>
<Name>SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<Type>SystemManagement</Type>
<Type>__UNLABELED__</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type/>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>__UNLABELED__</Name>
<SimpleTypeEnforcementTypes>
<Type>__UNLABELED__</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type/>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
</SecurityLabelTemplate>
</SecurityPolicyDefinition>
+6 -1
View File
@@ -36,6 +36,8 @@ conflict_bmp = None
realm_icon = None
workload_icon = None
ACM_LABEL_UNLABELED = '__UNLABELED__'
class orgTreeCtrl(wx.TreeCtrl):
event = None
@@ -870,7 +872,8 @@ class ezFrame(wx.Frame):
self.realm_menu.Enable(self.ID_ORGDEL, True)
self.realm_menu.Enable(self.ID_ORGEDT, True)
self.realm_menu.Enable(self.ID_ORGADD, True)
if len(self.orgs.GetSelections()) > 1:
if len(self.orgs.GetSelections()) > 1 or \
ACM_LABEL_UNLABELED == self.orgs.GetItemText(item):
self.realm_menu.Enable(self.ID_ORGEDT, False)
self.realm_menu.Enable(self.ID_ORGADD, False)
self.PopupMenu(self.realm_menu)
@@ -1622,6 +1625,8 @@ def main():
app = ezApp(0)
if len(sys.argv) in [2]:
app.Load(sys.argv[1])
else:
dict2org({'orgs' : [[ACM_LABEL_UNLABELED,[]]], 'cons': []})
app.MainLoop()
print "Goodbye"
+1 -1
View File
@@ -677,7 +677,7 @@ static void xenstat_prune_domain(xenstat_node *node, unsigned int entry)
/* shift entries following specified entry up by one */
if (entry < node->num_domains) {
xenstat_domain *domain = &node->domains[entry];
memmove(domain,domain+1,node->num_domains-entry);
memmove(domain,domain+1,(node->num_domains - entry) * sizeof(xenstat_domain) );
}
/* zero out original last entry from node -- not
+3 -4
View File
@@ -10,19 +10,18 @@
#include <signal.h>
#include "utils.h"
void xprintf(const char *fmt, ...)
static void default_xprintf(const char *fmt, ...)
{
va_list args;
if (!stderr)
return; /* could trace()? */
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fflush(stderr);
}
void (*xprintf)(const char *fmt, ...) = default_xprintf;
void barf(const char *fmt, ...)
{
char *str;
+1 -1
View File
@@ -24,7 +24,7 @@ static inline bool strends(const char *a, const char *b)
void barf(const char *fmt, ...) __attribute__((noreturn));
void barf_perror(const char *fmt, ...) __attribute__((noreturn));
void xprintf(const char *fmt, ...);
void (*xprintf)(const char *fmt, ...);
#define eprintf(_fmt, _args...) xprintf("[ERR] %s" _fmt, __FUNCTION__, ##_args)
+8 -8
View File
@@ -1880,14 +1880,14 @@ int main(int argc, char *argv[])
/* close stdin/stdout now we're ready to accept connections */
if (dofork) {
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Get ourselves a nice xenstored crash if these are used. */
stdin = NULL;
stdout = NULL;
stderr = NULL;
int devnull = open("/dev/null", O_RDWR);
if (devnull == -1)
barf_perror("Could not open /dev/null\n");
close(STDIN_FILENO); dup2(STDIN_FILENO, devnull);
close(STDOUT_FILENO); dup2(STDOUT_FILENO, devnull);
close(STDERR_FILENO); dup2(STDERR_FILENO, devnull);
close(devnull);
xprintf = trace;
}
signal(SIGHUP, trigger_reopen_log);
@@ -11,6 +11,12 @@ struct ap_suspend_info {
atomic_t nr_spinning;
};
/*
* Use a rwlock to protect the hypercall page from being executed in AP context
* while the BSP is re-initializing it after restore.
*/
static DEFINE_RWLOCK(suspend_lock);
/*
* Spinning prevents, for example, APs touching grant table entries while
* the shared grant table is not mapped into the address space imemdiately
@@ -27,7 +33,9 @@ static void ap_suspend(void *_info)
while (info->do_spin) {
cpu_relax();
read_lock(&suspend_lock);
HYPERVISOR_yield();
read_unlock(&suspend_lock);
}
mb();
@@ -43,7 +51,9 @@ static int bp_suspend(void)
suspend_cancelled = HYPERVISOR_shutdown(SHUTDOWN_suspend);
if (!suspend_cancelled) {
write_lock(&suspend_lock);
platform_pci_resume();
write_unlock(&suspend_lock);
gnttab_resume();
irq_resume();
}
+63 -40
View File
@@ -93,6 +93,7 @@ int acm_init_chwall_policy(void)
return ACM_OK;
}
static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
{
struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
@@ -104,10 +105,10 @@ static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
chwall_ssidp->chwall_ssidref =
GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
if ( (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
|| (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) )
if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
{
printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n",
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;
@@ -118,6 +119,7 @@ static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
return ACM_OK;
}
static void chwall_free_domain_ssid(void *chwall_ssid)
{
xfree(chwall_ssid);
@@ -205,7 +207,9 @@ chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
read_lock(&ssid_list_rwlock);
/* go through all domains and adjust policy as if this domain was started now */
/* go through all domains and adjust policy as if this domain was
* started now
*/
for_each_acmssid( rawssid )
{
chwall_ssid =
@@ -220,8 +224,8 @@ chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
/* 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])
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);
@@ -231,37 +235,46 @@ chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
goto out;
}
/* set violation and break out of the loop */
/* c) adapt conflict aggregate set for this domain (notice conflicts) */
/* 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])
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)
if ( common == 0 )
continue; /* try next conflict set */
/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
/* 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])
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 */
/* 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
*/
}
@@ -348,8 +361,10 @@ static int _chwall_update_policy(u8 *buf, u32 buf_size, int test_only,
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 */
/* 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,
@@ -483,31 +498,27 @@ static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
{
printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
__func__);
return ACM_ACCESS_DENIED; /* catching and indicating config error */
}
if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
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])
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)*/
* other domains simultaneously created are evaluated against
* this new set)
*/
for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
{
int common = 0;
@@ -521,7 +532,7 @@ static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
common = 1;
break;
}
if (common == 0)
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++ )
@@ -571,9 +582,15 @@ static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
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) */
{
/* 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]
@@ -638,9 +655,15 @@ static void chwall_domain_destroy(void *object_ssid, struct domain *d)
common = 1;
break;
}
if (common == 0)
continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
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]
+3 -3
View File
@@ -710,10 +710,10 @@ acm_change_policy(struct acm_change_policy *chgpolicy)
goto acm_chg_policy_exit;
}
if ( copy_from_guest(dels.array,
if ( copy_from_guest((u8 *)dels.array,
chgpolicy->del_array,
chgpolicy->delarray_size) ||
copy_from_guest(ssidmap.array,
copy_from_guest((u8 *)ssidmap.array,
chgpolicy->chg_array,
chgpolicy->chgarray_size) ||
copy_from_guest(binpolicy,
@@ -844,7 +844,7 @@ acm_relabel_domains(struct acm_relabel_doms *relabel)
memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items);
}
if ( copy_from_guest(relabels.array,
if ( copy_from_guest((u8 *)relabels.array,
relabel->relabel_map,
relabel->relabel_map_size) )
{
+1 -1
View File
@@ -408,7 +408,7 @@ _ste_update_policy(u8 *buf, u32 buf_size, int test_only,
ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
if ( ste_init_state(NULL) )
if ( ste_init_state(errors) )
{
/* new policy conflicts with sharing of running domains */
printk("%s: New policy conflicts with running domains. "
+67
View File
@@ -0,0 +1,67 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright IBM Corp. 2006, 2007
*
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
*/
#include <xen/config.h>
#include <xen/lib.h>
#include <xen/multiboot2.h>
#include <asm/boot.h>
#include <asm/init.h>
static struct mb2_tag_module *mb2_tag_mod_find(struct mb2_tag_header *tags,
const char *type)
{
struct mb2_tag_header *tag;
for_each_tag(tag, tags) {
if (tag->key == MB2_TAG_MODULE) {
struct mb2_tag_module *mod = (struct mb2_tag_module *)tag;
if (!strcmp((char *)mod->type, type))
return mod;
}
}
return NULL;
}
void parse_multiboot(ulong tags_addr)
{
struct mb2_tag_header *tags = (struct mb2_tag_header *)tags_addr;
struct mb2_tag_module *mod;
if (tags->key != MB2_TAG_START)
return;
mod = mb2_tag_mod_find(tags, "kernel");
if (mod) {
xen_cmdline = (char *)mod->cmdline;
}
mod = mb2_tag_mod_find(tags, "dom0");
if (mod) {
dom0_addr = mod->addr;
dom0_len = mod->size;
dom0_cmdline = (char *)mod->cmdline;
}
mod = mb2_tag_mod_find(tags, "initrd");
if (mod) {
initrd_start = mod->addr;
initrd_len = mod->size;
}
}
+4 -4
View File
@@ -316,9 +316,9 @@ int __init construct_dom0(
parms.pae ? ", PAE" : "",
elf_msb(&elf) ? "msb" : "lsb",
elf.pstart, elf.pend);
if ( parms.bsd_symtab )
if ( elf.bsd_symtab_pstart )
printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
elf.sstart, elf.send);
elf.bsd_symtab_pstart, elf.bsd_symtab_pend);
if ( !compatible )
{
@@ -388,7 +388,7 @@ int __init construct_dom0(
v_start = parms.virt_base;
vkern_start = parms.virt_kstart;
vkern_end = parms.virt_kend;
vinitrd_start = round_pgup(parms.virt_end);
vinitrd_start = round_pgup(vkern_end);
vinitrd_end = vinitrd_start + initrd_len;
vphysmap_start = round_pgup(vinitrd_end);
vphysmap_end = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ?
@@ -798,7 +798,7 @@ int __init construct_dom0(
/* Copy the OS image and free temporary buffer. */
elf.dest = (void*)vkern_start;
elf_xen_dom_load_binary(&elf, &parms);
elf_load_binary(&elf);
if ( UNSET_ADDR != parms.virt_hypercall )
{
-2
View File
@@ -1,7 +1,5 @@
obj-y += bigsmp.o
obj-y += default.o
obj-y += delivery.o
obj-y += es7000.o
obj-y += es7000plat.o
obj-y += probe.o
obj-y += summit.o
+7 -3
View File
@@ -13,7 +13,7 @@
static int dmi_bigsmp; /* can be set by dmi scanners */
static __init int hp_ht_bigsmp(struct dmi_system_id *d)
static __init int force_bigsmp(struct dmi_system_id *d)
{
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
dmi_bigsmp = 1;
@@ -22,15 +22,19 @@ static __init int hp_ht_bigsmp(struct dmi_system_id *d)
static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
{ hp_ht_bigsmp, "HP ProLiant DL760 G2", {
{ force_bigsmp, "HP ProLiant DL760 G2", {
DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
}},
{ hp_ht_bigsmp, "HP ProLiant DL740", {
{ force_bigsmp, "HP ProLiant DL740", {
DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
}},
{ force_bigsmp, "UNISYS ES7000-ONE", {
DMI_MATCH(DMI_PRODUCT_NAME, "ES7000-ONE")
}},
{ }
};
-27
View File
@@ -1,27 +0,0 @@
/*
* APIC driver for the Unisys ES7000 chipset.
*/
#include <xen/config.h>
#include <xen/cpumask.h>
#include <asm/current.h>
#include <asm/mpspec.h>
#include <asm/genapic.h>
#include <asm/fixmap.h>
#include <asm/apicdef.h>
#include <asm/atomic.h>
#include <xen/kernel.h>
#include <xen/string.h>
#include <xen/smp.h>
#include <xen/init.h>
#include <asm/mach-es7000/mach_mpparse.h>
static __init int probe_es7000(void)
{
/* probed later in mptable/ACPI hooks */
return 0;
}
struct genapic apic_es7000 = {
APIC_INIT("es7000", probe_es7000),
GENAPIC_PHYS
};
-141
View File
@@ -1,141 +0,0 @@
/*
* Written by: Garry Forsgren, Unisys Corporation
* Natalie Protasevich, Unisys Corporation
* Modified by: Raj Subrahmanian <raj.subrahmanian@unisys.com> Unisys Corp.
* This file contains the code to configure and interface
* with Unisys ES7000 series hardware system manager.
*
* Copyright (c) 2003 Unisys Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Unisys Corporation, Township Line & Union Meeting
* Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
*
* http://www.unisys.com
*/
#include <xen/config.h>
#include <xen/types.h>
#include <xen/kernel.h>
#include <xen/smp.h>
#include <xen/string.h>
#include <xen/spinlock.h>
#include <xen/errno.h>
#include <xen/init.h>
#include <xen/acpi.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/apicdef.h>
#define MIP_REG 1
#define MIP_PSAI_REG 4
struct acpi_table_sdt {
unsigned long pa;
unsigned long count;
struct {
unsigned long pa;
enum acpi_table_id id;
unsigned long size;
} entry[50];
};
struct oem_table {
struct acpi_table_header Header;
u32 OEMTableAddr;
u32 OEMTableSize;
};
int __init
parse_unisys_oem(char *oemptr)
{
int i;
int success = 0;
unsigned char type, size;
char *tp = NULL;
tp = oemptr;
tp += 8;
for (i=0; i <= 6; i++) {
type = *tp++;
size = *tp++;
tp -= 2;
switch (type) {
case MIP_REG:
case MIP_PSAI_REG:
success++;
break;
default:
break;
}
tp += size;
}
return (success >= 2);
}
int __init
find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
struct acpi_table_rsdp *rsdp = NULL;
unsigned long rsdp_phys = 0;
struct acpi_table_header *header = NULL;
int i;
struct acpi_table_sdt sdt = { 0 }; /* initialise sdt.count */
rsdp_phys = acpi_find_rsdp();
rsdp = __va(rsdp_phys);
if (rsdp->rsdt_address) {
struct acpi_table_rsdt *mapped_rsdt = NULL;
sdt.pa = rsdp->rsdt_address;
header = (struct acpi_table_header *)
__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
if (!header)
return -ENODEV;
sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3;
mapped_rsdt = (struct acpi_table_rsdt *)
__acpi_map_table(sdt.pa, header->length);
if (!mapped_rsdt)
return -ENODEV;
header = &mapped_rsdt->header;
for (i = 0; i < sdt.count; i++)
sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
};
for (i = 0; i < sdt.count; i++) {
header = (struct acpi_table_header *)
__acpi_map_table(sdt.entry[i].pa,
sizeof(struct acpi_table_header));
if (!header)
continue;
if (!strncmp((char *) &header->signature, "OEM1", 4)) {
if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) {
void *addr;
struct oem_table *t;
acpi_table_print(header, sdt.entry[i].pa);
t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length);
addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize);
*oem_addr = (unsigned long) addr;
return 0;
}
}
}
return -1;
}
-2
View File
@@ -16,7 +16,6 @@
extern struct genapic apic_summit;
extern struct genapic apic_bigsmp;
extern struct genapic apic_es7000;
extern struct genapic apic_default;
struct genapic *genapic;
@@ -24,7 +23,6 @@ struct genapic *genapic;
struct genapic *apic_probe[] __initdata = {
&apic_summit,
&apic_bigsmp,
&apic_es7000,
&apic_default, /* must be last */
NULL,
};
+25 -1
View File
@@ -395,9 +395,33 @@ static void irq_dump(struct domain *d)
static int irq_save_pci(struct domain *d, hvm_domain_context_t *h)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
unsigned int asserted, pdev, pintx;
int rc;
spin_lock(&d->arch.hvm_domain.irq_lock);
pdev = hvm_irq->callback_via.pci.dev;
pintx = hvm_irq->callback_via.pci.intx;
asserted = (hvm_irq->callback_via_asserted &&
(hvm_irq->callback_via_type == HVMIRQ_callback_pci_intx));
/*
* Deassert virtual interrupt via PCI INTx line. The virtual interrupt
* status is not save/restored, so the INTx line must be deasserted in
* the restore context.
*/
if ( asserted )
__hvm_pci_intx_deassert(d, pdev, pintx);
/* Save PCI IRQ lines */
return ( hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx) );
rc = hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx);
if ( asserted )
__hvm_pci_intx_assert(d, pdev, pintx);
spin_unlock(&d->arch.hvm_domain.irq_lock);
return rc;
}
static int irq_save_isa(struct domain *d, hvm_domain_context_t *h)
+1
View File
@@ -2159,6 +2159,7 @@ static void svm_do_msr_access(
case MSR_K8_MC2_STATUS:
case MSR_K8_MC3_STATUS:
case MSR_K8_MC4_STATUS:
case MSR_K8_MC5_STATUS:
/* No point in letting the guest see real MCEs */
msr_content = 0;
break;
+1
View File
@@ -2596,6 +2596,7 @@ static int vmx_do_msr_read(struct cpu_user_regs *regs)
case MSR_K8_MC2_STATUS:
case MSR_K8_MC3_STATUS:
case MSR_K8_MC4_STATUS:
case MSR_K8_MC5_STATUS:
/* No point in letting the guest see real MCEs */
msr_content = 0;
break;
+1 -1
View File
@@ -84,7 +84,7 @@ unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
mfn = get_mfn_from_gpfn(gpfn);
if ( mfn == INVALID_MFN )
{
HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva,
HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva,
lev);
success = 0;
break;
+28 -28
View File
@@ -73,7 +73,7 @@ int hap_disable_log_dirty(struct domain *d)
hap_unlock(d);
/* set l1e entries of P2M table with normal mode */
p2m_set_flags_global(d, __PAGE_HYPERVISOR|_PAGE_USER);
p2m_set_flags_global(d, __PAGE_HYPERVISOR|_PAGE_USER);
return 0;
}
@@ -111,7 +111,7 @@ static struct page_info *hap_alloc(struct domain *d)
static void hap_free(struct domain *d, mfn_t mfn)
{
struct page_info *pg = mfn_to_page(mfn);
struct page_info *pg = mfn_to_page(mfn);
ASSERT(hap_locked_by_me(d));
@@ -128,7 +128,7 @@ static struct page_info *hap_alloc_p2m_page(struct domain *d)
#if CONFIG_PAGING_LEVELS == 3
/* Under PAE mode, top-level P2M table should be allocated below 4GB space
* because the size of h_cr3 is only 32-bit. We use alloc_domheap_pages to
* because the size of h_cr3 is only 32-bit. We use alloc_domheap_pages to
* force this requirement, and exchange the guaranteed 32-bit-clean
* page for the one we just hap_alloc()ed. */
if ( d->arch.paging.hap.p2m_pages == 0
@@ -166,9 +166,9 @@ void hap_free_p2m_page(struct domain *d, struct page_info *pg)
HAP_ERROR("Odd p2m page count c=%#x t=%"PRtype_info"\n",
pg->count_info, pg->u.inuse.type_info);
pg->count_info = 0;
/* Free should not decrement domain's total allocation, since
/* Free should not decrement domain's total allocation, since
* these pages were allocated without an owner. */
page_set_owner(pg, NULL);
page_set_owner(pg, NULL);
free_domheap_page(pg);
d->arch.paging.hap.p2m_pages--;
ASSERT(d->arch.paging.hap.p2m_pages >= 0);
@@ -221,7 +221,7 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
pg->count_info = 0;
free_domheap_page(pg);
}
/* Check to see if we need to yield and try again */
if ( preempted && hypercall_preempt_check() )
{
@@ -275,7 +275,7 @@ static void hap_install_xen_entries_in_l2h(struct vcpu *v, mfn_t l2hmfn)
l2e = hap_map_domain_page(l2hmfn);
ASSERT(l2e != NULL);
/* Copy the common Xen mappings from the idle domain */
memcpy(&l2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)],
&idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT],
@@ -318,7 +318,7 @@ static void hap_install_xen_entries_in_l2(struct vcpu *v, mfn_t l2mfn)
l2e = hap_map_domain_page(l2mfn);
ASSERT(l2e != NULL);
/* Copy the common Xen mappings from the idle domain */
memcpy(&l2e[L2_PAGETABLE_FIRST_XEN_SLOT],
&idle_pg_table[L2_PAGETABLE_FIRST_XEN_SLOT],
@@ -362,7 +362,7 @@ static mfn_t hap_make_monitor_table(struct vcpu *v)
}
#elif CONFIG_PAGING_LEVELS == 3
{
mfn_t m3mfn, m2mfn;
mfn_t m3mfn, m2mfn;
l3_pgentry_t *l3e;
l2_pgentry_t *l2e;
int i;
@@ -384,8 +384,8 @@ static mfn_t hap_make_monitor_table(struct vcpu *v)
l2e = hap_map_domain_page(m2mfn);
for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
l2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
(l3e_get_flags(l3e[i]) & _PAGE_PRESENT)
? l2e_from_pfn(l3e_get_pfn(l3e[i]), __PAGE_HYPERVISOR)
(l3e_get_flags(l3e[i]) & _PAGE_PRESENT)
? l2e_from_pfn(l3e_get_pfn(l3e[i]), __PAGE_HYPERVISOR)
: l2e_empty();
hap_unmap_domain_page(l2e);
hap_unmap_domain_page(l3e);
@@ -536,7 +536,7 @@ void hap_teardown(struct domain *d)
d->arch.paging.hap.p2m_pages);
ASSERT(d->arch.paging.hap.total_pages == 0);
}
d->arch.paging.mode &= ~PG_log_dirty;
hap_unlock(d);
@@ -555,7 +555,7 @@ int hap_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
hap_unlock(d);
if ( preempted )
/* Not finished. Set up to re-run the call. */
rc = hypercall_create_continuation(__HYPERVISOR_domctl, "h",
rc = hypercall_create_continuation(__HYPERVISOR_domctl, "h",
u_domctl);
else
/* Finished. Return the new allocation */
@@ -578,11 +578,11 @@ void hap_vcpu_init(struct vcpu *v)
/************************************************/
/* HAP PAGING MODE FUNCTIONS */
/************************************************/
/*
/*
* HAP guests can handle page faults (in the guest page tables) without
* needing any action from Xen, so we should not be intercepting them.
*/
static int hap_page_fault(struct vcpu *v, unsigned long va,
static int hap_page_fault(struct vcpu *v, unsigned long va,
struct cpu_user_regs *regs)
{
HAP_ERROR("Intercepted a guest #PF (%u:%u) with HAP enabled.\n",
@@ -591,9 +591,9 @@ static int hap_page_fault(struct vcpu *v, unsigned long va,
return 0;
}
/*
/*
* HAP guests can handle invlpg without needing any action from Xen, so
* should not be intercepting it.
* should not be intercepting it.
*/
static int hap_invlpg(struct vcpu *v, unsigned long va)
{
@@ -649,7 +649,7 @@ static void hap_update_paging_modes(struct vcpu *v)
}
#if CONFIG_PAGING_LEVELS == 3
static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e)
static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e)
/* Special case, only used for PAE hosts: update the mapping of the p2m
* table. This is trivial in other paging modes (one top-level entry
* points to the top-level p2m, no maintenance needed), but PAE makes
@@ -660,13 +660,13 @@ static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e)
l2_pgentry_t *ml2e;
struct vcpu *v;
unsigned int index;
index = ((unsigned long)l3e & ~PAGE_MASK) / sizeof(l3_pgentry_t);
ASSERT(index < MACHPHYS_MBYTES>>1);
for_each_vcpu ( d, v )
{
if ( pagetable_get_pfn(v->arch.monitor_table) == 0 )
if ( pagetable_get_pfn(v->arch.monitor_table) == 0 )
continue;
ASSERT(paging_mode_external(v->domain));
@@ -689,7 +689,7 @@ static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e)
}
#endif
static void
static void
hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
mfn_t table_mfn, l1_pgentry_t new, unsigned int level)
{
@@ -698,12 +698,12 @@ hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
safe_write_pte(p, new);
#if CONFIG_PAGING_LEVELS == 3
/* install P2M in monitor table for PAE Xen */
if ( level == 3 )
if ( level == 3 )
/* We have written to the p2m l3: need to sync the per-vcpu
* copies of it in the monitor tables */
p2m_install_entry_in_monitors(v->domain, (l3_pgentry_t *)p);
#endif
hap_unlock(v->domain);
}
@@ -715,7 +715,7 @@ static unsigned long hap_gva_to_gfn_real_mode(
/* Entry points into this mode of the hap code. */
struct paging_mode hap_paging_real_mode = {
.page_fault = hap_page_fault,
.page_fault = hap_page_fault,
.invlpg = hap_invlpg,
.gva_to_gfn = hap_gva_to_gfn_real_mode,
.update_cr3 = hap_update_cr3,
@@ -725,7 +725,7 @@ struct paging_mode hap_paging_real_mode = {
};
struct paging_mode hap_paging_protected_mode = {
.page_fault = hap_page_fault,
.page_fault = hap_page_fault,
.invlpg = hap_invlpg,
.gva_to_gfn = hap_gva_to_gfn_2level,
.update_cr3 = hap_update_cr3,
@@ -735,7 +735,7 @@ struct paging_mode hap_paging_protected_mode = {
};
struct paging_mode hap_paging_pae_mode = {
.page_fault = hap_page_fault,
.page_fault = hap_page_fault,
.invlpg = hap_invlpg,
.gva_to_gfn = hap_gva_to_gfn_3level,
.update_cr3 = hap_update_cr3,
@@ -745,7 +745,7 @@ struct paging_mode hap_paging_pae_mode = {
};
struct paging_mode hap_paging_long_mode = {
.page_fault = hap_page_fault,
.page_fault = hap_page_fault,
.invlpg = hap_invlpg,
.gva_to_gfn = hap_gva_to_gfn_4level,
.update_cr3 = hap_update_cr3,
+87 -87
View File
@@ -2,12 +2,12 @@
* arch/x86/mm/p2m.c
*
* physical-to-machine mappings for automatically-translated domains.
*
*
* Parts of this code are Copyright (c) 2007 by Advanced Micro Devices.
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -34,7 +34,7 @@
/*
* The P2M lock. This protects all updates to the p2m table.
* Updates are expected to be safe against concurrent reads,
* Updates are expected to be safe against concurrent reads,
* which do *not* require the lock.
*
* Locking discipline: always acquire this lock before the shadow or HAP one
@@ -80,7 +80,7 @@
#define P2M_DEBUG(_f, _a...) \
debugtrace_printk("p2mdebug: %s(): " _f, __func__, ##_a)
#else
#define P2M_DEBUG(_f, _a...) do { (void)(_f); } while(0)
#define P2M_DEBUG(_f, _a...) do { (void)(_f); } while(0)
#endif
@@ -119,8 +119,8 @@ p2m_find_entry(void *table, unsigned long *gfn_remainder,
// Returns 0 on error.
//
static int
p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
unsigned long *gfn_remainder, unsigned long gfn, u32 shift,
p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
unsigned long *gfn_remainder, unsigned long gfn, u32 shift,
u32 max, unsigned long type)
{
l1_pgentry_t *p2m_entry;
@@ -146,7 +146,7 @@ p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
switch ( type ) {
case PGT_l3_page_table:
paging_write_p2m_entry(d, gfn,
paging_write_p2m_entry(d, gfn,
p2m_entry, *table_mfn, new_entry, 4);
break;
case PGT_l2_page_table:
@@ -154,11 +154,11 @@ p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
/* for PAE mode, PDPE only has PCD/PWT/P bits available */
new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)), _PAGE_PRESENT);
#endif
paging_write_p2m_entry(d, gfn,
paging_write_p2m_entry(d, gfn,
p2m_entry, *table_mfn, new_entry, 3);
break;
case PGT_l1_page_table:
paging_write_p2m_entry(d, gfn,
paging_write_p2m_entry(d, gfn,
p2m_entry, *table_mfn, new_entry, 2);
break;
default:
@@ -216,7 +216,7 @@ set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, u32 l1e_flags)
ASSERT(p2m_entry);
/* Track the highest gfn for which we have ever had a valid mapping */
if ( mfn_valid(mfn) && (gfn > d->arch.p2m.max_mapped_pfn) )
if ( mfn_valid(mfn) && (gfn > d->arch.p2m.max_mapped_pfn) )
d->arch.p2m.max_mapped_pfn = gfn;
if ( mfn_valid(mfn) )
@@ -229,7 +229,7 @@ set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, u32 l1e_flags)
/* Success */
rv = 1;
out:
unmap_domain_page(table);
return rv;
@@ -250,7 +250,7 @@ void p2m_init(struct domain *d)
// controlled by CONFIG_PAGING_LEVELS).
//
// The alloc_page and free_page functions will be used to get memory to
// build the p2m, and to release it again at the end of day.
// build the p2m, and to release it again at the end of day.
//
// Returns 0 for success or -errno.
//
@@ -264,7 +264,7 @@ int p2m_alloc_table(struct domain *d,
struct page_info *page, *p2m_top;
unsigned int page_count = 0;
unsigned long gfn;
p2m_lock(d);
if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
@@ -288,7 +288,7 @@ int p2m_alloc_table(struct domain *d,
list_add_tail(&p2m_top->list, &d->arch.p2m.pages);
p2m_top->count_info = 1;
p2m_top->u.inuse.type_info =
p2m_top->u.inuse.type_info =
#if CONFIG_PAGING_LEVELS == 4
PGT_l4_page_table
#elif CONFIG_PAGING_LEVELS == 3
@@ -301,7 +301,7 @@ int p2m_alloc_table(struct domain *d,
d->arch.phys_table = pagetable_from_mfn(page_to_mfn(p2m_top));
P2M_PRINTK("populating p2m table\n");
/* Initialise physmap tables for slot zero. Other code assumes this. */
gfn = 0;
mfn = _mfn(INVALID_MFN);
@@ -365,17 +365,17 @@ gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
paddr_t addr = ((paddr_t)gpfn) << PAGE_SHIFT;
l2_pgentry_t *l2e;
l1_pgentry_t *l1e;
ASSERT(paging_mode_translate(d));
mfn = pagetable_get_mfn(d->arch.phys_table);
if ( gpfn > d->arch.p2m.max_mapped_pfn )
if ( gpfn > d->arch.p2m.max_mapped_pfn )
/* This pfn is higher than the highest the p2m map currently holds */
return _mfn(INVALID_MFN);
#if CONFIG_PAGING_LEVELS >= 4
{
{
l4_pgentry_t *l4e = map_domain_page(mfn_x(mfn));
l4e += l4_table_offset(addr);
if ( (l4e_get_flags(*l4e) & _PAGE_PRESENT) == 0 )
@@ -398,7 +398,7 @@ gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
* the bounds of the p2m. */
l3e += (addr >> L3_PAGETABLE_SHIFT);
#else
l3e += l3_table_offset(addr);
l3e += l3_table_offset(addr);
#endif
if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 )
{
@@ -443,18 +443,18 @@ static void audit_p2m(struct domain *d)
mfn_t p2mfn;
unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0;
int test_linear;
if ( !paging_mode_translate(d) )
return;
//P2M_PRINTK("p2m audit starts\n");
test_linear = ( (d == current->domain)
test_linear = ( (d == current->domain)
&& !pagetable_is_null(current->arch.monitor_table) );
if ( test_linear )
local_flush_tlb();
local_flush_tlb();
/* Audit part one: walk the domain's page allocation list, checking
/* Audit part one: walk the domain's page allocation list, checking
* the m2p entries. */
for ( entry = d->page_list.next;
entry != &d->page_list;
@@ -463,11 +463,11 @@ static void audit_p2m(struct domain *d)
page = list_entry(entry, struct page_info, list);
mfn = mfn_x(page_to_mfn(page));
// P2M_PRINTK("auditing guest page, mfn=%#lx\n", mfn);
// P2M_PRINTK("auditing guest page, mfn=%#lx\n", mfn);
od = page_get_owner(page);
if ( od != d )
if ( od != d )
{
P2M_PRINTK("wrong owner %#lx -> %p(%u) != %p(%u)\n",
mfn, od, (od?od->domain_id:-1), d, d->domain_id);
@@ -475,19 +475,19 @@ static void audit_p2m(struct domain *d)
}
gfn = get_gpfn_from_mfn(mfn);
if ( gfn == INVALID_M2P_ENTRY )
if ( gfn == INVALID_M2P_ENTRY )
{
orphans_i++;
//P2M_PRINTK("orphaned guest page: mfn=%#lx has invalid gfn\n",
// mfn);
// mfn);
continue;
}
if ( gfn == 0x55555555 )
if ( gfn == 0x55555555 )
{
orphans_d++;
//P2M_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n",
// mfn);
//P2M_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n",
// mfn);
continue;
}
@@ -503,7 +503,7 @@ static void audit_p2m(struct domain *d)
: -1u));
/* This m2p entry is stale: the domain has another frame in
* this physical slot. No great disaster, but for neatness,
* blow away the m2p entry. */
* blow away the m2p entry. */
set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY, __PAGE_HYPERVISOR|_PAGE_USER);
}
@@ -517,9 +517,9 @@ static void audit_p2m(struct domain *d)
}
}
// P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n",
// mfn, gfn, p2mfn, lp2mfn);
}
// P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n",
// mfn, gfn, p2mfn, lp2mfn);
}
/* Audit part two: walk the domain's p2m table, checking the entries. */
if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
@@ -527,7 +527,7 @@ static void audit_p2m(struct domain *d)
l2_pgentry_t *l2e;
l1_pgentry_t *l1e;
int i1, i2;
#if CONFIG_PAGING_LEVELS == 4
l4_pgentry_t *l4e;
l3_pgentry_t *l3e;
@@ -553,8 +553,8 @@ static void audit_p2m(struct domain *d)
}
l3e = map_domain_page(mfn_x(_mfn(l4e_get_pfn(l4e[i4]))));
#endif /* now at levels 3 or 4... */
for ( i3 = 0;
i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
for ( i3 = 0;
i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
i3++ )
{
if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
@@ -572,7 +572,7 @@ static void audit_p2m(struct domain *d)
continue;
}
l1e = map_domain_page(mfn_x(_mfn(l2e_get_pfn(l2e[i2]))));
for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
{
if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
@@ -610,14 +610,14 @@ static void audit_p2m(struct domain *d)
}
//P2M_PRINTK("p2m audit complete\n");
//if ( orphans_i | orphans_d | mpbad | pmbad )
//if ( orphans_i | orphans_d | mpbad | pmbad )
// P2M_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n",
// orphans_i + orphans_d, orphans_i, orphans_d,
if ( mpbad | pmbad )
if ( mpbad | pmbad )
P2M_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n",
pmbad, mpbad);
}
#else
#else
#define audit_p2m(_d) do { (void)(_d); } while(0)
#endif /* P2M_AUDIT */
@@ -645,7 +645,7 @@ guest_physmap_remove_page(struct domain *d, unsigned long gfn,
audit_p2m(d);
p2m_remove_page(d, gfn, mfn);
audit_p2m(d);
p2m_unlock(d);
p2m_unlock(d);
}
void
@@ -683,11 +683,11 @@ guest_physmap_add_page(struct domain *d, unsigned long gfn,
/* This machine frame is already mapped at another physical address */
P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
mfn, ogfn, gfn);
if ( mfn_valid(omfn = gfn_to_mfn(d, ogfn)) )
if ( mfn_valid(omfn = gfn_to_mfn(d, ogfn)) )
{
P2M_DEBUG("old gfn=%#lx -> mfn %#lx\n",
P2M_DEBUG("old gfn=%#lx -> mfn %#lx\n",
ogfn , mfn_x(omfn));
if ( mfn_x(omfn) == mfn )
if ( mfn_x(omfn) == mfn )
p2m_remove_page(d, ogfn, mfn);
}
}
@@ -720,15 +720,15 @@ void p2m_set_flags_global(struct domain *d, u32 l1e_flags)
int i4;
#endif /* CONFIG_PAGING_LEVELS == 4 */
#endif /* CONFIG_PAGING_LEVELS >= 3 */
if ( !paging_mode_translate(d) )
return;
if ( pagetable_get_pfn(d->arch.phys_table) == 0 )
return;
p2m_lock(d);
#if CONFIG_PAGING_LEVELS == 4
l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
#elif CONFIG_PAGING_LEVELS == 3
@@ -739,52 +739,52 @@ void p2m_set_flags_global(struct domain *d, u32 l1e_flags)
#if CONFIG_PAGING_LEVELS >= 3
#if CONFIG_PAGING_LEVELS >= 4
for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; i4++ )
for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; i4++ )
{
if ( !(l4e_get_flags(l4e[i4]) & _PAGE_PRESENT) )
{
continue;
}
l3e = map_domain_page(l4e_get_pfn(l4e[i4]));
if ( !(l4e_get_flags(l4e[i4]) & _PAGE_PRESENT) )
{
continue;
}
l3e = map_domain_page(l4e_get_pfn(l4e[i4]));
#endif /* now at levels 3 or 4... */
for ( i3 = 0;
i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
i3++ )
{
if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
{
continue;
}
l2e = map_domain_page(l3e_get_pfn(l3e[i3]));
for ( i3 = 0;
i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
i3++ )
{
if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
{
continue;
}
l2e = map_domain_page(l3e_get_pfn(l3e[i3]));
#endif /* all levels... */
for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
{
if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) )
{
continue;
}
for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
{
if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) )
{
continue;
}
l1mfn = _mfn(l2e_get_pfn(l2e[i2]));
l1e = map_domain_page(mfn_x(l1mfn));
for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
{
if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
continue;
mfn = l1e_get_pfn(l1e[i1]);
gfn = get_gpfn_from_mfn(mfn);
/* create a new 1le entry using l1e_flags */
l1e_content = l1e_from_pfn(mfn, l1e_flags);
paging_write_p2m_entry(d, gfn, &l1e[i1],
l1e = map_domain_page(mfn_x(l1mfn));
for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
{
if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
continue;
mfn = l1e_get_pfn(l1e[i1]);
gfn = get_gpfn_from_mfn(mfn);
/* create a new 1le entry using l1e_flags */
l1e_content = l1e_from_pfn(mfn, l1e_flags);
paging_write_p2m_entry(d, gfn, &l1e[i1],
l1mfn, l1e_content, 1);
}
unmap_domain_page(l1e);
}
}
unmap_domain_page(l1e);
}
#if CONFIG_PAGING_LEVELS >= 3
unmap_domain_page(l2e);
}
unmap_domain_page(l2e);
}
#if CONFIG_PAGING_LEVELS >= 4
unmap_domain_page(l3e);
unmap_domain_page(l3e);
}
#endif
#endif
@@ -814,7 +814,7 @@ int p2m_set_flags(struct domain *d, paddr_t gpa, u32 l1e_flags)
mfn = gfn_to_mfn(d, gfn);
if ( mfn_valid(mfn) )
set_p2m_entry(d, gfn, mfn, l1e_flags);
p2m_unlock(d);
return 1;
+38 -38
View File
@@ -54,10 +54,10 @@ boolean_param("hap", opt_hap_enabled);
#define page_to_mfn(_pg) (_mfn((_pg) - frame_table))
/* The log-dirty lock. This protects the log-dirty bitmap from
* concurrent accesses (and teardowns, etc).
*
* concurrent accesses (and teardowns, etc).
*
* Locking discipline: always acquire shadow or HAP lock before this one.
*
*
* Because mark_dirty is called from a lot of places, the log-dirty lock
* may be acquired with the shadow or HAP locks already held. When the
* log-dirty code makes callbacks into HAP or shadow code to reset
@@ -105,7 +105,7 @@ int paging_alloc_log_dirty_bitmap(struct domain *d)
d->arch.paging.log_dirty.bitmap_size =
(domain_get_maximum_gpfn(d) + BITS_PER_LONG) & ~(BITS_PER_LONG - 1);
d->arch.paging.log_dirty.bitmap =
d->arch.paging.log_dirty.bitmap =
xmalloc_array(unsigned long,
d->arch.paging.log_dirty.bitmap_size / BITS_PER_LONG);
if ( d->arch.paging.log_dirty.bitmap == NULL )
@@ -152,8 +152,8 @@ int paging_log_dirty_enable(struct domain *d)
log_dirty_unlock(d);
/* Safe because the domain is paused. */
ret = d->arch.paging.log_dirty.enable_log_dirty(d);
/* Safe because the domain is paused. */
ret = d->arch.paging.log_dirty.enable_log_dirty(d);
/* Possibility of leaving the bitmap allocated here but it'll be
* tidied on domain teardown. */
@@ -202,7 +202,7 @@ void paging_mark_dirty(struct domain *d, unsigned long guest_mfn)
pfn = get_gpfn_from_mfn(mfn_x(gmfn));
/*
* Values with the MSB set denote MFNs that aren't really part of the
* Values with the MSB set denote MFNs that aren't really part of the
* domain's pseudo-physical memory map (e.g., the shared info frame).
* Nothing to do here...
*/
@@ -212,11 +212,11 @@ void paging_mark_dirty(struct domain *d, unsigned long guest_mfn)
return;
}
if ( likely(pfn < d->arch.paging.log_dirty.bitmap_size) )
{
if ( likely(pfn < d->arch.paging.log_dirty.bitmap_size) )
{
if ( !__test_and_set_bit(pfn, d->arch.paging.log_dirty.bitmap) )
{
PAGING_DEBUG(LOGDIRTY,
PAGING_DEBUG(LOGDIRTY,
"marked mfn %" PRI_mfn " (pfn=%lx), dom %d\n",
mfn_x(gmfn), pfn, d->domain_id);
d->arch.paging.log_dirty.dirty_count++;
@@ -227,21 +227,21 @@ void paging_mark_dirty(struct domain *d, unsigned long guest_mfn)
PAGING_PRINTK("mark_dirty OOR! "
"mfn=%" PRI_mfn " pfn=%lx max=%x (dom %d)\n"
"owner=%d c=%08x t=%" PRtype_info "\n",
mfn_x(gmfn),
pfn,
mfn_x(gmfn),
pfn,
d->arch.paging.log_dirty.bitmap_size,
d->domain_id,
(page_get_owner(mfn_to_page(gmfn))
? page_get_owner(mfn_to_page(gmfn))->domain_id
: -1),
mfn_to_page(gmfn)->count_info,
mfn_to_page(gmfn)->count_info,
mfn_to_page(gmfn)->u.inuse.type_info);
}
log_dirty_unlock(d);
}
/* Read a domain's log-dirty bitmap and stats. If the operation is a CLEAN,
/* Read a domain's log-dirty bitmap and stats. If the operation is a CLEAN,
* clear the bitmap and stats as well. */
int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
{
@@ -252,15 +252,15 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
clean = (sc->op == XEN_DOMCTL_SHADOW_OP_CLEAN);
PAGING_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n",
PAGING_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n",
(clean) ? "clean" : "peek",
d->domain_id,
d->arch.paging.log_dirty.fault_count,
d->arch.paging.log_dirty.fault_count,
d->arch.paging.log_dirty.dirty_count);
sc->stats.fault_count = d->arch.paging.log_dirty.fault_count;
sc->stats.dirty_count = d->arch.paging.log_dirty.dirty_count;
if ( clean )
{
d->arch.paging.log_dirty.fault_count = 0;
@@ -276,7 +276,7 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
rv = -EINVAL; /* perhaps should be ENOMEM? */
goto out;
}
if ( sc->pages > d->arch.paging.log_dirty.bitmap_size )
sc->pages = d->arch.paging.log_dirty.bitmap_size;
@@ -322,11 +322,11 @@ int paging_log_dirty_op(struct domain *d, struct xen_domctl_shadow_op *sc)
/* Note that this function takes three function pointers. Callers must supply
* these functions for log dirty code to call. This function usually is
* invoked when paging is enabled. Check shadow_enable() and hap_enable() for
* these functions for log dirty code to call. This function usually is
* invoked when paging is enabled. Check shadow_enable() and hap_enable() for
* reference.
*
* These function pointers must not be followed with the log-dirty lock held.
* These function pointers must not be followed with the log-dirty lock held.
*/
void paging_log_dirty_init(struct domain *d,
int (*enable_log_dirty)(struct domain *d),
@@ -335,7 +335,7 @@ void paging_log_dirty_init(struct domain *d,
{
/* We initialize log dirty lock first */
log_dirty_lock_init(d);
d->arch.paging.log_dirty.enable_log_dirty = enable_log_dirty;
d->arch.paging.log_dirty.disable_log_dirty = disable_log_dirty;
d->arch.paging.log_dirty.clean_dirty_bitmap = clean_dirty_bitmap;
@@ -387,7 +387,7 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
d->domain_id);
return -EINVAL;
}
if ( unlikely(d->is_dying) )
{
gdprintk(XENLOG_INFO, "Ignoring paging op on dying domain %u\n",
@@ -401,38 +401,38 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
d->domain_id);
return -EINVAL;
}
/* Code to handle log-dirty. Note that some log dirty operations
* piggy-back on shadow operations. For example, when
* piggy-back on shadow operations. For example, when
* XEN_DOMCTL_SHADOW_OP_OFF is called, it first checks whether log dirty
* mode is enabled. If does, we disables log dirty and continues with
* shadow code. For this reason, we need to further dispatch domctl
* mode is enabled. If does, we disables log dirty and continues with
* shadow code. For this reason, we need to further dispatch domctl
* to next-level paging code (shadow or hap).
*/
switch ( sc->op )
{
case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
return paging_log_dirty_enable(d);
case XEN_DOMCTL_SHADOW_OP_ENABLE:
return paging_log_dirty_enable(d);
case XEN_DOMCTL_SHADOW_OP_ENABLE:
if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY )
return paging_log_dirty_enable(d);
case XEN_DOMCTL_SHADOW_OP_OFF:
if ( paging_mode_log_dirty(d) )
if ( (rc = paging_log_dirty_disable(d)) != 0 )
if ( (rc = paging_log_dirty_disable(d)) != 0 )
return rc;
case XEN_DOMCTL_SHADOW_OP_CLEAN:
case XEN_DOMCTL_SHADOW_OP_PEEK:
return paging_log_dirty_op(d, sc);
return paging_log_dirty_op(d, sc);
}
/* Here, dispatch domctl to the appropriate paging code */
if ( opt_hap_enabled && is_hvm_domain(d) )
return hap_domctl(d, sc, u_domctl);
return hap_domctl(d, sc, u_domctl);
else
return shadow_domctl(d, sc, u_domctl);
return shadow_domctl(d, sc, u_domctl);
}
/* Call when destroying a domain */
@@ -492,7 +492,7 @@ void paging_dump_vcpu_info(struct vcpu *v)
{
if ( paging_mode_enabled(v->domain) )
{
printk(" paging assistance: ");
printk(" paging assistance: ");
if ( paging_mode_shadow(v->domain) )
{
if ( v->arch.paging.mode )
@@ -504,7 +504,7 @@ void paging_dump_vcpu_info(struct vcpu *v)
printk("not shadowed\n");
}
else if ( paging_mode_hap(v->domain) && v->arch.paging.mode )
printk("hap, %u levels\n",
printk("hap, %u levels\n",
v->arch.paging.mode->guest_levels);
else
printk("none\n");
+2 -2
View File
@@ -161,7 +161,7 @@ int compat_grant_table_op(unsigned int cmd,
while ( n-- )
{
guest_handle_add_offset(xfer, -1);
if ( __copy_field_to_guest(xfer, nat.xfer, status) )
if ( __copy_field_to_guest(xfer, nat.xfer + n, status) )
rc = -EFAULT;
}
}
@@ -199,7 +199,7 @@ int compat_grant_table_op(unsigned int cmd,
while ( n-- )
{
guest_handle_add_offset(copy, -1);
if ( __copy_field_to_guest(copy, nat.copy, status) )
if ( __copy_field_to_guest(copy, nat.copy + n, status) )
rc = -EFAULT;
}
}
+6 -98
View File
@@ -333,99 +333,6 @@ static int elf_xen_note_check(struct elf_binary *elf,
return 0;
}
static void elf_xen_loadsymtab(struct elf_binary *elf,
struct elf_dom_parms *parms)
{
unsigned long maxva, len;
if ( !parms->bsd_symtab )
return;
/* Calculate the required additional kernel space for the elf image */
/* The absolute base address of the elf image */
maxva = elf_round_up(elf, parms->virt_kend);
maxva += sizeof(long); /* Space to store the size of the elf image */
/* Space for the elf and elf section headers */
maxva += (elf_uval(elf, elf->ehdr, e_ehsize) +
elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
maxva = elf_round_up(elf, maxva);
/* Space for the symbol and string tabs */
len = (unsigned long)elf->send - (unsigned long)elf->sstart;
maxva = elf_round_up(elf, maxva + len);
/* The address the kernel must expanded to */
parms->virt_end = maxva;
}
int elf_xen_dom_load_binary(struct elf_binary *elf,
struct elf_dom_parms *parms)
{
elf_ehdr *sym_ehdr;
unsigned long shdr, symtab_addr;
unsigned long maxva, symbase;
uint8_t i;
char *p;
elf_load_binary(elf);
if ( !parms->bsd_symtab )
return 0;
#define elf_hdr_elm(_elf, _hdr, _elm, _val) \
do { \
if ( elf_64bit(_elf) ) \
(_hdr)->e64._elm = _val; \
else \
(_hdr)->e32._elm = _val; \
} while ( 0 )
/* ehdr right after the kernel image (4 byte aligned) */
symbase = elf_round_up(elf, parms->virt_kend);
symtab_addr = maxva = symbase + sizeof(long);
/* Set up Elf header. */
sym_ehdr = (elf_ehdr *)symtab_addr;
maxva = elf_copy_ehdr(elf, sym_ehdr);
elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
elf_hdr_elm(elf, sym_ehdr, e_shoff, elf_uval(elf, elf->ehdr, e_ehsize));
elf_hdr_elm(elf, sym_ehdr, e_phentsize, 0);
elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
/* Copy Elf section headers. */
shdr = maxva;
maxva = elf_copy_shdr(elf, (elf_shdr *)shdr);
for ( i = 0; i < elf_shdr_count(elf); i++ )
{
uint8_t type;
unsigned long tmp;
type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
{
elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
elf_section_start(elf, (elf_shdr *)shdr), (void *)maxva);
tmp = elf_copy_section(elf, (elf_shdr *)shdr, (void *)maxva);
/* Mangled to be based on ELF header location. */
elf_hdr_elm(elf, (elf_shdr *)shdr, sh_offset,
maxva - symtab_addr);
maxva = tmp;
}
shdr += elf_uval(elf, elf->ehdr, e_shentsize);
}
/* Write down the actual sym size. */
p = (char *)symbase;
*(long *)p = maxva - symtab_addr; /* sym size */
#undef elf_ehdr_elm
return 0;
}
static int elf_xen_addr_calc_check(struct elf_binary *elf,
struct elf_dom_parms *parms)
{
@@ -467,13 +374,16 @@ static int elf_xen_addr_calc_check(struct elf_binary *elf,
parms->virt_offset = parms->virt_base - parms->elf_paddr_offset;
parms->virt_kstart = elf->pstart + parms->virt_offset;
parms->virt_kend = elf->pend + parms->virt_offset;
parms->virt_end = parms->virt_kend;
if ( parms->virt_entry == UNSET_ADDR )
parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry);
if ( parms->bsd_symtab )
elf_xen_loadsymtab(elf, parms);
{
elf_parse_bsdsyms(elf, parms->virt_kend);
if ( elf->bsd_symtab_pend )
parms->virt_kend = elf->bsd_symtab_pend + parms->virt_offset;
}
elf_msg(elf, "%s: addresses:\n", __FUNCTION__);
elf_msg(elf, " virt_base = 0x%" PRIx64 "\n", parms->virt_base);
@@ -481,14 +391,12 @@ static int elf_xen_addr_calc_check(struct elf_binary *elf,
elf_msg(elf, " virt_offset = 0x%" PRIx64 "\n", parms->virt_offset);
elf_msg(elf, " virt_kstart = 0x%" PRIx64 "\n", parms->virt_kstart);
elf_msg(elf, " virt_kend = 0x%" PRIx64 "\n", parms->virt_kend);
elf_msg(elf, " virt_end = 0x%" PRIx64 "\n", parms->virt_end);
elf_msg(elf, " virt_entry = 0x%" PRIx64 "\n", parms->virt_entry);
if ( (parms->virt_kstart > parms->virt_kend) ||
(parms->virt_entry < parms->virt_kstart) ||
(parms->virt_entry > parms->virt_kend) ||
(parms->virt_base > parms->virt_kstart) ||
(parms->virt_kend > parms->virt_end) )
(parms->virt_base > parms->virt_kstart) )
{
elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n",
__FUNCTION__);
+99 -33
View File
@@ -10,8 +10,6 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
{
const elf_shdr *shdr;
uint64_t i, count, section, offset;
uint64_t low = -1;
uint64_t high = 0;
if ( !elf_is_elfbinary(image) )
{
@@ -22,14 +20,10 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
memset(elf, 0, sizeof(*elf));
elf->image = image;
elf->size = size;
elf->ehdr = (elf_ehdr *) image;
elf->ehdr = (elf_ehdr *)image;
elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
elf->data = elf->ehdr->e32.e_ident[EI_DATA];
#ifdef VERBOSE
elf_set_verbose(elf);
#endif
/* Sanity check phdr. */
offset = elf_uval(elf, elf->ehdr, e_phoff) +
elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
@@ -60,43 +54,18 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
count = elf_shdr_count(elf);
for ( i = 0; i < count; i++ )
{
const char *sh_symend, *sh_strend;
shdr = elf_shdr_by_index(elf, i);
if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
continue;
elf->sym_tab = shdr;
sh_symend = (const char *)elf_section_end(elf, shdr);
shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
if ( shdr == NULL )
{
elf->sym_tab = NULL;
sh_symend = 0;
continue;
}
elf->sym_strtab = elf_section_start(elf, shdr);
sh_strend = (const char *)elf_section_end(elf, shdr);
if ( low > (unsigned long)elf->sym_tab )
low = (unsigned long)elf->sym_tab;
if ( low > (unsigned long)shdr )
low = (unsigned long)shdr;
if ( high < ((unsigned long)sh_symend) )
high = (unsigned long)sh_symend;
if ( high < ((unsigned long)sh_strend) )
high = (unsigned long)sh_strend;
elf_msg(elf, "%s: shdr: sym_tab=%p size=0x%" PRIx64 "\n",
__FUNCTION__, elf->sym_tab,
elf_uval(elf, elf->sym_tab, sh_size));
elf_msg(elf, "%s: shdr: str_tab=%p size=0x%" PRIx64 "\n",
__FUNCTION__, elf->sym_strtab, elf_uval(elf, shdr, sh_size));
elf->sstart = low;
elf->send = high;
elf_msg(elf, "%s: symbol map: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
__FUNCTION__, elf->sstart, elf->send);
break;
}
return 0;
@@ -115,6 +84,101 @@ void elf_set_verbose(struct elf_binary *elf)
}
#endif
/* Calculate the required additional kernel space for the elf image */
void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
{
uint64_t sz;
const elf_shdr *shdr;
int i, type;
if ( !elf->sym_tab )
return;
pstart = elf_round_up(elf, pstart);
/* Space to store the size of the elf image */
sz = sizeof(uint32_t);
/* Space for the elf and elf section headers */
sz += (elf_uval(elf, elf->ehdr, e_ehsize) +
elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
sz = elf_round_up(elf, sz);
/* Space for the symbol and string tables. */
for ( i = 0; i < elf_shdr_count(elf); i++ )
{
shdr = elf_shdr_by_index(elf, i);
type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
}
elf->bsd_symtab_pstart = pstart;
elf->bsd_symtab_pend = pstart + sz;
}
static void elf_load_bsdsyms(struct elf_binary *elf)
{
elf_ehdr *sym_ehdr;
unsigned long sz;
char *maxva, *symbase, *symtab_addr;
elf_shdr *shdr;
int i, type;
if ( !elf->bsd_symtab_pstart )
return;
#define elf_hdr_elm(_elf, _hdr, _elm, _val) \
do { \
if ( elf_64bit(_elf) ) \
(_hdr)->e64._elm = _val; \
else \
(_hdr)->e32._elm = _val; \
} while ( 0 )
symbase = elf_get_ptr(elf, elf->bsd_symtab_pstart);
symtab_addr = maxva = symbase + sizeof(uint32_t);
/* Set up Elf header. */
sym_ehdr = (elf_ehdr *)symtab_addr;
sz = elf_uval(elf, elf->ehdr, e_ehsize);
memcpy(sym_ehdr, elf->ehdr, sz);
maxva += sz; /* no round up */
elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
elf_hdr_elm(elf, sym_ehdr, e_shoff, elf_uval(elf, elf->ehdr, e_ehsize));
elf_hdr_elm(elf, sym_ehdr, e_phentsize, 0);
elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
/* Copy Elf section headers. */
shdr = (elf_shdr *)maxva;
sz = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
memcpy(shdr, elf->image + elf_uval(elf, elf->ehdr, e_shoff), sz);
maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
for ( i = 0; i < elf_shdr_count(elf); i++ )
{
type = elf_uval(elf, shdr, sh_type);
if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
{
elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
elf_section_start(elf, shdr), maxva);
sz = elf_uval(elf, shdr, sh_size);
memcpy(maxva, elf_section_start(elf, shdr), sz);
/* Mangled to be based on ELF header location. */
elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
}
shdr = (elf_shdr *)((long)shdr +
(long)elf_uval(elf, elf->ehdr, e_shentsize));
}
/* Write down the actual sym size. */
*(uint32_t *)symbase = maxva - symtab_addr;
#undef elf_ehdr_elm
}
void elf_parse_binary(struct elf_binary *elf)
{
const elf_phdr *phdr;
@@ -165,6 +229,8 @@ void elf_load_binary(struct elf_binary *elf)
memcpy(dest, elf->image + offset, filesz);
memset(dest + filesz, 0, memsz - filesz);
}
elf_load_bsdsyms(elf);
}
void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
-30
View File
@@ -238,36 +238,6 @@ int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
}
unsigned long
elf_copy_ehdr(struct elf_binary *elf, void *dest)
{
uint64_t size;
size = elf_uval(elf, elf->ehdr, e_ehsize);
memcpy(dest, elf->ehdr, size);
return elf_round_up(elf, (unsigned long)(dest) + size);
}
unsigned long
elf_copy_shdr(struct elf_binary *elf, void *dest)
{
uint64_t size;
size = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
memcpy(dest, elf->image + elf_uval(elf, elf->ehdr, e_shoff), size);
return elf_round_up(elf, (unsigned long)(dest) + size);
}
unsigned long
elf_copy_section(struct elf_binary *elf, const elf_shdr *shdr, void *dest)
{
uint64_t size;
size = elf_uval(elf, shdr, sh_size);
memcpy(dest, elf_section_start(elf, shdr), size);
return elf_round_up(elf, (unsigned long)(dest) + size);
}
/*
* Local variables:
* mode: C
+11 -3
View File
@@ -91,6 +91,14 @@ custom_param("dma_emergency_pool", parse_dma_emergency_pool);
#define round_pgdown(_p) ((_p)&PAGE_MASK)
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#ifndef NDEBUG
/* Avoid callers relying on allocations returning zeroed pages. */
#define scrub_page(p) memset((p), 0xc2, PAGE_SIZE)
#else
/* For a production build, clear_page() is the fastest way to scrub. */
#define scrub_page(p) clear_page(p)
#endif
static DEFINE_SPINLOCK(page_scrub_lock);
LIST_HEAD(page_scrub_list);
static unsigned long scrub_pages;
@@ -618,13 +626,13 @@ void __init scrub_heap_pages(void)
{
p = page_to_virt(mfn_to_page(mfn));
memguard_unguard_range(p, PAGE_SIZE);
clear_page(p);
scrub_page(p);
memguard_guard_range(p, PAGE_SIZE);
}
else
{
p = map_domain_page(mfn);
clear_page(p);
scrub_page(p);
unmap_domain_page(p);
}
}
@@ -1018,7 +1026,7 @@ static void page_scrub_softirq(void)
pg = list_entry(ent, struct page_info, list);
ent = ent->prev;
p = map_domain_page(page_to_mfn(pg));
clear_page(p);
scrub_page(p);
unmap_domain_page(p);
free_heap_pages(pfn_dom_zone_type(page_to_mfn(pg)), pg, 0);
}
+46
View File
@@ -0,0 +1,46 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright IBM Corp. 2007
*
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
*/
#ifndef _ASM_BOOT_H
#define _ASM_BOOT_H
/* a collection of interfaces used during boot. */
extern void boot_of_init(ulong, ulong);
extern void *boot_of_devtree(void);
extern void boot_of_serial(void *);
extern void boot_of_finish(void);
extern int boot_of_mem_avail(int pos, ulong *startpage, ulong *endpage);
extern void parse_multiboot(ulong tags_addr);
extern void memory_init(void);
extern char *xen_cmdline;
extern ulong dom0_addr;
extern ulong dom0_len;
extern char *dom0_cmdline;
extern ulong initrd_start;
extern ulong initrd_len;
/* From linker script. */
extern char builtin_cmdline[];
#endif
+9 -8
View File
@@ -77,10 +77,10 @@ struct shadow_domain {
int locker; /* processor which holds the lock */
const char *locker_function; /* Func that took it */
unsigned int opt_flags; /* runtime tunable optimizations on/off */
struct list_head pinned_shadows;
struct list_head pinned_shadows;
/* Memory allocation */
struct list_head freelists[SHADOW_MAX_ORDER + 1];
struct list_head freelists[SHADOW_MAX_ORDER + 1];
struct list_head p2m_freelist;
unsigned int total_pages; /* number of pages allocated */
unsigned int free_pages; /* number of pages on freelists */
@@ -116,7 +116,7 @@ struct hap_domain {
spinlock_t lock;
int locker;
const char *locker_function;
struct list_head freelist;
unsigned int total_pages; /* number of pages allocated */
unsigned int free_pages; /* number of pages on freelists */
@@ -131,13 +131,13 @@ struct p2m_domain {
spinlock_t lock;
int locker; /* processor which holds the lock */
const char *locker_function; /* Func that took it */
/* Pages used to construct the p2m */
struct list_head pages;
/* Functions to call to get or free pages for the p2m */
struct page_info * (*alloc_page )(struct domain *d);
void (*free_page )(struct domain *d,
void (*free_page )(struct domain *d,
struct page_info *pg);
/* Highest guest frame that's ever been mapped in the p2m */
@@ -177,6 +177,7 @@ struct paging_domain {
/* log dirty support */
struct log_dirty_domain log_dirty;
};
struct paging_vcpu {
/* Pointers to mode-specific entry points. */
struct paging_mode *mode;
@@ -184,9 +185,9 @@ struct paging_vcpu {
unsigned int translate_enabled:1;
/* HVM guest: last emulate was to a pagetable */
unsigned int last_write_was_pt:1;
/* Translated guest: virtual TLB */
/* Translated guest: virtual TLB */
struct shadow_vtlb *vtlb;
spinlock_t vtlb_lock;
spinlock_t vtlb_lock;
/* paging support extension */
struct shadow_vcpu shadow;
@@ -303,7 +304,7 @@ struct arch_vcpu
* shadow refcounts are in use */
pagetable_t shadow_table[4]; /* (MFN) shadow(s) of guest */
pagetable_t monitor_table; /* (MFN) hypervisor PT (for HVM) */
unsigned long cr3; /* (MA) value to install in HW CR3 */
unsigned long cr3; /* (MA) value to install in HW CR3 */
/* Current LDT details. */
unsigned long shadow_ldt_mapcnt;
+1 -1
View File
@@ -3,7 +3,7 @@
*
* hardware-assisted paging
* Copyright (c) 2007 Advanced Micro Devices (Wei Huang)
*
*
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
@@ -1,45 +0,0 @@
#ifndef __ASM_MACH_MPPARSE_H
#define __ASM_MACH_MPPARSE_H
#include <xen/acpi.h>
extern int parse_unisys_oem(char *oemptr);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
{
if (mpc->mpc_oemptr) {
struct mp_config_oemtable *oem_table =
(struct mp_config_oemtable *)(long)mpc->mpc_oemptr;
if (!strncmp(oem, "UNISYS", 6))
return parse_unisys_oem((char *)oem_table);
}
return 0;
}
static inline int es7000_check_dsdt(void)
{
struct acpi_table_header *header = NULL;
if(!acpi_get_table_header_early(ACPI_DSDT, &header))
acpi_table_print(header, 0);
if (!strncmp(header->oem_id, "UNISYS", 6))
return 1;
return 0;
}
/* Hook from generic ACPI tables.c */
static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
unsigned long oem_addr;
if (!find_unisys_acpi_oem_table(&oem_addr)) {
if (es7000_check_dsdt())
return parse_unisys_oem((char *)oem_addr);
else
return 1;
}
return 0;
}
#endif /* __ASM_MACH_MPPARSE_H */
+5
View File
@@ -240,6 +240,11 @@ static inline void write_efer(__u64 val)
#define MSR_K8_MC4_ADDR 0x412
#define MSR_K8_MC4_MISC 0x413
#define MSR_K8_MC5_CTL 0x414
#define MSR_K8_MC5_STATUS 0x415
#define MSR_K8_MC5_ADDR 0x416
#define MSR_K8_MC5_MISC 0x417
/* Pentium IV performance counter MSRs */
#define MSR_P4_BPU_PERFCTR0 0x300
#define MSR_P4_BPU_PERFCTR1 0x301
+6 -12
View File
@@ -65,12 +65,13 @@ struct elf_binary {
/* loaded to */
char *dest;
uint64_t sstart;
uint64_t send;
uint64_t pstart;
uint64_t pend;
uint64_t reloc_offset;
uint64_t bsd_symtab_pstart;
uint64_t bsd_symtab_pend;
#ifndef __XEN__
/* misc */
FILE *log;
@@ -150,11 +151,6 @@ const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
int elf_is_elfbinary(const void *image);
int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
unsigned long elf_copy_ehdr(struct elf_binary *elf, void *dest);
unsigned long elf_copy_shdr(struct elf_binary *elf, void *dest);
unsigned long elf_copy_section(struct elf_binary *elf,
const elf_shdr *shdr, void *dest);
/* ------------------------------------------------------------------------ */
/* xc_libelf_loader.c */
@@ -171,6 +167,8 @@ void elf_load_binary(struct elf_binary *elf);
void *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
/* ------------------------------------------------------------------------ */
/* xc_libelf_relocate.c */
@@ -221,8 +219,7 @@ struct elf_dom_parms {
/* calculated */
uint64_t virt_offset;
uint64_t virt_kstart;
uint64_t virt_kend; /* end of kernel image */
uint64_t virt_end; /* end of kernel symtab (== virt_kend if none) */
uint64_t virt_kend;
};
static inline void elf_xen_feature_set(int nr, uint32_t * addr)
@@ -245,7 +242,4 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
int elf_xen_parse(struct elf_binary *elf,
struct elf_dom_parms *parms);
int elf_xen_dom_load_binary(struct elf_binary *elf,
struct elf_dom_parms *parms);
#endif /* __XC_LIBELF__ */
+99
View File
@@ -0,0 +1,99 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright IBM Corp. 2006, 2007
*
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
*
*/
#ifndef _MULTIBOOT2_H_
#define _MULTIBOOT2_H_
/* How many bytes from the start of the file we search for the header. */
#define MB2_HEADER_SEARCH 8192
/* The magic field should contain this. */
#define MB2_HEADER_MAGIC 0xe85250d6
/* Passed from the bootloader to the kernel. */
#define MB2_BOOTLOADER_MAGIC 0x36d76289
#include <stdint.h>
#define for_each_tag(_tag, _tags) \
for ((_tag) = (_tags); \
((_tag)->key != MB2_TAG_END && (_tag)->key != 0); \
(_tag) = (void *)(_tag) + (_tag)->len)
typedef uint32_t mb2_word;
struct mb2_header
{
uint32_t magic;
};
struct mb2_tag_header
{
uint32_t key;
uint32_t len;
};
#define MB2_TAG_START 1
struct mb2_tag_start
{
struct mb2_tag_header header;
mb2_word size; /* Total size of all mb2 tags. */
};
#define MB2_TAG_NAME 2
struct mb2_tag_name
{
struct mb2_tag_header header;
char name[1];
};
#define MB2_TAG_MODULE 3
struct mb2_tag_module
{
struct mb2_tag_header header;
mb2_word addr;
mb2_word size;
unsigned char type[36];
unsigned char cmdline[1];
};
#define MB2_TAG_MEMORY 4
struct mb2_tag_memory
{
struct mb2_tag_header header;
mb2_word addr;
mb2_word size;
mb2_word type;
};
#define MB2_TAG_UNUSED 5
struct mb2_tag_unused
{
struct mb2_tag_header header;
};
#define MB2_TAG_END 0xffff
struct mb2_tag_end
{
struct mb2_tag_header header;
};
#endif
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.