mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
087b48842b
57 files changed
+3016
-720
No files matched your search
@@ -123,3 +123,7 @@ cscope:
|
||||
tags:
|
||||
$(all_sources) | xargs ctags
|
||||
|
||||
.PHONY: TAGS
|
||||
TAGS:
|
||||
$(all_sources) | xargs etags
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.")
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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) )
|
||||
{
|
||||
|
||||
@@ -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. "
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
}},
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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__);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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
|
||||