diff --git a/13161_xenapi.patch b/13161_xenapi.patch new file mode 100644 index 0000000..4d95695 --- /dev/null +++ b/13161_xenapi.patch @@ -0,0 +1,34 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1167179881 0 +# Node ID a9a43705f26b0892f722da1b6db8e98db49bad35 +# Parent 6f8d650f3ab1cf23d00baf904abe62fb85b89377 +Fix HVM booting through Xen-API when the kernel is unspecified. + +Signed-off-by: Ewan Mellor + +diff -r 6f8d650f3ab1 -r a9a43705f26b tools/python/xen/xend/XendDomainInfo.py +--- a/tools/python/xen/xend/XendDomainInfo.py Wed Dec 27 00:35:27 2006 +0000 ++++ b/tools/python/xen/xend/XendDomainInfo.py Wed Dec 27 00:38:01 2006 +0000 +@@ -1555,6 +1555,8 @@ class XendDomainInfo: + if boot: + # HVM booting. + self.info['image']['type'] = 'hvm' ++ if not 'devices' in self.info['image']: ++ self.info['image']['devices'] = {} + self.info['image']['devices']['boot'] = boot + elif not blexec and kernel: + # Boot from dom0. Nothing left to do -- the kernel and ramdisk +diff -r 6f8d650f3ab1 -r a9a43705f26b tools/python/xen/xend/image.py +--- a/tools/python/xen/xend/image.py Wed Dec 27 00:35:27 2006 +0000 ++++ b/tools/python/xen/xend/image.py Wed Dec 27 00:38:01 2006 +0000 +@@ -311,6 +311,9 @@ class HVMImageHandler(ImageHandler): + + def configure(self, vmConfig, imageConfig, deviceConfig): + ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig) ++ ++ if not self.kernel: ++ self.kernel = '/usr/lib/xen/boot/hvmloader' + + info = xc.xeninfo() + if 'hvm' not in info['xen_caps']: diff --git a/13201_xenapi.patch b/13201_xenapi.patch new file mode 100644 index 0000000..879d4e1 --- /dev/null +++ b/13201_xenapi.patch @@ -0,0 +1,53 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1167743041 0 +# Node ID 7cd6c032689eca5509a1b8cffaaa50b3f45f5765 +# Parent 711c31232d71608fe4ea9f4f22ca2620d3faf8ff +Don't lose the image settings when rebooting domains. This fixes recent HVM +reboot problems -- we were passing 0 to shadow_mem_control, because Xend was +treating the domain as PV. + +Signed-off-by: Ewan Mellor + +diff -r 711c31232d71 -r 7cd6c032689e tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Tue Jan 02 10:57:50 2007 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Tue Jan 02 13:04:01 2007 +0000 +@@ -299,7 +299,7 @@ class XendConfig(dict): + self._sxp_to_xapi_unsupported(sxp_obj) + elif xapi: + self.update_with_xenapi_config(xapi) +- self._add_xapi_unsupported() ++ self._add_xapi_unsupported(xapi) + elif dominfo: + # output from xc.domain_getinfo + self._dominfo_to_xapi(dominfo) +@@ -728,19 +728,22 @@ class XendConfig(dict): + _set_cfg_if_exists('up_time') + _set_cfg_if_exists('status') # TODO, deprecated + +- def _add_xapi_unsupported(self): ++ def _add_xapi_unsupported(self, xapi_dict): + """Updates the configuration object with entries that are not + officially supported by the Xen API but is required for + the rest of Xend to function. + """ + + # populate image +- hvm = self['HVM_boot'] != '' +- self['image']['type'] = hvm and 'hvm' or 'linux' +- if hvm: +- self['image']['hvm'] = {} +- for xapi, cfgapi in XENAPI_HVM_CFG.items(): +- self['image']['hvm'][cfgapi] = self[xapi] ++ if 'image' in xapi_dict: ++ self['image'].update(xapi_dict['image']) ++ else: ++ hvm = self['HVM_boot'] != '' ++ self['image']['type'] = hvm and 'hvm' or 'linux' ++ if hvm: ++ self['image']['hvm'] = {} ++ for xapi, cfgapi in XENAPI_HVM_CFG.items(): ++ self['image']['hvm'][cfgapi] = self[xapi] + + + def _get_old_state_string(self): diff --git a/13226_xenapi.patch b/13226_xenapi.patch new file mode 100644 index 0000000..32d7aa3 --- /dev/null +++ b/13226_xenapi.patch @@ -0,0 +1,17 @@ +# HG changeset patch +# User Alastair Tse +# Date 1167928289 0 +# Node ID b2ea5ae25a2665d927501a5ebaf4ff38bfd086fc +# Parent 292edc60d2603f744b5408cbf7795365fa8598ce +[XEND] Add VBD_MODE enum from XenAPI. + +Signed-off-by: Alastair Tse + +diff -r 292edc60d260 -r b2ea5ae25a26 tools/python/xen/xend/XendAPIConstants.py +--- a/tools/python/xen/xend/XendAPIConstants.py Thu Jan 04 16:30:20 2007 +0000 ++++ b/tools/python/xen/xend/XendAPIConstants.py Thu Jan 04 16:31:29 2007 +0000 +@@ -73,3 +73,4 @@ XEN_API_VBD_MODE = ['RO', 'RW'] + XEN_API_VBD_MODE = ['RO', 'RW'] + XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral'] + XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised'] ++XEN_API_VBD_TYPE = ['CD', 'Disk'] diff --git a/13235_xenapi.patch b/13235_xenapi.patch new file mode 100644 index 0000000..0a34203 --- /dev/null +++ b/13235_xenapi.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1168000166 0 +# Node ID 36e00d04278d4fbdb0b034355a0e683372211752 +# Parent 68f0d46de55ab1e158c19e7e5890902e05d6f623 +Added permissiveness for floats. + +Signed-off-by: Ewan Mellor + +diff -r 68f0d46de55a -r 36e00d04278d tools/libxen/src/xen_common.c +--- a/tools/libxen/src/xen_common.c Fri Jan 05 11:03:16 2007 +0000 ++++ b/tools/libxen/src/xen_common.c Fri Jan 05 12:29:26 2007 +0000 +@@ -557,8 +557,14 @@ static void parse_into(xen_session *s, x + xmlChar *string = string_from_value(value_node, "double"); + if (string == NULL) + { ++#if PERMISSIVE ++ fprintf(stderr, ++ "Expected a Float from the server, but didn't get one\n"); ++ ((double *)value)[slot] = 0.0; ++#else + server_error( + s, "Expected a Float from the server, but didn't get one"); ++#endif + } + else + { diff --git a/13236_xenapi.patch b/13236_xenapi.patch new file mode 100644 index 0000000..1769e9a --- /dev/null +++ b/13236_xenapi.patch @@ -0,0 +1,72 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1168000232 0 +# Node ID bb8ae710d829d5a7805c5588d8ded2ea393686cf +# Parent 36e00d04278d4fbdb0b034355a0e683372211752 +Treat tags with no type tag inside as if they were strings (as required +by the XML-RPC spec). + +Signed-off-by: Ewan Mellor + +diff -r 36e00d04278d -r bb8ae710d829 tools/libxen/src/xen_common.c +--- a/tools/libxen/src/xen_common.c Fri Jan 05 12:29:26 2007 +0000 ++++ b/tools/libxen/src/xen_common.c Fri Jan 05 12:30:32 2007 +0000 +@@ -373,11 +373,18 @@ static void server_error_2(xen_session * + } + + +-static bool is_container_node(xmlNode *n, char *type) ++static bool is_node(xmlNode *n, char *type) + { + return + n->type == XML_ELEMENT_NODE && +- 0 == strcmp((char *)n->name, type) && ++ 0 == strcmp((char *)n->name, type); ++} ++ ++ ++static bool is_container_node(xmlNode *n, char *type) ++{ ++ return ++ is_node(n, type) && + n->children != NULL && + n->children == n->last && + n->children->type == XML_ELEMENT_NODE; +@@ -390,13 +397,30 @@ static bool is_container_node(xmlNode *n + */ + static xmlChar *string_from_value(xmlNode *n, char *type) + { +- return +- is_container_node(n, "value") && +- 0 == strcmp((char *)n->children->name, type) ? +- (n->children->children == NULL ? +- xmlStrdup(BAD_CAST("")) : +- xmlNodeGetContent(n->children->children)) : +- NULL; ++ /* ++ XYZ is normal, but the XML-RPC spec also ++ allows XYZ where XYZ is to be interpreted as a string. ++ */ ++ ++ if (is_container_node(n, "value") && ++ 0 == strcmp((char *)n->children->name, type)) ++ { ++ return ++ n->children->children == NULL ? ++ xmlStrdup(BAD_CAST("")) : ++ xmlNodeGetContent(n->children->children); ++ } ++ else if (0 == strcmp(type, "string") && is_node(n, "value")) ++ { ++ return ++ n->children == NULL ? ++ xmlStrdup(BAD_CAST("")) : ++ xmlNodeGetContent(n->children); ++ } ++ else ++ { ++ return NULL; ++ } + } + + diff --git a/13577_xenapi.patch b/13577_xenapi.patch new file mode 100644 index 0000000..d2bab76 --- /dev/null +++ b/13577_xenapi.patch @@ -0,0 +1,52 @@ +# HG changeset patch +# User Alastair Tse +# Date 1169640474 0 +# Node ID 4f5772324e679e9794ccd72848023c081d7300da +# Parent 8331aca2f29ca29704f4bafabe0e542f312d6950 +[XEND] Strip suffix from device name and add support for 'VBD.type' + +Signed-off-by: Alastair Tse + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -1040,6 +1040,7 @@ class XendAPI: + 'VDI', + 'device', + 'mode', ++ 'type', + 'driver'] + + VBD_attr_inst = VBD_attr_rw + ['image'] +@@ -1117,6 +1118,11 @@ class XendAPI: + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, + 'driver')) + ++ def VBD_get_type(self, session, vbd_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref, ++ 'type')) ++ + # Xen API: Class VIF + # ---------------------------------------------------------------- + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -1988,6 +1988,14 @@ class XendDomainInfo: + if dev_class == 'vbd': + config['VDI'] = config.get('VDI', '') + config['device'] = config.get('dev', '') ++ if ':' in config['device']: ++ vbd_name, vbd_type = config['device'].split(':', 1) ++ config['device'] = vbd_name ++ if vbd_type == 'cdrom': ++ config['type'] = XEN_API_VBD_TYPE[0] ++ else: ++ config['type'] = XEN_API_VBD_TYPE[1] ++ + config['driver'] = 'paravirtualised' # TODO + config['image'] = config.get('uname', '') + config['io_read_kbs'] = 0.0 diff --git a/13585_xenapi.patch b/13585_xenapi.patch new file mode 100644 index 0000000..d9ad785 --- /dev/null +++ b/13585_xenapi.patch @@ -0,0 +1,451 @@ +# HG changeset patch +# User Alastair Tse +# Date 1169648721 0 +# Node ID bea3d48576c66663e559fbba1bcd9f840a3d1b25 +# Parent 6a54b1d8d1053c4facfef8c3c1da871950a5b29c +[XEND] Add missing Xen API methods + +* Added session.get_all, task.get_by_name_label, + host.get_by_name_label, VM.add_to_otherConfig, + VM.remove_from_otherConfig + +* Added implementations for VM.get_VCPUs_policy, + VM.get_platform_std_vga, VM.get_vm_by_uuid, + VM.get_platform_localtime, VM.get_platform_clock_offset, + VM.get_platform_enable_audio, VM.get_platform_keymap, + VM.get_otherConfig, VM.set_actions_after_shutdown, + VM.set_actions_after_reboot, VM.set_actions_after_suspend, + VM.set_actions_after_crash, VM.set_platform_std_VGA, + VM.set_platform_serial, VM.set_platform_keymap, + VM.set_platform_localtime, VM.set_platform_clock_offset, + VM.set_platform_enable_audio, VM.set_otherConfig, VBD.destroy, + VBD.get_io_read_kbs, VBD.get_io_write_kbs, VBD.get_all, VIF.destroy, + VIF.get_VM, VIF.get_name, VIF.get_MTU, VIF.get_MAC, VIF.get_type, + VIF.get_device, VIF.get_io_read_kbs, VIF.get_io_write_kbs, + VIF.get_all, VTPM.destroy, VTPM.get_all + +* Save devid of a device on creation in XendDomainInfo + +Signed-off-by: Alastair Tse + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -406,7 +406,6 @@ class XendAPI: + return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED) + session_login_with_password.api = 'session.login_with_password' + +- + # object methods + def session_logout(self, session): + auth_manager().logout(session) +@@ -417,7 +416,9 @@ class XendAPI: + record = {'this_host': XendNode.instance().uuid, + 'this_user': auth_manager().get_user(session)} + return xen_api_success(record) +- ++ def session_get_all(self): ++ return xen_api_error(XEND_ERROR_UNSUPPORTED) ++ + # attributes (ro) + def session_get_this_host(self, session): + return xen_api_success(XendNode.instance().uuid) +@@ -504,6 +505,11 @@ class XendAPI: + return xen_api_success((XendNode.instance().uuid,)) + def host_create(self, session, struct): + return xen_api_error(XEND_ERROR_UNSUPPORTED) ++ def host_get_by_name_label(self, session, name): ++ if XendNode.instance().name == name: ++ return xen_api_success((XendNode.instance().uuid,)) ++ return xen_api_success([]) ++ + + # Xen API: Class Host_CPU + # ---------------------------------------------------------------- +@@ -514,9 +520,6 @@ class XendAPI: + 'utilisation'] + + # attributes +- def host_cpu_get_uuid(self, session, host_cpu_ref): +- uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref) +- return xen_api_success(uuid) + def host_cpu_get_host(self, session, host_cpu_ref): + return xen_api_success(XendNode.instance().uuid) + def host_cpu_get_features(self, session, host_cpu_ref): +@@ -752,7 +755,7 @@ class XendAPI: + + def VM_get_VCPUs_policy(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() # need to access scheduler ++ return dom.get_vcpus_policy() + + def VM_get_VCPUs_params(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +@@ -776,7 +779,7 @@ class XendAPI: + + def VM_get_actions_after_suspend(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success(dom.get_on_suspend()) ++ return xen_api_success(dom.get_on_suspend()) + + def VM_get_actions_after_crash(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +@@ -802,31 +805,30 @@ class XendAPI: + + def VM_get_platform_std_VGA(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_std_vga()) + + def VM_get_platform_serial(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_serial()) + + def VM_get_platform_localtime(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_localtime()) + + def VM_get_platform_clock_offset(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_clock_offset()) + + def VM_get_platform_enable_audio(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_enable_audio()) + + def VM_get_platform_keymap(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return xen_api_success(dom.get_platform_keymap()) + + def VM_get_otherConfig(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return self.VM_get('otherConfig', session, vm_ref) + + def VM_set_name_label(self, session, vm_ref, label): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +@@ -870,20 +872,24 @@ class XendAPI: + return xen_api_success_void() + + def VM_set_actions_after_shutdown(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ if action not in XEN_API_ON_NORMAL_EXIST: ++ return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) ++ return self.VM_set('actions_after_shutdown', session, vm_ref, action) + + def VM_set_actions_after_reboot(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ if action not in XEN_API_ON_NORMAL_EXIST: ++ return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) ++ return self.VM_set('actions_after_reboot', session, vm_ref, action) + + def VM_set_actions_after_suspend(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ if action not in XEN_API_ON_NORMAL_EXIT: ++ return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) ++ return self.VM_set('actions_after_suspend', session, vm_ref, action) + + def VM_set_actions_after_crash(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ if action not in XEN_API_ON_CRASH_BEHAVIOUR: ++ return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref]) ++ return self.VM_set('actions_after_crash', session, vm_ref, action) + + def VM_set_HVM_boot(self, session, vm_ref, value): + return self.VM_set('HVM_boot', session, vm_ref, value) +@@ -903,29 +909,26 @@ class XendAPI: + def VM_set_PV_bootloader_args(self, session, vm_ref, value): + return self.VM_set('PV_bootloader_args', session, vm_ref, value) + +- def VM_set_platform_std_VGA(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() +- +- def VM_set_platform_serial(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ def VM_set_platform_std_VGA(self, session, vm_ref, value): ++ return self.VM_set('platform_std_vga', session, vm_ref, value) + +- def VM_set_platform_localtime(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ def VM_set_platform_serial(self, session, vm_ref, value): ++ return self.VM_set('platform_serial', session, vm_ref, value) ++ ++ def VM_set_platform_keymap(self, session, vm_ref, value): ++ return self.VM_set('platform_keymap', session, vm_ref, value) ++ ++ def VM_set_platform_localtime(self, session, vm_ref, value): ++ return self.VM_set('platform_localtime', session, vm_ref, value) + +- def VM_set_platform_clock_offset(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ def VM_set_platform_clock_offset(self, session, vm_ref, value): ++ return self.VM_set('platform_clock_offset', session, vm_ref, value) + +- def VM_set_platform_enable_audio(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ def VM_set_platform_enable_audio(self, session, vm_ref, value): ++ return self.VM_set('platform_enable_audio', session, vm_ref, value) + +- def VM_set_otherConfig(self, session, vm_ref): +- dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_success_void() ++ def VM_set_otherConfig(self, session, vm_ref, value): ++ return self.VM_set('otherconfig', session, vm_ref, value) + + # class methods + def VM_get_all(self, session): +@@ -995,7 +998,7 @@ class XendAPI: + 'platform_keymap': xeninfo.get_platform_keymap(), + 'PCI_bus': xeninfo.get_pci_bus(), + 'tools_version': xeninfo.get_tools_version(), +- 'otherConfig': xeninfo.get_other_config() ++ 'otherConfig': xeninfo.info.get('otherconfig'), + } + return xen_api_success(record) + +@@ -1030,8 +1033,6 @@ class XendAPI: + + # Xen API: Class VBD + # ---------------------------------------------------------------- +- # Note: accepts a non-API standard 'image' attribute to emulate +- # regular xm created VBDs + + VBD_attr_ro = ['image', + 'io_read_kbs', +@@ -1097,6 +1098,16 @@ class XendAPI: + xendom.managed_config_save(dom) + return xen_api_success(vbd_ref) + ++ ++ def VBD_destroy(self, session, vbd_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref) ++ if not vm: ++ return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref]) ++ ++ vm.destroy_vbd(vbd_ref) ++ return xen_api_success_void() ++ + # attributes (rw) + def VBD_get_VM(self, session, vbd_ref): + xendom = XendDomain.instance() +@@ -1123,6 +1134,18 @@ class XendAPI: + return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref, + 'type')) + ++ def VBD_get_io_read_kbs(self, session, vbd_ref): ++ return xen_api_todo() ++ ++ def VBD_get_io_write_kbs(self, session, vbd_ref): ++ return xen_api_todo() ++ ++ def VBD_get_all(self, session): ++ xendom = XendDomain.instance() ++ vbds = [d.get_vbds() for d in XendDomain.instance().list('all')] ++ vbds = reduce(lambda x, y: x + y, vbds) ++ return xen_api_success(vbds) ++ + # Xen API: Class VIF + # ---------------------------------------------------------------- + +@@ -1173,6 +1196,59 @@ class XendAPI: + return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + + ++ def VIF_destroy(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) ++ if not vm: ++ return xen_api_error(['VIF_HANDLE_INVALID', vif_ref]) ++ ++ vm.destroy_vif(vif_ref) ++ return xen_api_success_void() ++ ++ # getters/setters ++ def VIF_get_VM(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) ++ return xen_api_success(vm.get_uuid()) ++ ++ def VIF_get_name(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, ++ 'name')) ++ def VIF_get_MTU(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, ++ 'MTU')) ++ def VIF_get_MAC(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, ++ 'MAC')) ++ ++ def VIF_get_type(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, ++ 'type')) ++ ++ ++ def VIF_get_device(self, session, vif_ref): ++ xendom = XendDomain.instance() ++ return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, ++ 'device')) ++ ++ ++ def VIF_get_io_read_kbs(self, session, vif_ref): ++ return xen_api_todo() ++ ++ def VIF_get_io_write_kbs(self, session, vif_ref): ++ return xen_api_todo() ++ ++ def VIF_get_all(self, session): ++ xendom = XendDomain.instance() ++ vifs = [d.get_vifs() for d in XendDomain.instance().list('all')] ++ vifs = reduce(lambda x, y: x + y, vifs) ++ return xen_api_success(vifs) ++ ++ + # Xen API: Class VDI + # ---------------------------------------------------------------- + VDI_attr_ro = ['VBDs', +@@ -1401,6 +1477,15 @@ class XendAPI: + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM')) + ++ def VTPM_destroy(self, session, vtpm_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) ++ if not vm: ++ return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref]) ++ ++ vm.destroy_vtpm(vtpm_ref) ++ return xen_api_success_void() ++ + # class methods + def VTPM_create(self, session, vtpm_struct): + xendom = XendDomain.instance() +@@ -1415,6 +1500,12 @@ class XendAPI: + else: + return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + ++ def VTPM_get_all(self, session): ++ xendom = XendDomain.instance() ++ vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')] ++ vtpms = reduce(lambda x, y: x + y, vtpms) ++ return xen_api_success(vtpms) ++ + + # Xen API: Class SR + # ---------------------------------------------------------------- +@@ -1451,9 +1542,6 @@ class XendAPI: + def SR_create(self, session): + return xen_api_error(XEND_ERROR_UNSUPPORTED) + +- def SR_get_by_uuid(self, session): +- return xen_api_success(XendNode.instance().get_sr().uuid) +- + # Class Methods + def SR_clone(self, session, sr_ref): + return xen_api_error(XEND_ERROR_UNSUPPORTED) +Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +@@ -954,6 +954,8 @@ class XendConfig(dict): + # dev_info['vifname'] = cfg_xenapi.get('device') + if cfg_xenapi.get('type'): + dev_info['type'] = cfg_xenapi.get('type') ++ if cfg_xenapi.get('name'): ++ dev_info['name'] = cfg_xenapi.get('name') + + dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -525,8 +525,6 @@ class XendDomainInfo: + + return self.getDeviceController(deviceClass).destroyDevice(devid, force) + +- +- + def getDeviceSxprs(self, deviceClass): + if self.state == DOM_STATE_RUNNING: + return self.getDeviceController(deviceClass).sxprs() +@@ -1215,7 +1213,12 @@ class XendDomainInfo: + devclass, config = self.info['devices'][dev_uuid] + if devclass in XendDevices.valid_devices(): + log.info("createDevice: %s : %s" % (devclass, scrub_password(config))) +- self._createDevice(devclass, config) ++ dev_uuid = config.get('uuid') ++ devid = self._createDevice(devclass, config) ++ ++ # store devid in XendConfig for caching reasons ++ if dev_uuid in self.info['devices']: ++ self.info['devices'][dev_uuid][1]['devid'] = devid + + if self.image: + self.image.createDeviceModel() +@@ -1887,11 +1890,9 @@ class XendDomainInfo: + def get_platform_keymap(self): + return self.info.get('platform_keymap', '') + def get_pci_bus(self): +- return '' # TODO ++ return self.info.get('pci_bus', '') + def get_tools_version(self): +- return {} # TODO +- def get_other_config(self): +- return {} # TODO ++ return self.info.get('tools_version', {}) + + def get_on_shutdown(self): + after_shutdown = self.info.get('action_after_shutdown') +@@ -2112,6 +2113,32 @@ class XendDomainInfo: + + return dev_uuid + ++ def destroy_device_by_uuid(self, dev_type, dev_uuid): ++ if dev_uuid not in self.info['devices']: ++ raise XendError('Device does not exist') ++ ++ try: ++ if self.state == XEN_API_VM_POWER_STATE_RUNNING: ++ _, config = self.info['devices'][dev_uuid] ++ devid = config.get('devid') ++ if devid != None: ++ self.getDeviceController(dev_type).destroyDevice(devid, force = False) ++ else: ++ raise XendError('Unable to get devid for device: %s:%s' % ++ (dev_type, dev_uuid)) ++ finally: ++ del self.info['devices'][dev_uuid] ++ self.info['%s_refs' % dev_type].remove(dev_uuid) ++ ++ def destroy_vbd(self, dev_uuid): ++ self.destroy_device_by_uuid('vbd', dev_uuid) ++ ++ def destroy_vif(self, dev_uuid): ++ self.destroy_device_by_uuid('vif', dev_uuid) ++ ++ def destroy_vtpm(self, dev_uuid): ++ self.destroy_device_by_uuid('vtpm', dev_uuid) ++ + def has_device(self, dev_class, dev_uuid): + return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) + diff --git a/13615_xenapi.patch b/13615_xenapi.patch new file mode 100644 index 0000000..b18a20f --- /dev/null +++ b/13615_xenapi.patch @@ -0,0 +1,151 @@ +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -412,8 +412,11 @@ class HVMImageHandler(ImageHandler): + + # Handle booleans gracefully + if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']: +- if v != None: v = int(v) +- if v: ret.append("-%s" % a) ++ try: ++ if v != None: v = int(v) ++ if v: ret.append("-%s" % a) ++ except (ValueError, TypeError): ++ pass # if we can't convert it to a sane type, ignore it + else: + if v: + ret.append("-%s" % a) +Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +@@ -106,7 +106,6 @@ XENAPI_HVM_CFG = { + 'platform_std_vga': 'stdvga', + 'platform_serial' : 'serial', + 'platform_localtime': 'localtime', +- 'platform_enable_audio': 'soundhw', + 'platform_keymap' : 'keymap', + } + +@@ -248,17 +247,19 @@ LEGACY_IMAGE_HVM_DEVICES_CFG = [ + ('boot', str), + ('fda', str), + ('fdb', str), +- ('isa', str), ++ ('isa', int), + ('keymap', str), +- ('localtime', str), ++ ('localtime', int), + ('serial', str), + ('stdvga', int), + ('soundhw', str), +- ('usb', str), ++ ('usb', int), + ('usbdevice', str), + ('vcpus', int), + ] + ++LEGACY_DM = '/usr/lib/xen/bin/qemu-dm' ++ + ## + ## Config Choices + ## +@@ -731,9 +732,18 @@ class XendConfig(dict): + hvm = self['HVM_boot'] != '' + self['image']['type'] = hvm and 'hvm' or 'linux' + if hvm: +- self['image']['hvm'] = {} ++ self['image']['hvm'] = {'devices': {}} + for xapi, cfgapi in XENAPI_HVM_CFG.items(): +- self['image']['hvm'][cfgapi] = self[xapi] ++ if xapi in self: ++ self['image']['hvm']['devices'][cfgapi] = self[xapi] ++ ++ # currently unsupported options ++ self['image']['hvm']['device_model'] = LEGACY_DM ++ self['image']['vnc'] = 0 ++ self['image']['hvm']['pae'] = 1 ++ ++ if self['platform_enable_audio']: ++ self['image']['hvm']['devices']['soundhw'] = 'sb16' + + + def _get_old_state_string(self): +@@ -946,7 +956,8 @@ class XendConfig(dict): + return dev_uuid + + if cfg_xenapi: +- dev_info = {} ++ dev_info = {} ++ dev_uuid = '' + if dev_type == 'vif': + if cfg_xenapi.get('MAC'): # don't add if blank + dev_info['mac'] = cfg_xenapi.get('MAC') +@@ -964,7 +975,6 @@ class XendConfig(dict): + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vif_refs'].append(dev_uuid) +- return dev_uuid + + elif dev_type in ('vbd', 'tap'): + if dev_type == 'vbd': +@@ -986,7 +996,6 @@ class XendConfig(dict): + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vbd_refs'].append(dev_uuid) +- return dev_uuid + + elif dev_type in ('vtpm'): + if cfg_xenapi.get('type'): +@@ -996,9 +1005,12 @@ class XendConfig(dict): + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vtpm_refs'].append(dev_uuid) +- return dev_uuid + ++ return dev_uuid ++ ++ # no valid device to add + return '' ++ + + def device_update(self, dev_uuid, cfg_sxp): + """Update an existing device with the new configuration. +@@ -1094,13 +1106,18 @@ class XendConfig(dict): + if 'hvm' in self['image']: + for arg, conv in LEGACY_IMAGE_HVM_CFG: + if self['image']['hvm'].get(arg): +- image.append([arg, self['image']['hvm'][arg]]) ++ image.append([arg, conv(self['image']['hvm'][arg])]) + + if 'hvm' in self['image'] and 'devices' in self['image']['hvm']: + for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG: +- if self['image']['hvm']['devices'].get(arg): +- image.append([arg, +- self['image']['hvm']['devices'][arg]]) ++ val = self['image']['hvm']['devices'].get(arg) ++ if val != None: ++ try: ++ if conv: val = conv(val) ++ except (ValueError, TypeError): ++ if type(val) == bool: val = int(val) ++ ++ image.append([arg, val]) + + return image + +@@ -1144,8 +1161,11 @@ class XendConfig(dict): + for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG: + val = sxp.child_value(image_sxp, arg, None) + if val != None: +- image_hvm_devices[arg] = conv(val) +- ++ try: ++ image_hvm_devices[arg] = conv(val) ++ except (ValueError, TypeError): ++ image_hvm_devices[arg] = val ++ + if image_hvm or image_hvm_devices: + image['hvm'] = image_hvm + image['hvm']['devices'] = image_hvm_devices diff --git a/13616_xenapi.patch b/13616_xenapi.patch new file mode 100644 index 0000000..41674ef --- /dev/null +++ b/13616_xenapi.patch @@ -0,0 +1,309 @@ +Index: xen-3.0.4-testing/tools/python/xen/xend/server/DevController.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/server/DevController.py ++++ xen-3.0.4-testing/tools/python/xen/xend/server/DevController.py +@@ -75,7 +75,7 @@ class DevController: + + def __init__(self, vm): + self.vm = vm +- ++ self.hotplug = True + + def createDevice(self, config): + """Trigger the creation of a device with the given configuration. +@@ -151,6 +151,9 @@ class DevController: + + def waitForDevice(self, devid): + log.debug("Waiting for %s.", devid) ++ ++ if not self.hotplug: ++ return + + status = self.waitForBackend(devid) + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPIConstants.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPIConstants.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPIConstants.py +@@ -74,3 +74,4 @@ XEN_API_VBD_MODE = ['RO', 'RW'] + XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral'] + XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised'] + XEN_API_VBD_TYPE = ['CD', 'Disk'] ++XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp'] +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -227,6 +227,27 @@ def valid_vtpm(func): + + return check_vtpm_ref + ++def valid_console(func): ++ """Decorator to verify if console_ref is valid before calling method. ++ ++ @param func: function with params: (self, session, console_ref, ...) ++ @rtype: callable object ++ """ ++ def check_console_ref(self, session, console_ref, *args, **kwargs): ++ xendom = XendDomain.instance() ++ if type(console_ref) == type(str()) and \ ++ xendom.is_valid_dev('console', console_ref): ++ return func(self, session, console_ref, *args, **kwargs) ++ else: ++ return {'Status': 'Failure', ++ 'ErrorDescription': ('ECONSOLEINVALID', 'Console Invalid')} ++ ++ # make sure we keep the 'api' attribute ++ if hasattr(func, 'api'): ++ check_console_ref.api = func.api ++ ++ return check_console_ref ++ + def valid_sr(func): + """Decorator to verify if sr_ref is valid before calling + method. +@@ -299,6 +320,7 @@ class XendAPI: + 'VIF': (valid_vif, session_required), + 'VDI': (valid_vdi, session_required), + 'VTPM':(valid_vtpm, session_required), ++ 'console':(valid_console, session_required), + 'SR': (valid_sr, session_required)} + + # Cheat methods +@@ -719,14 +741,18 @@ class XendAPI: + def VM_get_VTPMs(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return xen_api_success(dom.get_vtpms()) ++ ++ def VM_get_consoles(self, session, vm_ref): ++ dom = XendDomain.instance().get_vm_by_uuid(vm_ref) ++ return xen_api_success(dom.get_consoles()) + + def VM_get_PCI_bus(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() # unsupported by xc ++ return dom.get_pci_bus() + + def VM_get_tools_version(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) +- return xen_api_todo() ++ return dom.get_tools_version() + + # attributes (rw) + def VM_get_name_label(self, session, vm_ref): +@@ -1507,6 +1533,55 @@ class XendAPI: + return xen_api_success(vtpms) + + ++ # Xen API: Class console ++ # ---------------------------------------------------------------- ++ ++ ++ console_attr_ro = ['uri', 'protocol', 'VM'] ++ console_attr_rw = [] ++ ++ def console_get_all(self, session): ++ xendom = XendDomain.instance() ++ cons = [d.get_consoles() for d in XendDomain.instance().list('all')] ++ cons = reduce(lambda x, y: x + y, cons) ++ return xen_api_success(cons) ++ ++ def console_get_uri(self, session, console_ref): ++ return xen_api_success(xendom.get_dev_property_by_uuid('console', ++ console_ref, ++ 'uri')) ++ ++ def console_get_protocol(self, session, console_ref): ++ return xen_api_success(xendom.get_dev_property_by_uuid('console', ++ console_ref, ++ 'protocol')) ++ ++ def console_get_VM(self, session, console_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('console', console_ref) ++ return xen_api_success(vm.get_uuid()) ++ ++ # object methods ++ def console_get_record(self, session, console_ref): ++ xendom = XendDomain.instance() ++ vm = xendom.get_vm_with_dev_uuid('console', console_ref) ++ if not vm: ++ return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref]) ++ cfg = vm.get_dev_xenapi_config('console', console_ref) ++ if not cfg: ++ return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref]) ++ ++ valid_console_keys = self.console_attr_ro + self.console_attr_rw + \ ++ self.Base_attr_ro + self.Base_attr_rw ++ ++ return_cfg = {} ++ for k in cfg.keys(): ++ if k in valid_console_keys: ++ return_cfg[k] = cfg[k] ++ ++ return xen_api_success(return_cfg) ++ ++ + # Xen API: Class SR + # ---------------------------------------------------------------- + SR_attr_ro = ['VDIs', +Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +@@ -900,8 +900,7 @@ class XendConfig(dict): + if target == None: + target = self + +- if dev_type not in XendDevices.valid_devices() and \ +- dev_type not in XendDevices.pseudo_devices(): ++ if dev_type not in XendDevices.valid_devices(): + raise XendConfigError("XendConfig: %s not a valid device type" % + dev_type) + +@@ -909,10 +908,10 @@ class XendConfig(dict): + raise XendConfigError("XendConfig: device_add requires some " + "config.") + +- if cfg_sxp: +- log.debug("XendConfig.device_add: %s" % str(cfg_sxp)) +- if cfg_xenapi: +- log.debug("XendConfig.device_add: %s" % str(cfg_xenapi)) ++ #if cfg_sxp: ++ # log.debug("XendConfig.device_add: %s" % str(cfg_sxp)) ++ #if cfg_xenapi: ++ # log.debug("XendConfig.device_add: %s" % str(cfg_xenapi)) + + if cfg_sxp: + if sxp.child0(cfg_sxp) == 'device': +@@ -952,6 +951,11 @@ class XendConfig(dict): + target['vbd_refs'] = [] + if dev_uuid not in target['vbd_refs']: + target['vbd_refs'].append(dev_uuid) ++ elif dev_type in ('console',): ++ if 'console_refs' not in target: ++ target['console_refs'] = [] ++ if dev_uuid not in target['console_refs']: ++ target['console_refs'].append(dev_uuid) + + return dev_uuid + +@@ -1012,6 +1016,25 @@ class XendConfig(dict): + return '' + + ++ def console_add(self, protocol, uri): ++ dev_uuid = uuid.createString() ++ dev_info = { ++ 'uuid': dev_uuid, ++ 'protocol': protocol, ++ 'uri': uri ++ } ++ if 'devices' not in self: ++ self['devices'] = {} ++ ++ self['devices'][dev_uuid] = ('console', dev_info) ++ self['console_refs'].append(dev_uuid) ++ return dev_info ++ ++ def console_get_all(self, protocol): ++ consoles = [dinfo for dtype, dinfo in self['devices'].values() ++ if dtype == 'console'] ++ return [c for c in consoles if c.get('protocol') == protocol] ++ + def device_update(self, dev_uuid, cfg_sxp): + """Update an existing device with the new configuration. + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDevices.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDevices.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDevices.py +@@ -21,6 +21,7 @@ + + from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif + from xen.xend.server.BlktapController import BlktapController ++from xen.xend.server.ConsoleController import ConsoleController + + class XendDevices: + """ An ugly halfway point between the module local device name +@@ -43,6 +44,7 @@ class XendDevices: + 'tap': BlktapController, + 'vfb': vfbif.VfbifController, + 'vkbd': vfbif.VkbdifController, ++ 'console': ConsoleController, + } + + #@classmethod +@@ -51,11 +53,6 @@ class XendDevices: + valid_devices = classmethod(valid_devices) + + #@classmethod +- def pseudo_devices(cls): +- return ['console'] +- pseudo_devices = classmethod(pseudo_devices) +- +- #@classmethod + def make_controller(cls, name, domain): + """Factory function to make device controllers per domain. + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -680,6 +680,29 @@ class XendDomainInfo: + for device in devices: + self.info.device_add(device[0], cfg_sxp = device) + ++ self._update_consoles() ++ ++ def _update_consoles(self): ++ if self.domid == None or self.domid == 0: ++ return ++ ++ # Update VT100 port if it exists ++ self.console_port = self.readDom('console/port') ++ if self.console_port is not None: ++ serial_consoles = self.info.console_get_all('vt100') ++ if not serial_consoles: ++ cfg = self.info.console_add('vt100', self.console_port) ++ self._createDevice('console', cfg) ++ ++ # Update VNC port if it exists ++ vnc_port = self.readDom('console/vnc-port') ++ if vnc_port is not None: ++ vnc_consoles = self.info.console_get_all('rfb') ++ if not vnc_consoles: ++ cfg = self.info.console_add('rfb', 'localhost:%s' % ++ str(vnc_port)) ++ self._createDevice('console', cfg) ++ + # + # Function to update xenstore /vm/* + # +@@ -1825,7 +1848,8 @@ class XendDomainInfo: + # TODO: we should eventually get rid of old_dom_states + + self.info.update_config(info) +- ++ self._update_consoles() ++ + if refresh: + self.refreshShutdown(info) + +@@ -1837,11 +1861,11 @@ class XendDomainInfo: + ignore_devices = ignore_store, + legacy_only = legacy_only) + +- if not ignore_store and self.dompath: +- vnc_port = self.readDom('console/vnc-port') +- if vnc_port is not None: +- result.append(['device', +- ['console', ['vnc-port', str(vnc_port)]]]) ++ #if not ignore_store and self.dompath: ++ # vnc_port = self.readDom('console/vnc-port') ++ # if vnc_port is not None: ++ # result.append(['device', ++ # ['console', ['vnc-port', str(vnc_port)]]]) + + return result + diff --git a/13628_xenapi.patch b/13628_xenapi.patch new file mode 100644 index 0000000..5f82f22 --- /dev/null +++ b/13628_xenapi.patch @@ -0,0 +1,42 @@ +# HG changeset patch +# User Alastair Tse +# Date 1169779475 0 +# Node ID ba3ec84c9423a4eb7f7a4c1de052f9e935d17891 +# Parent 9d1d9877131de3aec3d56b277c03075d7f63f3a1 +[XEND] Add missing ConsoleController.py + +Signed-off-by: Alastair Tse + +diff -r 9d1d9877131d -r ba3ec84c9423 tools/python/xen/xend/server/ConsoleController.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/tools/python/xen/xend/server/ConsoleController.py Fri Jan 26 02:44:35 2007 +0000 +@@ -0,0 +1,29 @@ ++from xen.xend.server.DevController import DevController ++from xen.xend.XendLogging import log ++ ++from xen.xend.XendError import VmError ++ ++class ConsoleController(DevController): ++ """A dummy controller for us to represent serial and vnc ++ console devices with persistent UUIDs. ++ """ ++ ++ valid_cfg = ['uri', 'uuid', 'protocol'] ++ ++ def __init__(self, vm): ++ DevController.__init__(self, vm) ++ self.hotplug = False ++ ++ def getDeviceDetails(self, config): ++ back = dict([(k, config[k]) for k in self.valid_cfg if k in config]) ++ return (self.allocateDeviceID(), back, {}) ++ ++ ++ def getDeviceConfiguration(self, devid): ++ result = DevController.getDeviceConfiguration(self, devid) ++ devinfo = self.readBackend(devid, *self.valid_cfg) ++ config = dict(zip(self.valid_cfg, devinfo)) ++ config = dict([(key, val) for key, val in config.items() ++ if val != None]) ++ return config ++ diff --git a/13630-domctl.patch b/13630-domctl.patch new file mode 100644 index 0000000..59ff9d2 --- /dev/null +++ b/13630-domctl.patch @@ -0,0 +1,93 @@ +# HG changeset patch +# User kaf24@localhost.localdomain +# Node ID e0291e3ed603f5437d1e88c7b746b6617346792c +# Parent 2f8a7e5fd8bab112208c7cf51941aaa79afc615f +32-on-64: New set_address_size domctl for switching to compat mode. +From: Gerd Hoffmann +Signed-off-by: Keir Fraser + +Index: xen-3.0.4-testing/xen/arch/x86/domctl.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/domctl.c ++++ xen-3.0.4-testing/xen/arch/x86/domctl.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -293,6 +294,46 @@ _long arch_do_domctl( + } + break; + ++ case XEN_DOMCTL_set_address_size: ++ { ++ struct domain *d; ++ ++ ret = -ESRCH; ++ if ( (d = find_domain_by_id(domctl->domain)) == NULL ) ++ break; ++ ++ switch ( domctl->u.address_size.size ) ++ { ++#ifdef CONFIG_COMPAT ++ case 32: ++ ret = switch_compat(d); ++ break; ++ case 64: ++ ret = switch_native(d); ++ break; ++#endif ++ default: ++ ret = (domctl->u.address_size.size == BITS_PER_LONG) ? 0 : -EINVAL; ++ break; ++ } ++ ++ put_domain(d); ++ } ++ ++ case XEN_DOMCTL_get_address_size: ++ { ++ struct domain *d; ++ ++ ret = -ESRCH; ++ if ( (d = find_domain_by_id(domctl->domain)) == NULL ) ++ break; ++ ++ domctl->u.address_size.size = BITS_PER_GUEST_LONG(d); ++ ++ ret = 0; ++ put_domain(d); ++ } ++ + default: + ret = -ENOSYS; + break; +Index: xen-3.0.4-testing/xen/include/public/domctl.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/public/domctl.h ++++ xen-3.0.4-testing/xen/include/public/domctl.h +@@ -387,6 +387,13 @@ struct xen_domctl_settimeoffset { + typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; + DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); + ++#define XEN_DOMCTL_set_address_size 35 ++#define XEN_DOMCTL_get_address_size 36 ++typedef struct xen_domctl_address_size { ++ uint32_t size; ++} xen_domctl_address_size_t; ++DEFINE_XEN_GUEST_HANDLE(xen_domctl_address_size_t); ++ + #define XEN_DOMCTL_real_mode_area 26 + struct xen_domctl_real_mode_area { + uint32_t log; /* log2 of Real Mode Area size */ +@@ -423,6 +430,7 @@ struct xen_domctl { + struct xen_domctl_arch_setup arch_setup; + struct xen_domctl_settimeoffset settimeoffset; + struct xen_domctl_real_mode_area real_mode_area; ++ struct xen_domctl_address_size address_size; + uint8_t pad[128]; + } u; + }; diff --git a/13655_xenapi.patch b/13655_xenapi.patch new file mode 100644 index 0000000..db2bc2f --- /dev/null +++ b/13655_xenapi.patch @@ -0,0 +1,19 @@ +# HG changeset patch +# User kaf24@localhost.localdomain +# Date 1169977642 0 +# Node ID fbe161b1af160a605878c7f18c42f4e1a9d1e55f +# Parent 47e26ced172a971f7d347d367e7b29b9741ca9f6 +To avoid problems (hang) when doing migration, the Console Controller +needs to implement a (dummy) migrate method. + +Signed-off-by: Stefan Berger + +diff -r 47e26ced172a -r fbe161b1af16 tools/python/xen/xend/server/ConsoleController.py +--- a/tools/python/xen/xend/server/ConsoleController.py Sun Jan 28 09:46:09 2007 +0000 ++++ b/tools/python/xen/xend/server/ConsoleController.py Sun Jan 28 09:47:22 2007 +0000 +@@ -27,3 +27,5 @@ class ConsoleController(DevController): + if val != None]) + return config + ++ def migrate(self, deviceConfig, network, dst, step, domName): ++ return 0 diff --git a/13689_xenapi.patch b/13689_xenapi.patch new file mode 100644 index 0000000..d488c98 --- /dev/null +++ b/13689_xenapi.patch @@ -0,0 +1,951 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170029140 0 +# Node ID bb15af2c2b4a52ef8a3ce9646507b956e6eae322 +# Parent 9db1847845d695f28cf59010fd7c0837811a8e1d +Remove VBD.driver, VIF.type, VIF.name, VTPM.driver. This modelling was never +correct, and the values are best left implicit. + +Signed-off-by: Ewan Mellor + +Index: xen-3.0.4-testing/docs/xen-api/xenapi-datamodel.tex +=================================================================== +--- xen-3.0.4-testing.orig/docs/xen-api/xenapi-datamodel.tex ++++ xen-3.0.4-testing/docs/xen-api/xenapi-datamodel.tex +@@ -274,16 +274,6 @@ The following enumeration types are used + \end{longtable} + + \vspace{1cm} +-\begin{longtable}{|ll|} +-\hline +-{\tt enum driver\_type} & \\ +-\hline +-\hspace{0.5cm}{\tt ioemu} & use hardware emulation \\ +-\hspace{0.5cm}{\tt paravirtualised} & use paravirtualised driver \\ +-\hline +-\end{longtable} +- +-\vspace{1cm} + + \newpage + \section{Class: session} +@@ -5950,8 +5940,6 @@ references to objects with match names + Quals & Field & Type & Description \\ + \hline + $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ +-$\mathit{RW}$ & {\tt name} & string & human-readable name of the interface \\ +-$\mathit{RW}$ & {\tt type} & driver\_type & interface type \\ + $\mathit{RW}$ & {\tt device} & string & name of network device as exposed to guest e.g. eth0 \\ + $\mathit{RW}$ & {\tt network} & network ref & virtual network to which this vif is connected \\ + $\mathit{RW}$ & {\tt VM} & VM ref & virtual machine to which this vif is connected \\ +@@ -6060,72 +6048,6 @@ void + \vspace{0.3cm} + \vspace{0.3cm} + \vspace{0.3cm} +-\subsubsection{RPC name:~get\_type} +- +-{\bf Overview:} +-Get the type field of the given VIF. +- +- \noindent {\bf Signature:} +-\begin{verbatim} (driver_type) get_type (session_id s, VIF ref self)\end{verbatim} +- +- +-\noindent{\bf Arguments:} +- +- +-\vspace{0.3cm} +-\begin{tabular}{|c|c|p{7cm}|} +- \hline +-{\bf type} & {\bf name} & {\bf description} \\ \hline +-{\tt VIF ref } & self & reference to the object \\ \hline +- +-\end{tabular} +- +-\vspace{0.3cm} +- +- \noindent {\bf Return Type:} +-{\tt +-driver\_type +-} +- +- +-value of the field +-\vspace{0.3cm} +-\vspace{0.3cm} +-\vspace{0.3cm} +-\subsubsection{RPC name:~set\_type} +- +-{\bf Overview:} +-Set the type field of the given VIF. +- +- \noindent {\bf Signature:} +-\begin{verbatim} void set_type (session_id s, VIF ref self, driver_type value)\end{verbatim} +- +- +-\noindent{\bf Arguments:} +- +- +-\vspace{0.3cm} +-\begin{tabular}{|c|c|p{7cm}|} +- \hline +-{\bf type} & {\bf name} & {\bf description} \\ \hline +-{\tt VIF ref } & self & reference to the object \\ \hline +- +-{\tt driver\_type } & value & New value to set \\ \hline +- +-\end{tabular} +- +-\vspace{0.3cm} +- +- \noindent {\bf Return Type:} +-{\tt +-void +-} +- +- +- +-\vspace{0.3cm} +-\vspace{0.3cm} +-\vspace{0.3cm} + \subsubsection{RPC name:~get\_device} + + {\bf Overview:} +@@ -8782,7 +8704,6 @@ $\mathit{RW}$ & {\tt VDI} & VDI ref & t + $\mathit{RW}$ & {\tt device} & string & device seen by the guest e.g. hda1 \\ + $\mathit{RW}$ & {\tt mode} & vbd\_mode & the mode the disk should be mounted with \\ + $\mathit{RW}$ & {\tt type} & vbd\_type & how the VBD will appear to the guest (e.g. disk or CD) \\ +-$\mathit{RW}$ & {\tt driver} & driver\_type & the style of driver \\ + $\mathit{RO}_\mathit{run}$ & {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\ + $\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ + \hline +@@ -9184,72 +9105,6 @@ void + \vspace{0.3cm} + \vspace{0.3cm} + \vspace{0.3cm} +-\subsubsection{RPC name:~get\_driver} +- +-{\bf Overview:} +-Get the driver field of the given VBD. +- +- \noindent {\bf Signature:} +-\begin{verbatim} (driver_type) get_driver (session_id s, VBD ref self)\end{verbatim} +- +- +-\noindent{\bf Arguments:} +- +- +-\vspace{0.3cm} +-\begin{tabular}{|c|c|p{7cm}|} +- \hline +-{\bf type} & {\bf name} & {\bf description} \\ \hline +-{\tt VBD ref } & self & reference to the object \\ \hline +- +-\end{tabular} +- +-\vspace{0.3cm} +- +- \noindent {\bf Return Type:} +-{\tt +-driver\_type +-} +- +- +-value of the field +-\vspace{0.3cm} +-\vspace{0.3cm} +-\vspace{0.3cm} +-\subsubsection{RPC name:~set\_driver} +- +-{\bf Overview:} +-Set the driver field of the given VBD. +- +- \noindent {\bf Signature:} +-\begin{verbatim} void set_driver (session_id s, VBD ref self, driver_type value)\end{verbatim} +- +- +-\noindent{\bf Arguments:} +- +- +-\vspace{0.3cm} +-\begin{tabular}{|c|c|p{7cm}|} +- \hline +-{\bf type} & {\bf name} & {\bf description} \\ \hline +-{\tt VBD ref } & self & reference to the object \\ \hline +- +-{\tt driver\_type } & value & New value to set \\ \hline +- +-\end{tabular} +- +-\vspace{0.3cm} +- +- \noindent {\bf Return Type:} +-{\tt +-void +-} +- +- +- +-\vspace{0.3cm} +-\vspace{0.3cm} +-\vspace{0.3cm} + \subsubsection{RPC name:~get\_io\_read\_kbs} + + {\bf Overview:} +@@ -9457,7 +9312,6 @@ Quals & Field & Type & Description \\ + $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ + $\mathit{RO}_\mathit{ins}$ & {\tt VM} & VM ref & the virtual machine \\ + $\mathit{RO}_\mathit{ins}$ & {\tt backend} & VM ref & the domain where the backend is located \\ +-$\mathit{RO}_\mathit{ins}$ & {\tt driver} & driver\_type & the style of driver \\ + $\mathit{RO}_\mathit{ins}$ & {\tt instance} & int & the instance number the virtual TPM represents \\ + \hline + \end{longtable} +@@ -9558,38 +9412,6 @@ value of the field + \vspace{0.3cm} + \vspace{0.3cm} + \vspace{0.3cm} +-\subsubsection{RPC name:~get\_driver} +- +-{\bf Overview:} +-Get the driver field of the given VTPM. +- +- \noindent {\bf Signature:} +-\begin{verbatim} (driver_type) get_driver (session_id s, VTPM ref self)\end{verbatim} +- +- +-\noindent{\bf Arguments:} +- +- +-\vspace{0.3cm} +-\begin{tabular}{|c|c|p{7cm}|} +- \hline +-{\bf type} & {\bf name} & {\bf description} \\ \hline +-{\tt VTPM ref } & self & reference to the object \\ \hline +- +-\end{tabular} +- +-\vspace{0.3cm} +- +- \noindent {\bf Return Type:} +-{\tt +-driver\_type +-} +- +- +-value of the field +-\vspace{0.3cm} +-\vspace{0.3cm} +-\vspace{0.3cm} + \subsubsection{RPC name:~get\_instance} + + {\bf Overview:} +Index: xen-3.0.4-testing/tools/libxen/include/xen_vbd.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_vbd.h ++++ xen-3.0.4-testing/tools/libxen/include/xen_vbd.h +@@ -20,7 +20,6 @@ + #define XEN_VBD_H + + #include "xen_common.h" +-#include "xen_driver_type.h" + #include "xen_vbd_decl.h" + #include "xen_vbd_mode.h" + #include "xen_vdi_decl.h" +@@ -28,8 +27,8 @@ + + + /* +- * The VBD class. +- * ++ * The VBD class. ++ * + * A virtual block device. + */ + +@@ -71,7 +70,6 @@ typedef struct xen_vbd_record + char *device; + char *image; + enum xen_vbd_mode mode; +- enum xen_driver_type driver; + double io_read_kbs; + double io_write_kbs; + } xen_vbd_record; +@@ -219,13 +217,6 @@ xen_vbd_get_mode(xen_session *session, e + + + /** +- * Get the driver field of the given VBD. +- */ +-extern bool +-xen_vbd_get_driver(xen_session *session, enum xen_driver_type *result, xen_vbd vbd); +- +- +-/** + * Get the io/read_kbs field of the given VBD. + */ + extern bool +@@ -268,13 +259,6 @@ xen_vbd_set_mode(xen_session *session, x + + + /** +- * Set the driver field of the given VBD. +- */ +-extern bool +-xen_vbd_set_driver(xen_session *session, xen_vbd vbd, enum xen_driver_type driver); +- +- +-/** + * Change the media in the device for CDROM-like devices only. For + * other devices, detach the VBD and attach a new one + */ +Index: xen-3.0.4-testing/tools/libxen/include/xen_vif.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_vif.h ++++ xen-3.0.4-testing/tools/libxen/include/xen_vif.h +@@ -20,15 +20,14 @@ + #define XEN_VIF_H + + #include "xen_common.h" +-#include "xen_driver_type.h" + #include "xen_network_decl.h" + #include "xen_vif_decl.h" + #include "xen_vm_decl.h" + + + /* +- * The VIF class. +- * ++ * The VIF class. ++ * + * A virtual network interface. + */ + +@@ -65,8 +64,6 @@ typedef struct xen_vif_record + { + xen_vif handle; + char *uuid; +- char *name; +- enum xen_driver_type type; + char *device; + struct xen_network_record_opt *network; + struct xen_vm_record_opt *vm; +@@ -191,20 +188,6 @@ xen_vif_get_uuid(xen_session *session, c + + + /** +- * Get the name field of the given VIF. +- */ +-extern bool +-xen_vif_get_name(xen_session *session, char **result, xen_vif vif); +- +- +-/** +- * Get the type field of the given VIF. +- */ +-extern bool +-xen_vif_get_type(xen_session *session, enum xen_driver_type *result, xen_vif vif); +- +- +-/** + * Get the device field of the given VIF. + */ + extern bool +@@ -254,20 +237,6 @@ xen_vif_get_io_write_kbs(xen_session *se + + + /** +- * Set the name field of the given VIF. +- */ +-extern bool +-xen_vif_set_name(xen_session *session, xen_vif vif, char *name); +- +- +-/** +- * Set the type field of the given VIF. +- */ +-extern bool +-xen_vif_set_type(xen_session *session, xen_vif vif, enum xen_driver_type type); +- +- +-/** + * Set the device field of the given VIF. + */ + extern bool +Index: xen-3.0.4-testing/tools/libxen/include/xen_vtpm.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_vtpm.h ++++ xen-3.0.4-testing/tools/libxen/include/xen_vtpm.h +@@ -21,7 +21,6 @@ + #define XEN_VTPM_H + + #include "xen_common.h" +-#include "xen_driver_type.h" + #include "xen_vm_decl.h" + #include "xen_vtpm_decl.h" + +@@ -67,7 +66,6 @@ typedef struct xen_vtpm_record + char *uuid; + struct xen_vm_record_opt *vm; + struct xen_vm_record_opt *backend; +- enum xen_driver_type driver; + int64_t instance; + } xen_vtpm_record; + +@@ -200,13 +198,6 @@ xen_vtpm_get_backend(xen_session *sessio + + + /** +- * Get the driver field of the given VTPM. +- */ +-extern bool +-xen_vtpm_get_driver(xen_session *session, enum xen_driver_type *result, xen_vtpm vtpm); +- +- +-/** + * Get the instance field of the given VTPM. + */ + extern bool +Index: xen-3.0.4-testing/tools/libxen/src/xen_vbd.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/src/xen_vbd.c ++++ xen-3.0.4-testing/tools/libxen/src/xen_vbd.c +@@ -21,7 +21,6 @@ + #include + + #include "xen_common.h" +-#include "xen_driver_type_internal.h" + #include "xen_internal.h" + #include "xen_vbd.h" + #include "xen_vbd_mode_internal.h" +@@ -58,9 +57,6 @@ static const struct_member xen_vbd_recor + { .key = "mode", + .type = &xen_vbd_mode_abstract_type_, + .offset = offsetof(xen_vbd_record, mode) }, +- { .key = "driver", +- .type = &xen_driver_type_abstract_type_, +- .offset = offsetof(xen_vbd_record, driver) }, + { .key = "io_read_kbs", + .type = &abstract_type_float, + .offset = offsetof(xen_vbd_record, io_read_kbs) }, +@@ -235,23 +231,6 @@ xen_vbd_get_mode(xen_session *session, e + + + bool +-xen_vbd_get_driver(xen_session *session, enum xen_driver_type *result, xen_vbd vbd) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vbd } +- }; +- +- abstract_type result_type = xen_driver_type_abstract_type_; +- char *result_str = NULL; +- XEN_CALL_("VBD.get_driver"); +- *result = xen_driver_type_from_string(session, result_str); +- return session->ok; +-} +- +- +-bool + xen_vbd_get_io_read_kbs(xen_session *session, double *result, xen_vbd vbd) + { + abstract_value param_values[] = +@@ -348,22 +327,6 @@ xen_vbd_set_mode(xen_session *session, x + + + bool +-xen_vbd_set_driver(xen_session *session, xen_vbd vbd, enum xen_driver_type driver) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vbd }, +- { .type = &xen_driver_type_abstract_type_, +- .u.string_val = xen_driver_type_to_string(driver) } +- }; +- +- xen_call_(session, "VBD.set_driver", param_values, 2, NULL, NULL); +- return session->ok; +-} +- +- +-bool + xen_vbd_media_change(xen_session *session, xen_vbd vbd, xen_vdi vdi) + { + abstract_value param_values[] = +Index: xen-3.0.4-testing/tools/libxen/src/xen_vif.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/src/xen_vif.c ++++ xen-3.0.4-testing/tools/libxen/src/xen_vif.c +@@ -21,7 +21,6 @@ + #include + + #include "xen_common.h" +-#include "xen_driver_type_internal.h" + #include "xen_internal.h" + #include "xen_network.h" + #include "xen_vif.h" +@@ -42,12 +41,6 @@ static const struct_member xen_vif_recor + { .key = "uuid", + .type = &abstract_type_string, + .offset = offsetof(xen_vif_record, uuid) }, +- { .key = "name", +- .type = &abstract_type_string, +- .offset = offsetof(xen_vif_record, name) }, +- { .key = "type", +- .type = &xen_driver_type_abstract_type_, +- .offset = offsetof(xen_vif_record, type) }, + { .key = "device", + .type = &abstract_type_string, + .offset = offsetof(xen_vif_record, device) }, +@@ -90,7 +83,6 @@ xen_vif_record_free(xen_vif_record *reco + } + free(record->handle); + free(record->uuid); +- free(record->name); + free(record->device); + xen_network_record_opt_free(record->network); + xen_vm_record_opt_free(record->vm); +@@ -171,38 +163,6 @@ xen_vif_destroy(xen_session *session, xe + + + bool +-xen_vif_get_name(xen_session *session, char **result, xen_vif vif) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vif } +- }; +- +- abstract_type result_type = abstract_type_string; +- +- *result = NULL; +- XEN_CALL_("VIF.get_name"); +- return session->ok; +-} +- +- +-bool +-xen_vif_get_type(xen_session *session, enum xen_driver_type *result, xen_vif vif) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vif } +- }; +- +- abstract_type result_type = xen_driver_type_abstract_type_; +- XEN_CALL_("VIF.get_type"); +- return session->ok; +-} +- +- +-bool + xen_vif_get_device(xen_session *session, char **result, xen_vif vif) + { + abstract_value param_values[] = +@@ -319,38 +279,6 @@ xen_vif_get_io_write_kbs(xen_session *se + + + bool +-xen_vif_set_name(xen_session *session, xen_vif vif, char *name) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vif }, +- { .type = &abstract_type_string, +- .u.string_val = name } +- }; +- +- xen_call_(session, "VIF.set_name", param_values, 2, NULL, NULL); +- return session->ok; +-} +- +- +-bool +-xen_vif_set_type(xen_session *session, xen_vif vif, enum xen_driver_type type) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vif }, +- { .type = &xen_driver_type_abstract_type_, +- .u.string_val = xen_driver_type_to_string(type) } +- }; +- +- xen_call_(session, "VIF.set_type", param_values, 2, NULL, NULL); +- return session->ok; +-} +- +- +-bool + xen_vif_set_device(xen_session *session, xen_vif vif, char *device) + { + abstract_value param_values[] = +Index: xen-3.0.4-testing/tools/libxen/src/xen_vtpm.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/src/xen_vtpm.c ++++ xen-3.0.4-testing/tools/libxen/src/xen_vtpm.c +@@ -22,7 +22,6 @@ + #include + + #include "xen_common.h" +-#include "xen_driver_type_internal.h" + #include "xen_internal.h" + #include "xen_vm.h" + #include "xen_vtpm.h" +@@ -48,9 +47,6 @@ static const struct_member xen_vtpm_reco + { .key = "backend", + .type = &abstract_type_ref, + .offset = offsetof(xen_vtpm_record, backend) }, +- { .key = "driver", +- .type = &xen_driver_type_abstract_type_, +- .offset = offsetof(xen_vtpm_record, driver) }, + { .key = "instance", + .type = &abstract_type_int, + .offset = offsetof(xen_vtpm_record, instance) } +@@ -187,21 +183,6 @@ xen_vtpm_get_backend(xen_session *sessio + + + bool +-xen_vtpm_get_driver(xen_session *session, enum xen_driver_type *result, xen_vtpm vtpm) +-{ +- abstract_value param_values[] = +- { +- { .type = &abstract_type_string, +- .u.string_val = vtpm } +- }; +- +- abstract_type result_type = xen_driver_type_abstract_type_; +- XEN_CALL_("VTPM.get_driver"); +- return session->ok; +-} +- +- +-bool + xen_vtpm_get_instance(xen_session *session, int64_t *result, xen_vtpm vtpm) + { + abstract_value param_values[] = +Index: xen-3.0.4-testing/tools/libxen/test/test_bindings.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/test/test_bindings.c ++++ xen-3.0.4-testing/tools/libxen/test/test_bindings.c +@@ -382,8 +382,7 @@ static xen_vm create_new_vm(xen_session + .vm = &vm_record_opt, + .vdi = &vdi0_record_opt, + .device = "xvda1", +- .mode = XEN_VBD_MODE_RW, +- .driver = XEN_DRIVER_TYPE_PARAVIRTUALISED ++ .mode = XEN_VBD_MODE_RW + }; + + xen_vbd vbd0; +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -1067,8 +1067,7 @@ class XendAPI: + 'VDI', + 'device', + 'mode', +- 'type', +- 'driver'] ++ 'type'] + + VBD_attr_inst = VBD_attr_rw + ['image'] + +@@ -1150,10 +1149,6 @@ class XendAPI: + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, + 'mode')) +- def VBD_get_driver(self, session, vbd_ref): +- xendom = XendDomain.instance() +- return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, +- 'driver')) + + def VBD_get_type(self, session, vbd_ref): + xendom = XendDomain.instance() +@@ -1177,9 +1172,7 @@ class XendAPI: + + VIF_attr_ro = ['io_read_kbs', + 'io_write_kbs'] +- VIF_attr_rw = ['name', +- 'type', +- 'device', ++ VIF_attr_rw = ['device', + 'network', + 'VM', + 'MAC', +@@ -1237,10 +1230,6 @@ class XendAPI: + vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) + return xen_api_success(vm.get_uuid()) + +- def VIF_get_name(self, session, vif_ref): +- xendom = XendDomain.instance() +- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, +- 'name')) + def VIF_get_MTU(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, +@@ -1250,17 +1239,10 @@ class XendAPI: + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'MAC')) + +- def VIF_get_type(self, session, vif_ref): +- xendom = XendDomain.instance() +- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, +- 'type')) +- +- + def VIF_get_device(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'device')) +- + + def VIF_get_io_read_kbs(self, session, vif_ref): + return xen_api_todo() +@@ -1434,8 +1416,7 @@ class XendAPI: + VTPM_attr_rw = [ ] + VTPM_attr_ro = ['VM', + 'backend', +- 'instance', +- 'driver'] ++ 'instance'] + + VTPM_attr_inst = VTPM_attr_rw + +@@ -1471,20 +1452,6 @@ class XendAPI: + instance = -1 + return xen_api_success(instance) + +- def VTPM_get_driver(self, session, vtpm_ref): +- xendom = XendDomain.instance() +- vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) +- if not vm: +- return xen_api_error(XEND_ERROR_VTPM_INVALID) +- cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref) +- if not cfg: +- return xen_api_error(XEND_ERROR_VTPM_INVALID) +- if cfg.has_key('type'): +- driver = cfg['type'] +- else: +- driver = "Unknown" +- return xen_api_success(driver) +- + def VTPM_get_backend(self, session, vtpm_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) +Index: xen-3.0.4-testing/tools/libxen/include/xen_driver_type.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_driver_type.h ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * Copyright (c) 2006, XenSource Inc. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- */ +- +-#ifndef XEN_DRIVER_TYPE_H +-#define XEN_DRIVER_TYPE_H +- +- +-#include "xen_common.h" +- +- +-enum xen_driver_type +-{ +- /** +- * use hardware emulation +- */ +- XEN_DRIVER_TYPE_IOEMU, +- +- /** +- * use paravirtualised driver +- */ +- XEN_DRIVER_TYPE_PARAVIRTUALISED +-}; +- +- +-typedef struct xen_driver_type_set +-{ +- size_t size; +- enum xen_driver_type contents[]; +-} xen_driver_type_set; +- +-/** +- * Allocate a xen_driver_type_set of the given size. +- */ +-extern xen_driver_type_set * +-xen_driver_type_set_alloc(size_t size); +- +-/** +- * Free the given xen_driver_type_set. The given set must have been +- * allocated by this library. +- */ +-extern void +-xen_driver_type_set_free(xen_driver_type_set *set); +- +- +-/** +- * Return the name corresponding to the given code. This string must +- * not be modified or freed. +- */ +-extern const char * +-xen_driver_type_to_string(enum xen_driver_type val); +- +- +-/** +- * Return the correct code for the given string, or set the session +- * object to failure and return an undefined value if the given string does +- * not match a known code. +- */ +-extern enum xen_driver_type +-xen_driver_type_from_string(xen_session *session, const char *str); +- +- +-#endif +Index: xen-3.0.4-testing/tools/libxen/include/xen_driver_type_internal.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_driver_type_internal.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-/* +- * Copyright (c) 2006, XenSource Inc. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- */ +- +- +-/* +- * Declarations of the abstract types used during demarshalling of enum +- * xen_driver_type. Internal to this library -- do not use from outside. +- */ +- +- +-#ifndef XEN_DRIVER_TYPE_INTERNAL_H +-#define XEN_DRIVER_TYPE_INTERNAL_H +- +- +-#include "xen_internal.h" +- +- +-extern const abstract_type xen_driver_type_abstract_type_; +-extern const abstract_type xen_driver_type_set_abstract_type_; +- +- +-#endif +Index: xen-3.0.4-testing/tools/libxen/src/xen_driver_type.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/src/xen_driver_type.c ++++ /dev/null +@@ -1,81 +0,0 @@ +-/* +- * Copyright (c) 2006, XenSource Inc. +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2.1 of the License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public +- * License along with this library; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- */ +- +-#include +- +-#include "xen_internal.h" +-#include "xen_driver_type.h" +-#include "xen_driver_type_internal.h" +- +- +-/* +- * Maintain this in the same order as the enum declaration! +- */ +-static const char *lookup_table[] = +-{ +- "ioemu", +- "paravirtualised" +-}; +- +- +-extern xen_driver_type_set * +-xen_driver_type_set_alloc(size_t size) +-{ +- return calloc(1, sizeof(xen_driver_type_set) + +- size * sizeof(enum xen_driver_type)); +-} +- +- +-extern void +-xen_driver_type_set_free(xen_driver_type_set *set) +-{ +- free(set); +-} +- +- +-const char * +-xen_driver_type_to_string(enum xen_driver_type val) +-{ +- return lookup_table[val]; +-} +- +- +-extern enum xen_driver_type +-xen_driver_type_from_string(xen_session *session, const char *str) +-{ +- return ENUM_LOOKUP(session, str, lookup_table); +-} +- +- +-const abstract_type xen_driver_type_abstract_type_ = +- { +- .typename = ENUM, +- .enum_marshaller = +- (const char *(*)(int))&xen_driver_type_to_string, +- .enum_demarshaller = +- (int (*)(xen_session *, const char *))&xen_driver_type_from_string +- }; +- +- +-const abstract_type xen_driver_type_set_abstract_type_ = +- { +- .typename = SET, +- .child = &xen_driver_type_abstract_type_ +- }; +- +- diff --git a/13724_xenapi.patch b/13724_xenapi.patch new file mode 100644 index 0000000..3847786 --- /dev/null +++ b/13724_xenapi.patch @@ -0,0 +1,157 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170170830 0 +# Node ID 2f3794098e22a15064fbf07d2208cf526f59010b +# Parent 7fdfa020d4ed63fe758395c4630dab018f13424a +Added VM.is_control_domain field. + +Signed-off-by: Ewan Mellor + +Index: xen-3.0.4-testing/docs/xen-api/xenapi-datamodel.tex +=================================================================== +--- xen-3.0.4-testing.orig/docs/xen-api/xenapi-datamodel.tex ++++ xen-3.0.4-testing/docs/xen-api/xenapi-datamodel.tex +@@ -3644,6 +3644,38 @@ void + \vspace{0.3cm} + \vspace{0.3cm} + \vspace{0.3cm} ++\subsubsection{RPC name:~get\_is\_control\_domain} ++ ++{\bf Overview:} ++Get the is\_control\_domain field of the given VM. ++ ++ \noindent {\bf Signature:} ++\begin{verbatim} bool get_is_control_domain (session_id s, VM ref self)\end{verbatim} ++ ++ ++\noindent{\bf Arguments:} ++ ++ ++\vspace{0.3cm} ++\begin{tabular}{|c|c|p{7cm}|} ++ \hline ++{\bf type} & {\bf name} & {\bf description} \\ \hline ++{\tt VM ref } & self & reference to the object \\ \hline ++ ++\end{tabular} ++ ++\vspace{0.3cm} ++ ++ \noindent {\bf Return Type:} ++{\tt ++bool ++} ++ ++ ++value of the field ++\vspace{0.3cm} ++\vspace{0.3cm} ++\vspace{0.3cm} + \subsubsection{RPC name:~get\_boot\_method} + + {\bf Overview:} +@@ -9312,7 +9344,6 @@ Quals & Field & Type & Description \\ + $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ + $\mathit{RO}_\mathit{ins}$ & {\tt VM} & VM ref & the virtual machine \\ + $\mathit{RO}_\mathit{ins}$ & {\tt backend} & VM ref & the domain where the backend is located \\ +-$\mathit{RO}_\mathit{ins}$ & {\tt instance} & int & the instance number the virtual TPM represents \\ + \hline + \end{longtable} + \subsection{Additional RPCs associated with class: VTPM} +Index: xen-3.0.4-testing/tools/libxen/include/xen_vm.h +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/include/xen_vm.h ++++ xen-3.0.4-testing/tools/libxen/include/xen_vm.h +@@ -142,6 +142,7 @@ typedef struct xen_vm_record + char *pci_bus; + xen_string_string_map *tools_version; + xen_string_string_map *otherconfig; ++ bool is_control_domain; + } xen_vm_record; + + /** +@@ -562,6 +563,13 @@ xen_vm_get_otherconfig(xen_session *sess + + + /** ++ * Get the is_control_domain field of the given VM. ++ */ ++extern bool ++xen_vm_get_is_control_domain(xen_session *session, bool *result, xen_vm vm); ++ ++ ++/** + * Set the name/label field of the given VM. + */ + extern bool +Index: xen-3.0.4-testing/tools/libxen/src/xen_vm.c +=================================================================== +--- xen-3.0.4-testing.orig/tools/libxen/src/xen_vm.c ++++ xen-3.0.4-testing/tools/libxen/src/xen_vm.c +@@ -176,7 +176,10 @@ static const struct_member xen_vm_record + .offset = offsetof(xen_vm_record, tools_version) }, + { .key = "otherConfig", + .type = &abstract_type_string_string_map, +- .offset = offsetof(xen_vm_record, otherconfig) } ++ .offset = offsetof(xen_vm_record, otherconfig) }, ++ { .key = "is_control_domain", ++ .type = &abstract_type_bool, ++ .offset = offsetof(xen_vm_record, is_control_domain) } + }; + + const abstract_type xen_vm_record_abstract_type_ = +@@ -1006,6 +1009,22 @@ xen_vm_get_otherconfig(xen_session *sess + + + bool ++xen_vm_get_is_control_domain(xen_session *session, bool *result, xen_vm vm) ++{ ++ abstract_value param_values[] = ++ { ++ { .type = &abstract_type_string, ++ .u.string_val = vm } ++ }; ++ ++ abstract_type result_type = abstract_type_bool; ++ ++ XEN_CALL_("VM.get_is_control_domain"); ++ return session->ok; ++} ++ ++ ++bool + xen_vm_set_name_label(xen_session *session, xen_vm vm, char *label) + { + abstract_value param_values[] = +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -603,6 +603,7 @@ class XendAPI: + 'VTPMs', + 'PCI_bus', + 'tools_version', ++ 'is_control_domain', + ] + + VM_attr_rw = ['name_label', +@@ -856,6 +857,11 @@ class XendAPI: + def VM_get_otherConfig(self, session, vm_ref): + return self.VM_get('otherConfig', session, vm_ref) + ++ def VM_get_is_control_domain(self, session, vm_ref): ++ xd = XendDomain.instance() ++ return xen_api_success( ++ xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain()) ++ + def VM_set_name_label(self, session, vm_ref, label): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + dom.setName(label) +@@ -1025,6 +1031,7 @@ class XendAPI: + 'PCI_bus': xeninfo.get_pci_bus(), + 'tools_version': xeninfo.get_tools_version(), + 'otherConfig': xeninfo.info.get('otherconfig'), ++ 'is_control_domain': xeninfo == xendom.privilegedDomain(), + } + return xen_api_success(record) + diff --git a/13745_xenapi.patch b/13745_xenapi.patch new file mode 100644 index 0000000..872cda7 --- /dev/null +++ b/13745_xenapi.patch @@ -0,0 +1,662 @@ +# HG changeset patch +# User Alastair Tse +# Date 1170249636 0 +# Node ID 3cccf8e6429666be58408972570dbd063a2bae1e +# Parent 7c992fd3b19ba3f7094e0c01205a481dc74661f8 +[XEND] Merge VFB support for PV and HVM guests. + +This patch merges the way VFB are represented inside Xend by making +HVM VNC consoles use the VFB as its configuration object. + +It preserves the way options are specified through xm but will create +a new VFB device that is used by image.py to put vnc config into +qemu-dm's command line. The parsing is moved into image.py's +parseDeviceModel() rather than in configVNC(). + +Through the Xen API, you can create a 'console' of protocol 'rfb' and +end up with a VNC console, on both HVM and PV guests. The location of +the connecting port is stored in the location attribute of the console +object. This is updated on each XendDomainInfo.update() if it +changes. + +Also fixes missing read of the vnclisten and HVM_boot from the +config when initialised via xm. Makes sure bootable attribute for VBD +is store as an int when making SXP config. + +Signed-off-by: Alastair Tse + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py +@@ -1511,8 +1511,9 @@ class XendAPI: + # ---------------------------------------------------------------- + + +- console_attr_ro = ['uri', 'protocol', 'VM'] +- console_attr_rw = [] ++ console_attr_ro = ['location', 'protocol', 'VM'] ++ console_attr_rw = ['other_config'] ++ console_funcs = [('create', 'console')] + + def console_get_all(self, session): + xendom = XendDomain.instance() +@@ -1520,10 +1521,10 @@ class XendAPI: + cons = reduce(lambda x, y: x + y, cons) + return xen_api_success(cons) + +- def console_get_uri(self, session, console_ref): ++ def console_get_location(self, session, console_ref): + return xen_api_success(xendom.get_dev_property_by_uuid('console', + console_ref, +- 'uri')) ++ 'location')) + + def console_get_protocol(self, session, console_ref): + return xen_api_success(xendom.get_dev_property_by_uuid('console', +@@ -1555,6 +1556,22 @@ class XendAPI: + + return xen_api_success(return_cfg) + ++ def console_create(self, session, console_struct): ++ xendom = XendDomain.instance() ++ if not xendom.is_valid_vm(console_struct['VM']): ++ return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']]) ++ ++ dom = xendom.get_vm_by_uuid(console_struct['VM']) ++ try: ++ if 'protocol' not in console_struct: ++ return xen_api_error(['CONSOLE_PROTOCOL_INVALID', ++ 'No protocol specified']) ++ ++ console_ref = dom.create_console(console_struct) ++ xendom.managed_config_save(dom) ++ return xen_api_success(console_ref) ++ except XendError, e: ++ return xen_api_error([XEND_ERROR_TODO, str(e)]) + + # Xen API: Class SR + # ---------------------------------------------------------------- +Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +@@ -107,6 +107,7 @@ XENAPI_HVM_CFG = { + 'platform_serial' : 'serial', + 'platform_localtime': 'localtime', + 'platform_keymap' : 'keymap', ++ 'HVM_boot': 'boot', + } + + # List of XendConfig configuration keys that have no direct equivalent +@@ -230,7 +231,8 @@ LEGACY_IMAGE_CFG = [ + ('sdl', int), + ('vncdisplay', int), + ('vncunused', int), +- ('vncpasswd', str), ++ ('vncpasswd', str), ++ ('vnclisten', str), + ] + + LEGACY_IMAGE_HVM_CFG = [ +@@ -362,6 +364,7 @@ class XendConfig(dict): + 'vif_refs': [], + 'vbd_refs': [], + 'vtpm_refs': [], ++ 'other_config': {}, + } + + defaults['name_label'] = 'Domain-' + defaults['uuid'] +@@ -643,6 +646,25 @@ class XendConfig(dict): + self['vbd_refs'] = cfg.get('vbd_refs', []) + self['vtpm_refs'] = cfg.get('vtpm_refs', []) + ++ # coalesce hvm vnc frame buffer with vfb config ++ if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0): ++ # add vfb device if it isn't there already ++ has_rfb = False ++ for console_uuid in self['console_refs']: ++ if self['devices'][console_uuid][1].get('protocol') == 'rfb': ++ has_rfb = True ++ break ++ ++ if not has_rfb: ++ dev_config = ['vfb'] ++ # copy VNC related params from image config to vfb dev conf ++ for key in ['vncpasswd', 'vncunused', 'vncdisplay', ++ 'vnclisten']: ++ if key in self['image']: ++ dev_config.append([key, self['image'][key]]) ++ ++ self.device_add('vfb', cfg_sxp = dev_config) ++ + + def _sxp_to_xapi_unsupported(self, sxp_cfg): + """Read in an SXP configuration object and populate +@@ -951,6 +973,26 @@ class XendConfig(dict): + target['vbd_refs'] = [] + if dev_uuid not in target['vbd_refs']: + target['vbd_refs'].append(dev_uuid) ++ elif dev_type == 'vfb': ++ # Populate other config with aux data that is associated ++ # with vfb ++ ++ other_config = {} ++ for key in ['vncunused', 'vncdisplay', 'vnclisten', ++ 'vncpasswd', 'type', 'display', 'xauthority', ++ 'keymap']: ++ if key in dev_info: ++ other_config[key] = dev_info[key] ++ target['devices'][dev_uuid][1]['other_config'] = other_config ++ ++ ++ if 'console_refs' not in target: ++ target['console_refs'] = [] ++ ++ # Treat VFB devices as console devices so they are found ++ # through Xen API ++ if dev_uuid not in target['console_refs']: ++ target['console_refs'].append(dev_uuid) + elif dev_type in ('console',): + if 'console_refs' not in target: + target['console_refs'] = [] +@@ -1010,49 +1052,118 @@ class XendConfig(dict): + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vtpm_refs'].append(dev_uuid) + ++ elif dev_type == 'console': ++ dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) ++ dev_info['uuid'] = dev_uuid ++ dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb') ++ dev_info['other_config'] = cfg_xenapi.get('other_config', {}) ++ if dev_info['protocol'] == 'rfb': ++ # collapse other config into devinfo for things ++ # such as vncpasswd, vncunused, etc. ++ dev_info.update(cfg_xenapi.get('other_config', {})) ++ dev_info['type'] = 'vnc' ++ target['devices'][dev_uuid] = ('vfb', dev_info) ++ target['console_refs'].append(dev_uuid) ++ ++ # Finally, if we are a pvfb, we need to make a vkbd ++ # as well that is not really exposed to Xen API ++ vkbd_uuid = uuid.createString() ++ target['devices'][vkbd_uuid] = ('vkbd', {}) ++ ++ elif dev_info['protocol'] == 'vt100': ++ # if someone tries to create a VT100 console ++ # via the Xen API, we'll have to ignore it ++ # because we create one automatically in ++ # XendDomainInfo._update_consoles ++ raise XendConfigError('Creating vt100 consoles via ' ++ 'Xen API is unsupported') ++ + return dev_uuid + + # no valid device to add + return '' + + +- def console_add(self, protocol, uri): ++ def console_add(self, protocol, location, other_config = {}): + dev_uuid = uuid.createString() +- dev_info = { +- 'uuid': dev_uuid, +- 'protocol': protocol, +- 'uri': uri +- } +- if 'devices' not in self: +- self['devices'] = {} +- +- self['devices'][dev_uuid] = ('console', dev_info) +- self['console_refs'].append(dev_uuid) +- return dev_info +- ++ if protocol == 'vt100': ++ dev_info = { ++ 'uuid': dev_uuid, ++ 'protocol': protocol, ++ 'location': location, ++ 'other_config': other_config, ++ } ++ ++ if 'devices' not in self: ++ self['devices'] = {} ++ ++ self['devices'][dev_uuid] = ('console', dev_info) ++ self['console_refs'].append(dev_uuid) ++ return dev_info ++ ++ return {} ++ ++ def console_update(self, console_uuid, key, value): ++ for dev_uuid, (dev_type, dev_info) in self['devices'].items(): ++ if dev_uuid == console_uuid: ++ dev_info[key] = value ++ break ++ + def console_get_all(self, protocol): +- consoles = [dinfo for dtype, dinfo in self['devices'].values() +- if dtype == 'console'] +- return [c for c in consoles if c.get('protocol') == protocol] ++ if protocol == 'vt100': ++ consoles = [dinfo for dtype, dinfo in self['devices'].values() ++ if dtype == 'console'] ++ return [c for c in consoles if c.get('protocol') == protocol] ++ ++ elif protocol == 'rfb': ++ vfbs = [dinfo for dtype, dinfo in self['devices'].values() ++ if dtype == 'vfb'] ++ ++ # move all non-console key values to other_config before ++ # returning console config ++ valid_keys = ['uuid', 'location'] ++ for vfb in vfbs: ++ other_config = {} ++ for key, val in vfb.items(): ++ if key not in valid_keys: ++ other_config[key] = vfb[key] ++ del vfb[key] ++ vfb['other_config'] = other_config ++ vfb['protocol'] = 'rfb' ++ ++ return vfbs ++ ++ else: ++ return [] + +- def device_update(self, dev_uuid, cfg_sxp): +- """Update an existing device with the new configuration. ++ def device_update(self, dev_uuid, cfg_sxp = [], cfg_xenapi = {}): ++ """Update an existing device with the new configuration. + + @rtype: boolean + @return: Returns True if succesfully found and updated a device conf + """ +- if dev_uuid in self['devices']: +- config = sxp.child0(cfg_sxp) +- dev_type = sxp.name(config) +- dev_info = {} ++ if dev_uuid in self['devices'] and cfg_sxp: ++ if sxp.child0(cfg_sxp) == 'device': ++ config = sxp.child0(cfg_sxp) ++ else: ++ config = cfg_sxp + +- try: +- for opt, val in config[1:]: +- self['devices'][opt] = val +- except ValueError: +- pass # SXP has no options for this device +- ++ dev_type, dev_info = self['devices'][dev_uuid] ++ for opt_val in config[1:]: ++ try: ++ opt, val = opt_val ++ dev_info[opt] = val ++ except (TypeError, ValueError): ++ pass # no value for this config option ++ ++ self['devices'][dev_uuid] = (dev_type, dev_info) + return True ++ ++ elif dev_uuid in self['devices'] and cfg_xenapi: ++ dev_type, dev_info = self['devices'][dev_uuid] ++ for key, val in cfg_xenapi.items(): ++ dev_info[key] = val ++ self['devices'][dev_uuid] = (dev_type, dev_info) + + return False + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -693,16 +693,29 @@ class XendDomainInfo: + if not serial_consoles: + cfg = self.info.console_add('vt100', self.console_port) + self._createDevice('console', cfg) ++ else: ++ console_uuid = serial_consoles[0].get('uuid') ++ self.info.console_update(console_uuid, 'location', ++ self.console_port) ++ + +- # Update VNC port if it exists ++ # Update VNC port if it exists and write to xenstore + vnc_port = self.readDom('console/vnc-port') + if vnc_port is not None: +- vnc_consoles = self.info.console_get_all('rfb') +- if not vnc_consoles: +- cfg = self.info.console_add('rfb', 'localhost:%s' % +- str(vnc_port)) +- self._createDevice('console', cfg) +- ++ for dev_uuid, (dev_type, dev_info) in self.info['devices'].items(): ++ if dev_type == 'vfb': ++ old_location = dev_info.get('location') ++ listen_host = dev_info.get('vnclisten', 'localhost') ++ new_location = '%s:%s' % (listen_host, str(vnc_port)) ++ if old_location == new_location: ++ break ++ ++ dev_info['location'] = new_location ++ self.info.device_update(dev_uuid, cfg_xenapi = dev_info) ++ vfb_ctrl = self.getDeviceController('vfb') ++ vfb_ctrl.reconfigureDevice(0, dev_info) ++ break ++ + # + # Function to update xenstore /vm/* + # +@@ -1952,21 +1965,18 @@ class XendDomainInfo: + + @rtype: dictionary + """ +- dev_type_config = self.info['devices'].get(dev_uuid) ++ dev_type, dev_config = self.info['devices'].get(dev_uuid, (None, None)) + + # shortcut if the domain isn't started because + # the devcontrollers will have no better information + # than XendConfig. + if self.state in (XEN_API_VM_POWER_STATE_HALTED,): +- if dev_type_config: +- return copy.deepcopy(dev_type_config[1]) ++ if dev_config: ++ return copy.deepcopy(dev_config) + return None + + # instead of using dev_class, we use the dev_type + # that is from XendConfig. +- # This will accomdate 'tap' as well as 'vbd' +- dev_type = dev_type_config[0] +- + controller = self.getDeviceController(dev_type) + if not controller: + return None +@@ -1975,14 +1985,14 @@ class XendDomainInfo: + if not all_configs: + return None + +- dev_config = copy.deepcopy(dev_type_config[1]) ++ updated_dev_config = copy.deepcopy(dev_config) + for _devid, _devcfg in all_configs.items(): + if _devcfg.get('uuid') == dev_uuid: +- dev_config.update(_devcfg) +- dev_config['id'] = _devid +- return dev_config ++ updated_dev_config.update(_devcfg) ++ updated_dev_config['id'] = _devid ++ return updated_dev_config + +- return dev_config ++ return updated_dev_config + + def get_dev_xenapi_config(self, dev_class, dev_uuid): + config = self.get_dev_config_by_uuid(dev_class, dev_uuid) +@@ -2137,6 +2147,21 @@ class XendDomainInfo: + + return dev_uuid + ++ def create_console(self, xenapi_console): ++ """ Create a console device from a Xen API struct. ++ ++ @return: uuid of device ++ @rtype: string ++ """ ++ if self.state not in (DOM_STATE_HALTED,): ++ raise VmError("Can only add console to a halted domain.") ++ ++ dev_uuid = self.info.device_add('console', cfg_xenapi = xenapi_console) ++ if not dev_uuid: ++ raise XendError('Failed to create device') ++ ++ return dev_uuid ++ + def destroy_device_by_uuid(self, dev_type, dev_uuid): + if dev_uuid not in self.info['devices']: + raise XendError('Device does not exist') +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -26,6 +26,7 @@ import xen.lowlevel.xc + from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS + from xen.xend.XendError import VmError, XendError + from xen.xend.XendLogging import log ++from xen.xend import XendRoot + from xen.xend.server.netif import randomMAC + from xen.xend.xenstore.xswatch import xswatch + from xen.xend import arch +@@ -361,8 +362,6 @@ class HVMImageHandler(ImageHandler): + + self.pid = None + +- self.dmargs += self.configVNC(imageConfig) +- + self.pae = imageConfig['hvm'].get('pae', 1) + self.apic = imageConfig['hvm'].get('apic', 0) + self.acpi = imageConfig['hvm']['devices'].get('acpi', 0) +@@ -462,49 +461,59 @@ class HVMImageHandler(ImageHandler): + net += ",bridge=%s" % (bridge,) + ret.append(net) + +- return ret + +- def configVNC(self, imageConfig): +- # Handle graphics library related options +- vnc = imageConfig.get('vnc') +- sdl = imageConfig.get('sdl') +- ret = [] +- nographic = imageConfig.get('nographic') ++ # ++ # Find RFB console device, and if it exists, make QEMU enable ++ # the VNC console. ++ # ++ if vmConfig['image'].get('nographic'): ++ # skip vnc init if nographic is set ++ ret.append('-nographic') ++ return ret + +- # get password from VM config (if password omitted, None) +- vncpasswd_vmconfig = imageConfig.get('vncpasswd') ++ vnc_config = {} ++ has_vfb = False ++ has_vnc = int(vmConfig['image'].get('vnc')) != 0 ++ for dev_uuid in vmConfig['console_refs']: ++ dev_type, dev_info = vmConfig['devices'][devuuid] ++ if dev_type == 'rfb': ++ vnc_config = dev_info.get('other_config', {}) ++ has_vfb = True ++ break ++ ++ if not vnc_config: ++ for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'): ++ if key in vmConfig['image']: ++ vnc_config[key] = vmConfig['image'][key] + +- if nographic: ++ if not has_vfb and not has_vnc: + ret.append('-nographic') + return ret + +- if vnc: +- vncdisplay = imageConfig.get('vncdisplay', +- int(self.vm.getDomid())) +- vncunused = imageConfig.get('vncunused') +- +- if vncunused: +- ret += ['-vncunused'] +- else: +- ret += ['-vnc', '%d' % vncdisplay] ++ ++ if not vnc_config.get('vncunused', 0) and \ ++ vnc_config.get('vncdisplay', 0): ++ ret.append('-vnc') ++ ret.append(str(vncdisplay)) ++ else: ++ ret.append('-vncunused') + +- vnclisten = imageConfig.get('vnclisten') ++ vnclisten = vnc_config.get('vnclisten', ++ XendRoot.instance().get_vnclisten_address()) ++ ret.append('-vnclisten') ++ ret.append(str(vnclisten)) ++ ++ # Store vncpassword in xenstore ++ vncpasswd = vnc_config.get('vncpasswd') ++ if not vncpasswd: ++ vncpasswd = XendRoot.instance().get_vncpasswd_default() ++ ++ if vncpasswd is None: ++ raise VmError('vncpasswd is not setup in vmconfig or ' ++ 'xend-config.sxp') + +- if not(vnclisten): +- vnclisten = (xen.xend.XendRoot.instance(). +- get_vnclisten_address()) +- if vnclisten: +- ret += ['-vnclisten', vnclisten] +- +- vncpasswd = vncpasswd_vmconfig +- if vncpasswd is None: +- vncpasswd = (xen.xend.XendRoot.instance(). +- get_vncpasswd_default()) +- if vncpasswd is None: +- raise VmError('vncpasswd is not set up in ' + +- 'VMconfig and xend-config.') +- if vncpasswd != '': +- self.vm.storeVm("vncpasswd", vncpasswd) ++ if vncpasswd != '': ++ self.vm.storeVm('vncpasswd', vncpasswd) + + return ret + +Index: xen-3.0.4-testing/tools/python/xen/xend/server/ConsoleController.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/server/ConsoleController.py ++++ xen-3.0.4-testing/tools/python/xen/xend/server/ConsoleController.py +@@ -8,7 +8,7 @@ class ConsoleController(DevController): + console devices with persistent UUIDs. + """ + +- valid_cfg = ['uri', 'uuid', 'protocol'] ++ valid_cfg = ['location', 'uuid', 'protocol'] + + def __init__(self, vm): + DevController.__init__(self, vm) +@@ -29,3 +29,7 @@ class ConsoleController(DevController): + + def migrate(self, deviceConfig, network, dst, step, domName): + return 0 ++ ++ def destroyDevice(self, devid, force): ++ DevController.destroyDevice(self, devid, True) ++ +Index: xen-3.0.4-testing/tools/python/xen/xend/server/vfbif.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/server/vfbif.py ++++ xen-3.0.4-testing/tools/python/xen/xend/server/vfbif.py +@@ -14,7 +14,9 @@ def spawn_detached(path, args, env): + os.waitpid(p, 0) + + CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused', +- 'display', 'xauthority'] ++ 'display', 'xauthority', 'keymap', ++ 'uuid', 'location', 'protocol'] ++ + + class VfbifController(DevController): + """Virtual frame buffer controller. Handles all vfb devices for a domain. +@@ -27,10 +29,11 @@ class VfbifController(DevController): + def getDeviceDetails(self, config): + """@see DevController.getDeviceDetails""" + +- back = dict([(k, config[k]) for k in CONFIG_ENTRIES ++ back = dict([(k, str(config[k])) for k in CONFIG_ENTRIES + if config.has_key(k)]) + +- return (0, back, {}) ++ devid = 0 ++ return (devid, back, {}) + + + def getDeviceConfiguration(self, devid): +@@ -44,6 +47,10 @@ class VfbifController(DevController): + + def createDevice(self, config): + DevController.createDevice(self, config) ++ if self.vm.info.get('HVM_boot'): ++ # is HVM, so qemu-dm will handle the vfb. ++ return ++ + std_args = [ "--domid", "%d" % self.vm.getDomid(), + "--title", self.vm.getName() ] + t = config.get("type", None) +@@ -80,6 +87,42 @@ class VfbifController(DevController): + else: + raise VmError('Unknown vfb type %s (%s)' % (t, repr(config))) + ++ ++ def waitForDevice(self, devid): ++ if self.vm.info.get('HVM_boot'): ++ log.debug('skip waiting for HVM vfb') ++ # is a qemu-dm managed device, don't wait for hotplug for these. ++ return ++ ++ DevController.waitForDevice(self, devid) ++ ++ ++ def reconfigureDevice(self, _, config): ++ """ Only allow appending location information of vnc port into ++ xenstore.""" ++ ++ if 'location' in config: ++ (devid, back, front) = self.getDeviceDetails(config) ++ self.writeBackend(devid, 'location', config['location']) ++ return back.get('uuid') ++ ++ raise VmError('Refusing to reconfigure device vfb:%d' % devid) ++ ++ def destroyDevice(self, devid, force): ++ if self.vm.info.get('HVM_boot'): ++ # remove the backend xenstore entries for HVM guests no matter ++ # what ++ DevController.destroyDevice(self, devid, True) ++ else: ++ DevController.destroyDevice(self, devid, force) ++ ++ ++ def migrate(self, deviceConfig, network, dst, step, domName): ++ if self.vm.info.get('HVM_boot'): ++ return 0 ++ return DevController.migrate(self, deviceConfig, network, dst, step, ++ domName) ++ + class VkbdifController(DevController): + """Virtual keyboard controller. Handles all vkbd devices for a domain. + """ +@@ -90,3 +133,24 @@ class VkbdifController(DevController): + back = {} + front = {} + return (devid, back, front) ++ ++ def waitForDevice(self, config): ++ if self.vm.info.get('HVM_boot'): ++ # is a qemu-dm managed device, don't wait for hotplug for these. ++ return ++ ++ DevController.waitForDevice(self, config) ++ ++ def destroyDevice(self, devid, force): ++ if self.vm.info.get('HVM_boot'): ++ # remove the backend xenstore entries for HVM guests no matter ++ # what ++ DevController.destroyDevice(self, devid, True) ++ else: ++ DevController.destroyDevice(self, devid, force) ++ ++ def migrate(self, deviceConfig, network, dst, step, domName): ++ if self.vm.info.get('HVM_boot'): ++ return 0 ++ return DevController.migrate(self, deviceConfig, network, dst, step, ++ domName) diff --git a/13747_xenapi.patch b/13747_xenapi.patch new file mode 100644 index 0000000..878a215 --- /dev/null +++ b/13747_xenapi.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# User Alastair Tse +# Date 1170255740 0 +# Node ID dfa9e5565063455d96b78a84c22e6e6b607d9f4a +# Parent f63e1244b48dd6d8c064f4ed38b7d7cf2bdf62ee +[XEND] Hide other_config from console and vfb SXP to prevent string +representation of dict to appear in SXP. + +Signed-off-by: Alastair Tse + +diff -r f63e1244b48d -r dfa9e5565063 tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Wed Jan 31 15:01:09 2007 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Wed Jan 31 15:02:20 2007 +0000 +@@ -1223,7 +1223,12 @@ class XendConfig(dict): + "configuration dictionary.") + + sxpr.append(dev_type) +- config = [(opt, val) for opt, val in dev_info.items()] ++ if dev_type in ('console', 'vfb'): ++ config = [(opt, val) for opt, val in dev_info.items() ++ if opt != 'other_config'] ++ else: ++ config = [(opt, val) for opt, val in dev_info.items()] ++ + sxpr += config + + return sxpr diff --git a/13753_xenapi.patch b/13753_xenapi.patch new file mode 100644 index 0000000..1a8d4a6 --- /dev/null +++ b/13753_xenapi.patch @@ -0,0 +1,26 @@ +# HG changeset patch +# User Alastair Tse +# Date 1170256953 0 +# Node ID 3db881ef97c44dbe749c7b3e7679f97dd959262d +# Parent beb0b36de1560f5a0094461063e48fa659398a0f +[XEND] Fix typos in vfb/vnc detect in image.py + +Signed-off-by: Alastair Tse + +diff -r beb0b36de156 -r 3db881ef97c4 tools/python/xen/xend/image.py +--- a/tools/python/xen/xend/image.py Wed Jan 31 15:08:29 2007 +0000 ++++ b/tools/python/xen/xend/image.py Wed Jan 31 15:22:33 2007 +0000 +@@ -450,10 +450,10 @@ class HVMImageHandler(ImageHandler): + + vnc_config = {} + has_vfb = False +- has_vnc = int(vmConfig['image'].get('vnc')) != 0 ++ has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0 + for dev_uuid in vmConfig['console_refs']: +- dev_type, dev_info = vmConfig['devices'][devuuid] +- if dev_type == 'rfb': ++ dev_type, dev_info = vmConfig['devices'][dev_uuid] ++ if dev_type == 'vfb': + vnc_config = dev_info.get('other_config', {}) + has_vfb = True + break diff --git a/13775_xenapi.patch b/13775_xenapi.patch new file mode 100644 index 0000000..9a56018 --- /dev/null +++ b/13775_xenapi.patch @@ -0,0 +1,24 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170343822 0 +# Node ID 868babf6b1dd2b196de7fea6a158365a0e63675c +# Parent d34d43fb88ae23e78ea90048d6c20a7255193836 +Fix HVM save/restore wrt console handling. + +From Tim Deegan . + +Signed-off-by: Ewan Mellor + +diff -r d34d43fb88ae -r 868babf6b1dd tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Thu Feb 01 15:03:55 2007 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Thu Feb 01 15:30:22 2007 +0000 +@@ -679,6 +679,9 @@ class XendConfig(dict): + if self['devices'][console_uuid][1].get('protocol') == 'rfb': + has_rfb = True + break ++ if self['devices'][console_uuid][0] == 'vfb': ++ has_rfb = True ++ break + + if not has_rfb: + dev_config = ['vfb'] diff --git a/13777_xenapi.patch b/13777_xenapi.patch new file mode 100644 index 0000000..dc0cdda --- /dev/null +++ b/13777_xenapi.patch @@ -0,0 +1,41 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170343936 0 +# Node ID 1fb0302683d34317d363f5e7b627fb432f1ac19e +# Parent 2b4b07391df2d63dc419701099b04f8a0c202111 +Fix handling of HVM boot. + +Signed-off-by: Ewan Mellor + +Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +@@ -707,6 +707,7 @@ class XendConfig(dict): + val = sxp.child_value(image_sxp, imgkey, None) + if val != None: + self[apikey] = val ++ self._hvm_boot_params_from_sxp(image_sxp) + + # extract backend value + +@@ -1310,11 +1311,18 @@ class XendConfig(dict): + val = sxp.child_value(image_sxp, imgkey, None) + if val != None: + type_conv = XENAPI_CFG_TYPES[apikey] +- if callable(conv): ++ if callable(type_conv): + self[apikey] = type_conv(val) + else: + self[apikey] = val ++ self._hvm_boot_params_from_sxp(image_sxp) + ++ ++ def _hvm_boot_params_from_sxp(self, image_sxp): ++ boot = sxp.child_value(image_sxp, 'boot', None) ++ if boot is not None: ++ self['HVM_boot_policy'] = 'BIOS order' ++ self['HVM_boot_params'] = { 'order' : boot } + + # + # debugging diff --git a/13778_xenapi.patch b/13778_xenapi.patch new file mode 100644 index 0000000..553d8c7 --- /dev/null +++ b/13778_xenapi.patch @@ -0,0 +1,98 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170344640 0 +# Node ID f84ba62ca615e67f297820455c76f4a061e32490 +# Parent 1fb0302683d34317d363f5e7b627fb432f1ac19e +Fix SDL option for HVM domains. + +Signed-off-by: Ewan Mellor + +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -472,48 +472,50 @@ class HVMImageHandler(ImageHandler): + return ret + + vnc_config = {} +- has_vfb = False + has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0 ++ has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0 + for dev_uuid in vmConfig['console_refs']: + dev_type, dev_info = vmConfig['devices'][dev_uuid] + if dev_type == 'vfb': + vnc_config = dev_info.get('other_config', {}) +- has_vfb = True ++ has_vnc = True + break + +- if not vnc_config: +- for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'): +- if key in vmConfig['image']: +- vnc_config[key] = vmConfig['image'][key] +- +- if not has_vfb and not has_vnc: +- ret.append('-nographic') +- return ret +- +- +- if not vnc_config.get('vncunused', 0) and \ +- vnc_config.get('vncdisplay', 0): +- ret.append('-vnc') +- ret.append(str(vncdisplay)) ++ if has_vnc: ++ if not vnc_config: ++ for key in ('vncunused', 'vnclisten', 'vncdisplay', ++ 'vncpasswd'): ++ if key in vmConfig['image']: ++ vnc_config[key] = vmConfig['image'][key] ++ ++ if not vnc_config.get('vncunused', 0) and \ ++ vnc_config.get('vncdisplay', 0): ++ ret.append('-vnc') ++ ret.append(str(vncdisplay)) ++ else: ++ ret.append('-vncunused') ++ ++ vnclisten = vnc_config.get('vnclisten', ++ XendRoot.instance().get_vnclisten_address()) ++ ret.append('-vnclisten') ++ ret.append(str(vnclisten)) ++ ++ # Store vncpassword in xenstore ++ vncpasswd = vnc_config.get('vncpasswd') ++ if not vncpasswd: ++ vncpasswd = XendRoot.instance().get_vncpasswd_default() ++ ++ if vncpasswd is None: ++ raise VmError('vncpasswd is not setup in vmconfig or ' ++ 'xend-config.sxp') ++ ++ if vncpasswd != '': ++ self.vm.storeVm('vncpasswd', vncpasswd) ++ elif has_sdl: ++ # SDL is default in QEMU. ++ pass + else: +- ret.append('-vncunused') +- +- vnclisten = vnc_config.get('vnclisten', +- XendRoot.instance().get_vnclisten_address()) +- ret.append('-vnclisten') +- ret.append(str(vnclisten)) +- +- # Store vncpassword in xenstore +- vncpasswd = vnc_config.get('vncpasswd') +- if not vncpasswd: +- vncpasswd = XendRoot.instance().get_vncpasswd_default() +- +- if vncpasswd is None: +- raise VmError('vncpasswd is not setup in vmconfig or ' +- 'xend-config.sxp') +- +- if vncpasswd != '': +- self.vm.storeVm('vncpasswd', vncpasswd) ++ ret.append('-nographic') + + return ret + diff --git a/13784_xenapi.patch b/13784_xenapi.patch new file mode 100644 index 0000000..4b5b923 --- /dev/null +++ b/13784_xenapi.patch @@ -0,0 +1,131 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170353736 0 +# Node ID e0b7ab2a1d5677ba95a3f2c29eb083fc248357e2 +# Parent b32a44bfb10ccd23cd6ac71883cea65fb4c7b1a0 +Treat the empty string as an absent UUID, not an invalid one. Fix to_sxp +wrt dictionaries. + +Signed-off-by: Ewan Mellor + +diff -r b32a44bfb10c -r e0b7ab2a1d56 tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Thu Feb 01 18:14:40 2007 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Thu Feb 01 18:15:36 2007 +0000 +@@ -349,7 +349,6 @@ class XendConfig(dict): + + def _defaults(self): + defaults = { +- 'uuid': uuid.createString(), + 'name_label': 'Domain-Unnamed', + 'actions_after_shutdown': 'destroy', + 'actions_after_reboot': 'restart', +@@ -385,7 +384,6 @@ class XendConfig(dict): + 'other_config': {}, + } + +- defaults['name_label'] = 'Domain-' + defaults['uuid'] + return defaults + + def _memory_sanity_check(self): +@@ -415,13 +413,21 @@ class XendConfig(dict): + + def _uuid_sanity_check(self): + """Make sure UUID is in proper string format with hyphens.""" +- self['uuid'] = uuid.toString(uuid.fromString(self['uuid'])) ++ if 'uuid' not in self or not self['uuid']: ++ self['uuid'] = uuid.createString() ++ else: ++ self['uuid'] = uuid.toString(uuid.fromString(self['uuid'])) ++ ++ def _name_sanity_check(self): ++ if 'name_label' not in self: ++ self['name_label'] = 'Domain-' + self['uuid'] + + def validate(self): ++ self._uuid_sanity_check() ++ self._name_sanity_check() + self._memory_sanity_check() + self._actions_sanity_check() + self._vcpus_sanity_check() +- self._uuid_sanity_check() + + def _dominfo_to_xapi(self, dominfo): + self['domid'] = dominfo['domid'] +@@ -840,8 +846,6 @@ class XendConfig(dict): + else: + self[key] = val + +- self.validate() +- + def to_sxp(self, domain = None, ignore_devices = False, ignore = [], + legacy_only = True): + """ Get SXP representation of this config object. +@@ -865,9 +869,13 @@ class XendConfig(dict): + sxpr.append(['domid', domain.getDomid()]) + + if not legacy_only: +- for name in XENAPI_CFG_TYPES.keys(): ++ for name, typ in XENAPI_CFG_TYPES.items(): + if name in self and self[name] not in (None, []): +- sxpr.append([name, str(self[name])]) ++ if typ == dict: ++ s = self[name].items() ++ else: ++ s = str(self[name]) ++ sxpr.append([name, s]) + + for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items(): + if self.has_key(xenapi) and self[xenapi] not in (None, []): +@@ -996,7 +1004,9 @@ class XendConfig(dict): + dev_info['driver'] = 'paravirtualised' + + # create uuid if it doesn't exist +- dev_uuid = dev_info.get('uuid', uuid.createString()) ++ dev_uuid = dev_info.get('uuid', None) ++ if not dev_uuid: ++ dev_uuid = uuid.createString() + dev_info['uuid'] = dev_uuid + + # store dev references by uuid for certain device types +@@ -1066,7 +1076,9 @@ class XendConfig(dict): + if cfg_xenapi.get('name'): + dev_info['name'] = cfg_xenapi.get('name') + +- dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) ++ dev_uuid = cfg_xenapi.get('uuid', None) ++ if not dev_uuid: ++ dev_uuid = uuid.createString() + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vif_refs'].append(dev_uuid) +@@ -1090,7 +1102,9 @@ class XendConfig(dict): + else: + dev_info['mode'] = 'r' + +- dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) ++ dev_uuid = cfg_xenapi.get('uuid', None) ++ if not dev_uuid: ++ dev_uuid = uuid.createString() + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vbd_refs'].append(dev_uuid) +@@ -1099,13 +1113,17 @@ class XendConfig(dict): + if cfg_xenapi.get('type'): + dev_info['type'] = cfg_xenapi.get('type') + +- dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) ++ dev_uuid = cfg_xenapi.get('uuid', None) ++ if not dev_uuid: ++ dev_uuid = uuid.createString() + dev_info['uuid'] = dev_uuid + target['devices'][dev_uuid] = (dev_type, dev_info) + target['vtpm_refs'].append(dev_uuid) + + elif dev_type == 'console': +- dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) ++ dev_uuid = cfg_xenapi.get('uuid', None) ++ if not dev_uuid: ++ dev_uuid = uuid.createString() + dev_info['uuid'] = dev_uuid + dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb') + dev_info['other_config'] = cfg_xenapi.get('other_config', {}) diff --git a/13787_xenapi.patch b/13787_xenapi.patch new file mode 100644 index 0000000..ff4c784 --- /dev/null +++ b/13787_xenapi.patch @@ -0,0 +1,215 @@ +# HG changeset patch +# User Ewan Mellor +# Date 1170356533 0 +# Node ID 0fb5df09de9426b9144eabc0d9a93c0bbfe14070 +# Parent a357bed2daf8096bb5c682d454a2b3af652fc73f +Added support for maps inside structs, so that we can send the HVM boot params +and VCPU params. + +Signed-off-by: Ewan Mellor + +diff -r a357bed2daf8 -r 0fb5df09de94 tools/libxen/src/xen_common.c +--- a/tools/libxen/src/xen_common.c Thu Feb 01 19:00:17 2007 +0000 ++++ b/tools/libxen/src/xen_common.c Thu Feb 01 19:02:13 2007 +0000 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2006 XenSource, Inc. ++ * Copyright (c) 2006-2007 XenSource, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -86,6 +86,8 @@ add_param_struct(xmlNode *); + add_param_struct(xmlNode *); + static xmlNode * + add_struct_array(xmlNode *, const char *); ++static xmlNode * ++add_nested_struct(xmlNode *, const char *); + static void + add_struct_member(xmlNode *, const char *, const char *, const char *); + static void +@@ -106,6 +108,9 @@ parse_structmap_value(xen_session *, xml + void *); + + static size_t size_of_member(const abstract_type *); ++ ++static const char * ++get_val_as_string(const struct abstract_type *, void *, char *); + + + void +@@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_t + switch (type->typename) + { + case REF: +- { +- arbitrary_record_opt *val = *(arbitrary_record_opt **)value; +- if (val != NULL) +- { +- if (val->is_record) +- { +- adder(node, key, "string", val->u.record->handle); +- } +- else +- { +- adder(node, key, "string", val->u.handle); +- } +- } +- } +- break; +- + case STRING: +- { +- char *val = *(char **)value; +- if (val != NULL) +- { +- adder(node, key, "string", val); +- } +- } +- break; +- + case INT: +- { +- int64_t val = *(int64_t *)value; +- snprintf(buf, sizeof(buf), "%"PRId64, val); +- adder(node, key, "string", buf); ++ case ENUM: ++ { ++ const char *val_as_string = get_val_as_string(type, value, buf); ++ adder(node, key, "string", val_as_string); + } + break; + +@@ -1220,13 +1200,6 @@ add_struct_value(const struct abstract_t + { + bool val = *(bool *)value; + adder(node, key, "boolean", val ? "1" : "0"); +- } +- break; +- +- case ENUM: +- { +- int val = *(int *)value; +- adder(node, key, "string", type->enum_marshaller(val)); + } + break; + +@@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_t + break; + + case STRUCT: +- case MAP: +- { ++ { ++ assert(false); + /* XXX Nested structures aren't supported yet, but + fortunately we don't need them, because we don't have + any "deep create" calls. This will need to be +- fixed. We don't need maps either. */ ++ fixed. */ ++ } ++ break; ++ ++ case MAP: ++ { ++ size_t member_size = type->struct_size; ++ const struct abstract_type *l_type = type->members[0].type; ++ const struct abstract_type *r_type = type->members[1].type; ++ int l_offset = type->members[0].offset; ++ int r_offset = type->members[1].offset; ++ ++ arbitrary_map *map_val = *(arbitrary_map **)value; ++ ++ if (map_val != NULL) ++ { ++ xmlNode *struct_node = add_nested_struct(node, key); ++ ++ for (size_t i = 0; i < map_val->size; i++) ++ { ++ void *contents = (void *)map_val->contents; ++ void *l_value = contents + (i * member_size) + l_offset; ++ void *r_value = contents + (i * member_size) + r_offset; ++ ++ const char *l_value_as_string = ++ get_val_as_string(l_type, l_value, buf); ++ ++ add_struct_value(r_type, r_value, add_struct_member, ++ l_value_as_string, struct_node); ++ } ++ } ++ } ++ break; ++ ++ default: ++ assert(false); ++ } ++} ++ ++ ++static const char * ++get_val_as_string(const struct abstract_type *type, void *value, char *buf) ++{ ++ switch (type->typename) ++ { ++ case REF: ++ { ++ arbitrary_record_opt *val = *(arbitrary_record_opt **)value; ++ if (val != NULL) ++ { ++ if (val->is_record) ++ { ++ return val->u.record->handle; ++ } ++ else ++ { ++ return val->u.handle; ++ } ++ } ++ else ++ { ++ return NULL; ++ } ++ } ++ break; ++ ++ case STRING: ++ { ++ return *(char **)value; ++ } ++ break; ++ ++ case INT: ++ { ++ int64_t val = *(int64_t *)value; ++ snprintf(buf, sizeof(buf), "%"PRId64, val); ++ return buf; ++ } ++ break; ++ ++ case ENUM: ++ { ++ int val = *(int *)value; ++ return type->enum_marshaller(val); + } + break; + +@@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, c + xmlNode *array_node = add_container(value_node, "array"); + + return add_container(array_node, "data"); +- ++} ++ ++ ++static xmlNode * ++add_nested_struct(xmlNode *struct_node, const char *name) ++{ ++ xmlNode *member_node = add_container(struct_node, "member"); ++ ++ xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name); ++ ++ xmlNode *value_node = add_container(member_node, "value"); ++ ++ return add_container(value_node, "struct"); + } + + diff --git a/13903-domctl.patch b/13903-domctl.patch new file mode 100644 index 0000000..86f5513 --- /dev/null +++ b/13903-domctl.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User kfraser@localhost.localdomain +# Date 1171456536 0 +# Node ID 929868cd37150106c4235657c959ac3376e95aa2 +# Parent d08c2af538045c16366ab5e5e99e1c4bd01f8223 +Add missing breaks to {set,get}_address_size domctls. +Signed-off-by: Gerd Hoffmann + +Index: xen-3.0.4-testing/xen/arch/x86/domctl.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/domctl.c ++++ xen-3.0.4-testing/xen/arch/x86/domctl.c +@@ -318,6 +318,7 @@ _long arch_do_domctl( + + put_domain(d); + } ++ break; + + case XEN_DOMCTL_get_address_size: + { +@@ -332,6 +333,7 @@ _long arch_do_domctl( + ret = 0; + put_domain(d); + } ++ break; + + default: + ret = -ENOSYS; diff --git a/13908-domctl.patch b/13908-domctl.patch new file mode 100644 index 0000000..1c32a82 --- /dev/null +++ b/13908-domctl.patch @@ -0,0 +1,22 @@ +# HG changeset patch +# User kfraser@localhost.localdomain +# Date 1171468487 0 +# Node ID d44eb9e7f97b05d648dc8b0d614ffb32df667354 +# Parent 6fd71faaaa3b00250d65879750e4350b79bf0060 +Another domctl fix to insert missing copy_to_guest. +Signed-off-by: Gerd Hoffmann + +Index: xen-3.0.4-testing/xen/arch/x86/domctl.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/domctl.c ++++ xen-3.0.4-testing/xen/arch/x86/domctl.c +@@ -332,6 +332,9 @@ _long arch_do_domctl( + + ret = 0; + put_domain(d); ++ ++ if ( copy_to_guest(u_domctl, domctl, 1) ) ++ ret = -EFAULT; + } + break; + diff --git a/init.xend b/init.xend index 1c16be4..5dc9859 100644 --- a/init.xend +++ b/init.xend @@ -100,9 +100,11 @@ case "$1" in # - netloop at network-bridge init time # - netbk and blkbk when the dom0 hotplug events occur # (in xen-network-common.sh and block-common.sh) + # - xenblk when xend prepares for bootloader # but for now it's safest to have them loaded when xend starts in dom0. modprobe blktap 2>/dev/null || true modprobe blkbk 2>/dev/null || true + modprobe xenblk 2>/dev/null || true modprobe netloop 2>/dev/null || true modprobe netbk 2>/dev/null || true xend start diff --git a/libelf-dominfo.diff b/libelf-dominfo.diff new file mode 100644 index 0000000..718b21f --- /dev/null +++ b/libelf-dominfo.diff @@ -0,0 +1,15 @@ +diff -r ad9bbd103034 xen/common/libelf/libelf-dominfo.c +--- a/xen/common/libelf/libelf-dominfo.c Fri Feb 09 18:19:24 2007 +0000 ++++ b/xen/common/libelf/libelf-dominfo.c Mon Feb 12 15:05:11 2007 +0100 +@@ -107,9 +107,9 @@ int elf_xen_parse_note(struct elf_binary + if ((type >= sizeof(note_desc) / sizeof(note_desc[0])) || + (NULL == note_desc[type].name)) + { +- elf_err(elf, "%s: unknown xen elf note (0x%x)\n", ++ elf_msg(elf, "%s: unknown xen elf note (0x%x)\n", + __FUNCTION__, type); +- return -1; ++ return 0; + } + + if (note_desc[type].str) diff --git a/libxc-logging.diff b/libxc-logging.diff deleted file mode 100644 index cb79485..0000000 --- a/libxc-logging.diff +++ /dev/null @@ -1,111 +0,0 @@ -debug: log libxc output to /var/log/xen/libxc.log - -sledge hammer patch ;) ---- - tools/libxc/xc_dom_compat_linux.c | 2 ++ - tools/libxc/xc_hvm_build.c | 2 ++ - tools/libxc/xc_linux_build.c | 2 ++ - tools/libxc/xc_private.c | 9 +++++++++ - tools/libxc/xc_private.h | 11 +++++++---- - 5 files changed, 22 insertions(+), 4 deletions(-) - -Index: build-64-release304-13087/tools/libxc/xc_hvm_build.c -=================================================================== ---- build-64-release304-13087.orig/tools/libxc/xc_hvm_build.c -+++ build-64-release304-13087/tools/libxc/xc_hvm_build.c -@@ -310,6 +310,8 @@ static int xc_hvm_build_internal(int xc_ - vcpu_guest_context_t ctxt; - int rc; - -+ log_kraxel(); -+ - if ( (image == NULL) || (image_size == 0) ) - { - ERROR("Image required"); -Index: build-64-release304-13087/tools/libxc/xc_linux_build.c -=================================================================== ---- build-64-release304-13087.orig/tools/libxc/xc_linux_build.c -+++ build-64-release304-13087/tools/libxc/xc_linux_build.c -@@ -1099,6 +1099,8 @@ static int xc_linux_build_internal(int x - unsigned long vstartinfo_start, vkern_entry, vstack_start; - uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; - -+ log_kraxel(); -+ - if ( features != NULL ) - { - if ( !parse_features(features, features_bitmap, NULL) ) -Index: build-64-release304-13087/tools/libxc/xc_private.c -=================================================================== ---- build-64-release304-13087.orig/tools/libxc/xc_private.c -+++ build-64-release304-13087/tools/libxc/xc_private.c -@@ -88,6 +88,15 @@ void xc_set_error(int code, const char * - error_handler(&last_error); - } - -+FILE *kraxel; -+ -+void log_kraxel(void) -+{ -+ kraxel = fopen("/var/log/xen/libxc.log", "a"); -+ setvbuf(kraxel, NULL, _IONBF, 0); -+ fprintf(kraxel, "--- started ---\n"); -+} -+ - int lock_pages(void *addr, size_t len) - { - int e = 0; -Index: build-64-release304-13087/tools/libxc/xc_private.h -=================================================================== ---- build-64-release304-13087.orig/tools/libxc/xc_private.h -+++ build-64-release304-13087/tools/libxc/xc_private.h -@@ -39,22 +39,25 @@ - - #define DEBUG 1 - #define INFO 1 --#define PROGRESS 0 -+#define PROGRESS 1 -+ -+extern FILE *kraxel; -+void log_kraxel(void); - - #if INFO --#define IPRINTF(_f, _a...) printf(_f , ## _a) -+#define IPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) - #else - #define IPRINTF(_f, _a...) ((void)0) - #endif - - #if DEBUG --#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) -+#define DPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) - #else - #define DPRINTF(_f, _a...) ((void)0) - #endif - - #if PROGRESS --#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) -+#define PPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) - #else - #define PPRINTF(_f, _a...) - #endif -Index: build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c -=================================================================== ---- build-64-release304-13087.orig/tools/libxc/xc_dom_compat_linux.c -+++ build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c -@@ -74,6 +74,7 @@ int xc_linux_build_mem(int xc_handle, ui - int rc; - - xc_dom_loginit(); -+ log_kraxel(); - dom = xc_dom_allocate(cmdline, features); - if (0 != (rc = xc_dom_kernel_mem(dom, image_buffer, image_size))) - goto out; -@@ -106,6 +107,7 @@ int xc_linux_build(int xc_handle, uint32 - int rc; - - xc_dom_loginit(); -+ log_kraxel(); - dom = xc_dom_allocate(cmdline, features); - if (0 != (rc = xc_dom_kernel_file(dom, image_name))) - goto out; diff --git a/libxen_permissive.patch b/libxen_permissive.patch new file mode 100644 index 0000000..2b14ae7 --- /dev/null +++ b/libxen_permissive.patch @@ -0,0 +1,20 @@ +diff -ru xen-3.0.4-testing-orig/tools/libxen/src/xen_common.c xen-3.0.4-testing/tools/libxen/src/xen_common.c +--- xen-3.0.4-testing-orig/tools/libxen/src/xen_common.c 2007-02-07 16:15:33.000000000 -0700 ++++ xen-3.0.4-testing/tools/libxen/src/xen_common.c 2007-02-09 11:08:37.000000000 -0700 +@@ -634,8 +634,15 @@ + 0 != strcmp((char *)value_node->children->name, "struct") || + value_node->children->children == NULL) + { ++#if PERMISSIVE ++ fprintf(stderr, ++ "Expected Map from the server, but didn't get one\n"); ++ ((arbitrary_map **)value)[slot] = NULL; ++#else ++ + server_error(s, + "Expected Map from the server, but didn't get it"); ++#endif + } + else + { +Only in xen-3.0.4-testing/tools/libxen/src: xen_common.c~ diff --git a/pae-guest-linear-pgtable.patch b/pae-guest-linear-pgtable.patch index 438ebb3..75055fb 100644 --- a/pae-guest-linear-pgtable.patch +++ b/pae-guest-linear-pgtable.patch @@ -1,6 +1,70 @@ +Index: 2007-01-31/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domain.c 2007-01-31 09:39:18.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domain.c 2007-02-15 15:10:02.000000000 +0100 +@@ -1337,7 +1337,8 @@ int hypercall_xlat_continuation(unsigned + } + #endif + +-static void relinquish_memory(struct domain *d, struct list_head *list) ++static void relinquish_memory(struct domain *d, struct list_head *list, ++ unsigned long type) + { + struct list_head *ent; + struct page_info *page; +@@ -1366,23 +1367,24 @@ static void relinquish_memory(struct dom + put_page(page); + + /* +- * Forcibly invalidate base page tables at this point to break circular +- * 'linear page table' references. This is okay because MMU structures +- * are not shared across domains and this domain is now dead. Thus base +- * tables are not in use so a non-zero count means circular reference. ++ * Forcibly invalidate top-most, still valid page tables at this point ++ * to break circular 'linear page table' references. This is okay ++ * because MMU structures are not shared across domains and this domain ++ * is now dead. Thus top-most valid tables are not in use so a non-zero ++ * count means circular reference. + */ + y = page->u.inuse.type_info; + for ( ; ; ) + { + x = y; + if ( likely((x & (PGT_type_mask|PGT_validated)) != +- (PGT_base_page_table|PGT_validated)) ) ++ (type|PGT_validated)) ) + break; + + y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated); + if ( likely(y == x) ) + { +- free_page_type(page, PGT_base_page_table); ++ free_page_type(page, type); + break; + } + } +@@ -1464,8 +1466,16 @@ void domain_relinquish_resources(struct + destroy_gdt(v); + + /* Relinquish every page of memory. */ +- relinquish_memory(d, &d->xenpage_list); +- relinquish_memory(d, &d->page_list); ++#if CONFIG_PAGING_LEVELS >= 4 ++ relinquish_memory(d, &d->xenpage_list, PGT_l4_page_table); ++ relinquish_memory(d, &d->page_list, PGT_l4_page_table); ++#endif ++#if CONFIG_PAGING_LEVELS >= 3 ++ relinquish_memory(d, &d->xenpage_list, PGT_l3_page_table); ++ relinquish_memory(d, &d->page_list, PGT_l3_page_table); ++#endif ++ relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table); ++ relinquish_memory(d, &d->page_list, PGT_l2_page_table); + + /* Free page used by xen oprofile buffer */ + free_xenoprof_pages(d); Index: 2007-01-31/xen/arch/x86/mm.c =================================================================== ---- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:43:38.000000000 +0100 +--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-02-15 15:02:01.000000000 +0100 +++ 2007-01-31/xen/arch/x86/mm.c 2007-02-02 16:34:03.000000000 +0100 @@ -509,7 +509,7 @@ get_linear_pagetable( return 0; diff --git a/tools-domain-builder-core.diff b/tools-domain-builder-core.diff index 77fd320..0fe9235 100644 --- a/tools-domain-builder-core.diff +++ b/tools-domain-builder-core.diff @@ -1,3066 +1,3066 @@ -libxc domain builder rewrite, core bits. - -Signed-off-by: Gerd Hoffmann ---- - tools/libxc/Makefile | 14 - tools/libxc/xc_dom.h | 261 +++++++++++++ - tools/libxc/xc_dom_binloader.c | 294 +++++++++++++++ - tools/libxc/xc_dom_boot.c | 592 +++++++++++++++++++++++++++++++ - tools/libxc/xc_dom_core.c | 776 +++++++++++++++++++++++++++++++++++++++++ - tools/libxc/xc_dom_elfloader.c | 283 ++++++++++++++ - tools/libxc/xc_dom_ia64.c | 119 ++++++ - tools/libxc/xc_dom_powerpc64.c | 100 +++++ - tools/libxc/xc_dom_x86.c | 561 +++++++++++++++++++++++++++++ - 9 files changed, 3000 insertions(+) - -Index: build-32-release304-13138/tools/libxc/Makefile -=================================================================== ---- build-32-release304-13138.orig/tools/libxc/Makefile -+++ build-32-release304-13138/tools/libxc/Makefile -@@ -44,6 +44,20 @@ $(LIBELF_SRCS) libelf-private.h: - # add libelf bits to libxc - GUEST_SRCS-y += $(LIBELF_SRCS) - -+# new domain builder -+GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c -+GUEST_SRCS-y += xc_dom_elfloader.c -+GUEST_SRCS-y += xc_dom_binloader.c -+ -+ifeq ($(CONFIG_POWERPC),y) -+# big endian boxes -+GUEST_SRCS-y += xc_dom_powerpc64.c -+else -+# little endian boxes -+GUEST_SRCS-y += xc_dom_x86.c -+GUEST_SRCS-y += xc_dom_ia64.c -+endif -+ - -include $(XEN_TARGET_ARCH)/Makefile - - CFLAGS += -Werror -Wmissing-prototypes -Index: build-32-release304-13138/tools/libxc/xc_dom.h -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom.h -@@ -0,0 +1,261 @@ -+#include -+ -+#define INVALID_P2M_ENTRY ((xen_pfn_t)-1) -+ -+/* --- typedefs and structs ---------------------------------------- */ -+ -+typedef uint64_t xen_vaddr_t; -+typedef uint64_t xen_paddr_t; -+ -+/* FIXME: temporary hack ... */ -+#ifndef PRIpfn -+#define PRIpfn "lx" -+#endif -+ -+struct xc_dom_seg { -+ xen_vaddr_t vstart; -+ xen_vaddr_t vend; -+ xen_pfn_t pfn; -+}; -+ -+struct xc_dom_mem { -+ struct xc_dom_mem *next; -+ void *mmap_ptr; -+ size_t mmap_len; -+ unsigned char memory[0]; -+}; -+ -+struct xc_dom_phys { -+ struct xc_dom_phys *next; -+ void *ptr; -+ xen_pfn_t first; -+ xen_pfn_t count; -+}; -+ -+struct xc_dom_image { -+ /* files */ -+ void *kernel_blob; -+ size_t kernel_size; -+ void *ramdisk_blob; -+ size_t ramdisk_size; -+ -+ /* arguments and parameters */ -+ char *cmdline; -+ uint32_t f_requested[XENFEAT_NR_SUBMAPS]; -+ -+ /* info from (elf) kernel image */ -+ struct elf_dom_parms parms; -+ char *guest_type; -+ -+ /* memory layout */ -+ struct xc_dom_seg kernel_seg; -+ struct xc_dom_seg ramdisk_seg; -+ struct xc_dom_seg p2m_seg; -+ struct xc_dom_seg pgtables_seg; -+ xen_pfn_t start_info_pfn; -+ xen_pfn_t console_pfn; -+ xen_pfn_t xenstore_pfn; -+ xen_pfn_t shared_info_pfn; -+ xen_pfn_t bootstack_pfn; -+ xen_vaddr_t virt_alloc_end; -+ xen_vaddr_t bsd_symtab_start; -+ -+ /* initial page tables */ -+ unsigned int pgtables; -+ unsigned int pg_l4; -+ unsigned int pg_l3; -+ unsigned int pg_l2; -+ unsigned int pg_l1; -+ unsigned int alloc_bootstack; -+ unsigned int extra_pages; -+ xen_vaddr_t virt_pgtab_end; -+ -+ /* other state info */ -+ uint32_t f_active[XENFEAT_NR_SUBMAPS]; -+ xen_pfn_t *p2m_host; -+ void *p2m_guest; -+ -+ /* physical memory */ -+ xen_pfn_t total_pages; -+ struct xc_dom_phys *phys_pages; -+ -+ /* malloc memory pool */ -+ struct xc_dom_mem *memblocks; -+ -+ /* memory footprint stats */ -+ size_t alloc_malloc; -+ size_t alloc_mem_map; -+ size_t alloc_file_map; -+ size_t alloc_domU_map; -+ -+ /* misc xen domain config stuff */ -+ unsigned long flags; -+ unsigned int console_evtchn; -+ unsigned int xenstore_evtchn; -+ xen_pfn_t shared_info_mfn; -+ -+ int guest_xc; -+ domid_t guest_domid; -+ int shadow_enabled; -+ -+ int xen_version; -+ xen_capabilities_info_t xen_caps; -+ -+ /* kernel loader, arch hooks */ -+ struct xc_dom_loader *kernel_loader; -+ void *private_loader; -+ -+ /* kernel loader */ -+ struct xc_dom_arch *arch_hooks; -+}; -+ -+/* --- pluggable kernel loader ------------------------------------- */ -+ -+struct xc_dom_loader { -+ char *name; -+ int (*probe) (struct xc_dom_image * dom); -+ int (*parser) (struct xc_dom_image * dom); -+ int (*loader) (struct xc_dom_image * dom); -+ -+ struct xc_dom_loader *next; -+}; -+ -+#define __init __attribute__ ((constructor)) -+void xc_dom_register_loader(struct xc_dom_loader *loader); -+ -+/* --- arch specific hooks ----------------------------------------- */ -+ -+struct xc_dom_arch { -+ /* pagetable setup */ -+ int (*alloc_magic_pages) (struct xc_dom_image * dom); -+ int (*count_pgtables) (struct xc_dom_image * dom); -+ int (*setup_pgtables) (struct xc_dom_image * dom); -+ -+ /* arch-specific data structs setup */ -+ int (*start_info) (struct xc_dom_image * dom); -+ int (*shared_info) (struct xc_dom_image * dom, void *shared_info); -+ int (*vcpu) (struct xc_dom_image * dom, void *vcpu_ctxt); -+ -+ char *guest_type; -+ int page_shift; -+ int sizeof_pfn; -+ -+ struct xc_dom_arch *next; -+}; -+void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks); -+ -+#define XC_DOM_PAGE_SHIFT(dom) ((dom)->arch_hooks->page_shift) -+#define XC_DOM_PAGE_SIZE(dom) (1 << (dom)->arch_hooks->page_shift) -+ -+/* --- main functions ---------------------------------------------- */ -+ -+struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features); -+void xc_dom_release_phys(struct xc_dom_image *dom); -+void xc_dom_release(struct xc_dom_image *dom); -+int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb); -+ -+size_t xc_dom_check_gzip(void *blob, size_t ziplen); -+int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen); -+int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size); -+ -+int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename); -+int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename); -+int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, -+ size_t memsize); -+int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, -+ size_t memsize); -+ -+int xc_dom_parse_image(struct xc_dom_image *dom); -+int xc_dom_build_image(struct xc_dom_image *dom); -+int xc_dom_update_guest_p2m(struct xc_dom_image *dom); -+ -+int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid); -+int xc_dom_boot_mem_init(struct xc_dom_image *dom); -+void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, -+ xen_pfn_t count); -+int xc_dom_boot_image(struct xc_dom_image *dom); -+int xc_dom_compat_check(struct xc_dom_image *dom); -+ -+/* --- debugging bits ---------------------------------------------- */ -+ -+extern FILE *xc_dom_logfile; -+ -+void xc_dom_loginit(void); -+int xc_dom_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); -+int xc_dom_panic_func(const char *file, int line, xc_error_code err, -+ const char *fmt, ...) -+ __attribute__ ((format(printf, 4, 5))); -+#define xc_dom_panic(err, fmt, args...) \ -+ xc_dom_panic_func(__FILE__, __LINE__, err, fmt, ## args) -+#define xc_dom_trace(mark) \ -+ xc_dom_printf("%s:%d: trace %s\n", __FILE__, __LINE__, mark) -+ -+void xc_dom_log_memory_footprint(struct xc_dom_image *dom); -+ -+/* --- simple memory pool ------------------------------------------ */ -+ -+void *xc_dom_malloc(struct xc_dom_image *dom, size_t size); -+void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size); -+void *xc_dom_malloc_filemap(struct xc_dom_image *dom, -+ const char *filename, size_t * size); -+char *xc_dom_strdup(struct xc_dom_image *dom, const char *str); -+ -+/* --- alloc memory pool ------------------------------------------- */ -+ -+int xc_dom_alloc_page(struct xc_dom_image *dom, char *name); -+int xc_dom_alloc_segment(struct xc_dom_image *dom, -+ struct xc_dom_seg *seg, char *name, -+ xen_vaddr_t start, xen_vaddr_t size); -+ -+/* --- misc bits --------------------------------------------------- */ -+ -+void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first, -+ xen_pfn_t count); -+void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn); -+void xc_dom_unmap_all(struct xc_dom_image *dom); -+ -+static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom, -+ struct xc_dom_seg *seg) -+{ -+ xen_vaddr_t segsize = seg->vend - seg->vstart; -+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); -+ xen_pfn_t pages = (segsize + page_size - 1) / page_size; -+ -+ return xc_dom_pfn_to_ptr(dom, seg->pfn, pages); -+} -+ -+static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom, -+ xen_vaddr_t vaddr) -+{ -+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); -+ xen_pfn_t page = (vaddr - dom->parms.virt_base) / page_size; -+ unsigned int offset = (vaddr - dom->parms.virt_base) % page_size; -+ void *ptr = xc_dom_pfn_to_ptr(dom, page, 0); -+ -+ if (!ptr) -+ return NULL; -+ return ptr + offset; -+} -+ -+static inline int xc_dom_feature_translated(struct xc_dom_image *dom) -+{ -+ return elf_xen_feature_get(XENFEAT_auto_translated_physmap, dom->f_active); -+} -+ -+static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn) -+{ -+ if (dom->shadow_enabled) -+ return pfn; -+ return dom->p2m_host[pfn]; -+} -+ -+static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom, -+ xen_pfn_t pfn) -+{ -+ if (xc_dom_feature_translated(dom)) -+ return pfn; -+ return dom->p2m_host[pfn]; -+} -+ -+/* --- arch bits --------------------------------------------------- */ -+ -Index: build-32-release304-13138/tools/libxc/xc_dom_boot.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_boot.c -@@ -0,0 +1,592 @@ -+/* -+ * Xen domain builder -- xen booter. -+ * -+ * This is the code which actually boots a fresh -+ * prepared domain image as xen guest domain. -+ * -+ * ==> this is the only domain bilder code piece -+ * where xen hypercalls are allowed <== -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+#include -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int setup_hypercall_page(struct xc_dom_image *dom) -+{ -+ DECLARE_DOMCTL; -+ xen_pfn_t pfn; -+ int rc; -+ -+ if (-1 == dom->parms.virt_hypercall) -+ return 0; -+ pfn = (dom->parms.virt_hypercall - dom->parms.virt_base) -+ >> XC_DOM_PAGE_SHIFT(dom); -+ -+ xc_dom_printf("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "\n", __FUNCTION__, -+ dom->parms.virt_hypercall, pfn); -+ domctl.cmd = XEN_DOMCTL_hypercall_init; -+ domctl.domain = dom->guest_domid; -+ domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn); -+ rc = do_domctl(dom->guest_xc, &domctl); -+ if (0 != rc) -+ xc_dom_panic(XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)\n", -+ __FUNCTION__, rc); -+ return rc; -+} -+ -+static int launch_vm(int xc, domid_t domid, void *ctxt) -+{ -+ DECLARE_DOMCTL; -+ int rc; -+ -+ xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt); -+ memset(&domctl, 0, sizeof(domctl)); -+ domctl.cmd = XEN_DOMCTL_setvcpucontext; -+ domctl.domain = domid; -+ domctl.u.vcpucontext.vcpu = 0; -+ set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); -+ rc = do_domctl(xc, &domctl); -+ if (0 != rc) -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc); -+ return rc; -+} -+ -+static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn) -+{ -+ xen_pfn_t dst; -+ int rc; -+ -+ if (0 == pfn) -+ return 0; -+ -+ dst = xc_dom_p2m_host(dom, pfn); -+ xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", -+ __FUNCTION__, pfn, dst); -+ rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst); -+ if (0 != rc) -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn -+ ", rc=%d)\n", __FUNCTION__, pfn, rc); -+ return rc; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* arch stuff: x86 bits */ -+ -+#if defined(__i386__) || defined(__x86_64__) -+ -+static int x86_compat(int xc, domid_t domid, char *guest_type) -+{ -+#if defined(XEN_DOMCTL_set_address_size) -+ -+ /* stable api, 3.0.5 final */ -+ static const struct { -+ char *guest; -+ uint32_t size; -+ } types[] = { -+ { "xen-3.0-x86_32p", 32 }, -+ { "xen-3.0-x86_64", 64 }, -+ }; -+ DECLARE_DOMCTL; -+ int i,rc; -+ -+ memset(&domctl, 0, sizeof(domctl)); -+ domctl.domain = domid; -+ domctl.cmd = XEN_DOMCTL_set_address_size; -+ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) -+ if (0 == strcmp(types[i].guest, guest_type)) -+ domctl.u.address_size.size = types[i].size; -+ if (0 == domctl.u.address_size.size) -+ /* nothing to do */ -+ return 0; -+ -+ xc_dom_printf("%s: guest %s, address size %" PRId32 "\n", __FUNCTION__, -+ guest_type, domctl.u.address_size.size); -+ rc = do_domctl(xc, &domctl); -+ if (0 != rc) -+ xc_dom_printf("%s: warning: failed (rc=%d)\n", -+ __FUNCTION__, rc); -+ return rc; -+ -+#elif defined(XEN_DOMCTL_set_compat) -+ -+ /* temporary, 3.0.4 patches and 3.0.5 initial merge */ -+ static const struct { -+ char *guest; -+ unsigned long cmd; -+ } types[] = { -+ { "xen-3.0-x86_32p", XEN_DOMCTL_set_compat }, -+ { "xen-3.0-x86_64", XEN_DOMCTL_set_native }, -+ }; -+ DECLARE_DOMCTL; -+ int i,rc; -+ -+ memset(&domctl, 0, sizeof(domctl)); -+ domctl.domain = domid; -+ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) -+ if (0 == strcmp(types[i].guest, guest_type)) -+ domctl.cmd = types[i].cmd; -+ if (0 == domctl.cmd) -+ /* nothing to do */ -+ return 0; -+ -+ xc_dom_printf("%s: guest %s, cmd %d\n", __FUNCTION__, -+ guest_type, domctl.cmd); -+ rc = do_domctl(xc, &domctl); -+ if (0 != rc) -+ xc_dom_printf("%s: warning: failed (rc=%d)\n", -+ __FUNCTION__, rc); -+ return rc; -+ -+#else -+#warn compiling without compat/native switching -+ xc_dom_printf("%s: compiled without compat/native switching\n", __FUNCTION__); -+ return 0; -+#endif -+} -+ -+ -+static int x86_shadow(int xc, domid_t domid) -+{ -+ int rc, mode; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ mode = XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | -+ XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE; -+ -+ rc = xc_shadow_control(xc, domid, -+ XEN_DOMCTL_SHADOW_OP_ENABLE, -+ NULL, 0, NULL, mode, NULL); -+ if (0 != rc) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: SHADOW_OP_ENABLE (mode=0x%x) failed (rc=%d)\n", -+ __FUNCTION__, mode, rc); -+ return rc; -+ } -+ xc_dom_printf("%s: shadow enabled (mode=0x%x)\n", __FUNCTION__, mode); -+ return rc; -+} -+ -+static int arch_setup_meminit(struct xc_dom_image *dom) -+{ -+ int rc = 0; -+ -+ x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type); -+ if (xc_dom_feature_translated(dom)) -+ { -+ dom->shadow_enabled = 1; -+ rc = x86_shadow(dom->guest_xc, dom->guest_domid); -+ } -+ return rc; -+} -+ -+static int arch_setup_bootearly(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootlate(struct xc_dom_image *dom) -+{ -+ static const struct { -+ char *guest; -+ unsigned long pgd_type; -+ } types[] = { -+ { "xen-3.0-x86_32", MMUEXT_PIN_L2_TABLE}, -+ { "xen-3.0-x86_32p", MMUEXT_PIN_L3_TABLE}, -+ { "xen-3.0-x86_64", MMUEXT_PIN_L4_TABLE}, -+ }; -+ unsigned long pgd_type = 0; -+ shared_info_t *shared_info; -+ xen_pfn_t shinfo; -+ int i, rc; -+ -+ for (i = 0; i < sizeof(types) / sizeof(types[0]); i++) -+ if (0 == strcmp(types[i].guest, dom->guest_type)) -+ pgd_type = types[i].pgd_type; -+ -+ if (!xc_dom_feature_translated(dom)) -+ { -+ /* paravirtualized guest */ -+ xc_dom_unmap_one(dom, dom->pgtables_seg.pfn); -+ rc = pin_table(dom->guest_xc, pgd_type, -+ xc_dom_p2m_host(dom, dom->pgtables_seg.pfn), -+ dom->guest_domid); -+ if (0 != rc) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: pin_table failed (pfn 0x%" PRIpfn ", rc=%d)\n", -+ __FUNCTION__, dom->pgtables_seg.pfn, rc); -+ return rc; -+ } -+ shinfo = dom->shared_info_mfn; -+ } -+ else -+ { -+ /* paravirtualized guest with auto-translation */ -+ struct xen_add_to_physmap xatp; -+ int i; -+ -+ /* Map shared info frame into guest physmap. */ -+ xatp.domid = dom->guest_domid; -+ xatp.space = XENMAPSPACE_shared_info; -+ xatp.idx = 0; -+ xatp.gpfn = dom->shared_info_pfn; -+ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); -+ if (rc != 0) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed " -+ "(pfn=0x%" PRIpfn ", rc=%d)\n", -+ __FUNCTION__, xatp.gpfn, rc); -+ return rc; -+ } -+ -+ /* Map grant table frames into guest physmap. */ -+ for (i = 0;; i++) -+ { -+ xatp.domid = dom->guest_domid; -+ xatp.space = XENMAPSPACE_grant_table; -+ xatp.idx = i; -+ xatp.gpfn = dom->total_pages + i; -+ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); -+ if (rc != 0) -+ { -+ if (i > 0 && errno == EINVAL) -+ { -+ xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__, -+ i); -+ break; -+ } -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: mapping grant tables failed " "(pfn=0x%" -+ PRIpfn ", rc=%d)\n", __FUNCTION__, xatp.gpfn, rc); -+ return rc; -+ } -+ } -+ shinfo = dom->shared_info_pfn; -+ } -+ -+ /* setup shared_info page */ -+ xc_dom_printf("%s: shared_info: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", -+ __FUNCTION__, dom->shared_info_pfn, dom->shared_info_mfn); -+ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, -+ PAGE_SIZE_X86, -+ PROT_READ | PROT_WRITE, -+ shinfo); -+ if (NULL == shared_info) -+ return -1; -+ dom->arch_hooks->shared_info(dom, shared_info); -+ munmap(shared_info, PAGE_SIZE_X86); -+ -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* arch stuff: ia64 */ -+ -+#elif defined(__ia64__) -+ -+static int arch_setup_meminit(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootearly(struct xc_dom_image *dom) -+{ -+ DECLARE_DOMCTL; -+ int rc; -+ -+ xc_dom_printf("%s: setup firmware\n", __FUNCTION__); -+ -+ memset(&domctl, 0, sizeof(domctl)); -+ domctl.cmd = XEN_DOMCTL_arch_setup; -+ domctl.domain = dom->guest_domid; -+ domctl.u.arch_setup.flags = 0; -+ -+ domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT) -+ + sizeof(start_info_t); -+ /* 3 = start info page, xenstore page and console page */ -+ domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT; -+ rc = do_domctl(dom->guest_xc, &domctl); -+ return rc; -+} -+ -+static int arch_setup_bootlate(struct xc_dom_image *dom) -+{ -+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); -+ shared_info_t *shared_info; -+ -+ /* setup shared_info page */ -+ xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n", -+ __FUNCTION__, dom->shared_info_mfn); -+ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, -+ page_size, -+ PROT_READ | PROT_WRITE, -+ dom->shared_info_mfn); -+ if (NULL == shared_info) -+ return -1; -+ dom->arch_hooks->shared_info(dom, shared_info); -+ munmap(shared_info, page_size); -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* arch stuff: powerpc */ -+ -+#elif defined(__powerpc64__) -+ -+static int arch_setup_meminit(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootearly(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootlate(struct xc_dom_image *dom) -+{ -+ start_info_t *si = -+ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); -+ -+ xc_dom_printf("%s: TODO: setup devtree\n", __FUNCTION__); -+ -+#if 0 -+ load_devtree(dom->guest_xc, -+ dom->guest_domid, -+ dom->p2m_host, -+ devtree, // FIXME -+ devtree_addr, // FIXME -+ dom->ramdisk_seg.vstart, -+ dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart, -+ si, -+ dom->start_info_pfn << PAGE_SHIFT); -+#endif -+ return rc; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* arch stuff: other */ -+ -+#else -+ -+static int arch_setup_meminit(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootearly(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+static int arch_setup_bootlate(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); -+ return 0; -+} -+ -+#endif /* arch stuff */ -+ -+/* ------------------------------------------------------------------------ */ -+ -+int xc_dom_compat_check(struct xc_dom_image *dom) -+{ -+ xen_capabilities_info_t xen_caps; -+ char *item, *ptr; -+ int match, found = 0; -+ -+ strcpy(xen_caps, dom->xen_caps); -+ for (item = strtok_r(xen_caps, " ", &ptr); -+ NULL != item; item = strtok_r(NULL, " ", &ptr)) -+ { -+ match = (0 == strcmp(dom->guest_type, item)); -+ xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__, -+ item, match ? " <= matches" : ""); -+ if (match) -+ found++; -+ } -+ if (!found) -+ xc_dom_panic(XC_INVALID_KERNEL, -+ "%s: guest type %s not supported by xen kernel, sorry\n", -+ __FUNCTION__, dom->guest_type); -+ -+ return found; -+} -+ -+int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid) -+{ -+ dom->guest_xc = xc; -+ dom->guest_domid = domid; -+ -+ dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL); -+ if (xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0) { -+ xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities"); -+ return -1; -+ } -+ xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__, -+ dom->xen_version >> 16, dom->xen_version & 0xff, -+ dom->xen_caps); -+ return 0; -+} -+ -+int xc_dom_boot_mem_init(struct xc_dom_image *dom) -+{ -+ long rc; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ if (0 != (rc = arch_setup_meminit(dom))) -+ return rc; -+ -+ /* allocate guest memory */ -+ rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, -+ dom->total_pages, 0, 0, -+ dom->p2m_host); -+ if (0 != rc) -+ { -+ xc_dom_panic(XC_OUT_OF_MEMORY, -+ "%s: can't allocate low memory for domain\n", -+ __FUNCTION__); -+ return rc; -+ } -+ -+ return 0; -+} -+ -+void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, -+ xen_pfn_t count) -+{ -+ int page_shift = XC_DOM_PAGE_SHIFT(dom); -+ privcmd_mmap_entry_t *entries; -+ void *ptr; -+ int i, rc; -+ -+ entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); -+ if (NULL == entries) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn -+ " [malloc]\n", __FUNCTION__, pfn, count); -+ return NULL; -+ } -+ -+ ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE, -+ MAP_SHARED, dom->guest_xc, 0); -+ if (MAP_FAILED == ptr) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn -+ " [mmap]\n", __FUNCTION__, pfn, count); -+ return NULL; -+ } -+ -+ for (i = 0; i < count; i++) -+ { -+ entries[i].va = (uintptr_t) ptr + (i << page_shift); -+ entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); -+ entries[i].npages = 1; -+ } -+ -+ rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, entries, count); -+ if (rc < 0) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn -+ " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc); -+ return NULL; -+ } -+ return ptr; -+} -+ -+int xc_dom_boot_image(struct xc_dom_image *dom) -+{ -+ DECLARE_DOMCTL; -+ void *ctxt; -+ int rc; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* misc ia64 stuff*/ -+ if (0 != (rc = arch_setup_bootearly(dom))) -+ return rc; -+ -+ /* collect some info */ -+ domctl.cmd = XEN_DOMCTL_getdomaininfo; -+ domctl.domain = dom->guest_domid; -+ rc = do_domctl(dom->guest_xc, &domctl); -+ if (0 != rc) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: getdomaininfo failed (rc=%d)\n", __FUNCTION__, rc); -+ return rc; -+ } -+ if (domctl.domain != dom->guest_domid) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: Huh? domid mismatch (%d != %d)\n", __FUNCTION__, -+ domctl.domain, dom->guest_domid); -+ return -1; -+ } -+ dom->shared_info_mfn = domctl.u.getdomaininfo.shared_info_frame; -+ -+ /* sanity checks */ -+ if (!xc_dom_compat_check(dom)) -+ return -1; -+ -+ /* initial mm setup */ -+ if (0 != (rc = xc_dom_update_guest_p2m(dom))) -+ return rc; -+ if (dom->arch_hooks->setup_pgtables) -+ if (0 != (rc = dom->arch_hooks->setup_pgtables(dom))) -+ return rc; -+ -+ if (0 != (rc = clear_page(dom, dom->console_pfn))) -+ return rc; -+ if (0 != (rc = clear_page(dom, dom->xenstore_pfn))) -+ return rc; -+ -+ /* start info page */ -+ if (dom->arch_hooks->start_info) -+ dom->arch_hooks->start_info(dom); -+ -+ /* hypercall page */ -+ if (0 != (rc = setup_hypercall_page(dom))) -+ return rc; -+ xc_dom_log_memory_footprint(dom); -+ -+ /* misc x86 stuff */ -+ if (0 != (rc = arch_setup_bootlate(dom))) -+ return rc; -+ -+ /* let the vm run */ -+ ctxt = xc_dom_malloc(dom, PAGE_SIZE * 2 /* FIXME */ ); -+ memset(ctxt, 0, PAGE_SIZE * 2); -+ if (0 != (rc = dom->arch_hooks->vcpu(dom, ctxt))) -+ return rc; -+ xc_dom_unmap_all(dom); -+ rc = launch_vm(dom->guest_xc, dom->guest_domid, ctxt); -+ -+ return rc; -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_core.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_core.c -@@ -0,0 +1,776 @@ -+/* -+ * Xen domain builder -- core bits. -+ * -+ * The core code goes here: -+ * - allocate and release domain structs. -+ * - memory management functions. -+ * - misc helper functions. -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+/* ------------------------------------------------------------------------ */ -+/* debugging */ -+ -+FILE *xc_dom_logfile = NULL; -+ -+void xc_dom_loginit(void) -+{ -+ if (xc_dom_logfile) -+ return; -+ xc_dom_logfile = fopen("/var/log/xen/domain-builder-ng.log", "a"); -+ setvbuf(xc_dom_logfile, NULL, _IONBF, 0); -+ xc_dom_printf("### ----- xc domain builder logfile opened -----\n"); -+} -+ -+int xc_dom_printf(const char *fmt, ...) -+{ -+ va_list args; -+ char buf[1024]; -+ int rc; -+ -+ if (!xc_dom_logfile) -+ return 0; -+ -+ va_start(args, fmt); -+ rc = vsnprintf(buf, sizeof(buf), fmt, args); -+ va_end(args); -+ rc = fwrite(buf, rc, 1, xc_dom_logfile); -+ -+ return rc; -+} -+ -+int xc_dom_panic_func(const char *file, int line, xc_error_code err, -+ const char *fmt, ...) -+{ -+ va_list args; -+ FILE *fp = stderr; -+ int rc = 0; -+ char pos[256]; -+ char msg[XC_MAX_ERROR_MSG_LEN]; -+ -+ if (xc_dom_logfile) -+ fp = xc_dom_logfile; -+ -+ snprintf(pos, sizeof(pos), "%s:%d: panic: ", file, line); -+ va_start(args, fmt); -+ vsnprintf(msg, sizeof(msg), fmt, args); -+ va_end(args); -+ xc_set_error(err, "%s", msg); -+ rc = fprintf(fp, "%s%s", pos, msg); -+ return rc; -+} -+ -+static void print_mem(const char *name, size_t mem) -+{ -+ if (mem > 32 * 1024 * 1024) -+ xc_dom_printf("%-24s : %zd MB\n", name, mem / (1024 * 1024)); -+ else if (mem > 32 * 1024) -+ xc_dom_printf("%-24s : %zd kB\n", name, mem / 1024); -+ else -+ xc_dom_printf("%-24s : %zd bytes\n", name, mem); -+} -+ -+void xc_dom_log_memory_footprint(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("domain builder memory footprint\n"); -+ xc_dom_printf(" allocated\n"); -+ print_mem(" malloc", dom->alloc_malloc); -+ print_mem(" anon mmap", dom->alloc_mem_map); -+ xc_dom_printf(" mapped\n"); -+ print_mem(" file mmap", dom->alloc_file_map); -+ print_mem(" domU mmap", dom->alloc_domU_map); -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* simple memory pool */ -+ -+void *xc_dom_malloc(struct xc_dom_image *dom, size_t size) -+{ -+ struct xc_dom_mem *block; -+ -+ block = malloc(sizeof(*block) + size); -+ if (NULL == block) -+ return NULL; -+ memset(block, 0, sizeof(*block) + size); -+ block->next = dom->memblocks; -+ dom->memblocks = block; -+ dom->alloc_malloc += sizeof(*block) + size; -+ if (size > 100 * 1024) -+ print_mem(__FUNCTION__, size); -+ return block->memory; -+} -+ -+void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size) -+{ -+ struct xc_dom_mem *block; -+ -+ block = malloc(sizeof(*block)); -+ if (NULL == block) -+ return NULL; -+ memset(block, 0, sizeof(*block)); -+ block->mmap_len = size; -+ block->mmap_ptr = mmap(NULL, block->mmap_len, -+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -+ -1, 0); -+ if (MAP_FAILED == block->mmap_ptr) -+ { -+ free(block); -+ return NULL; -+ } -+ block->next = dom->memblocks; -+ dom->memblocks = block; -+ dom->alloc_malloc += sizeof(*block); -+ dom->alloc_mem_map += block->mmap_len; -+ if (size > 100 * 1024) -+ print_mem(__FUNCTION__, size); -+ return block->mmap_ptr; -+} -+ -+void *xc_dom_malloc_filemap(struct xc_dom_image *dom, -+ const char *filename, size_t * size) -+{ -+ struct xc_dom_mem *block = NULL; -+ int fd = -1; -+ -+ fd = open(filename, O_RDONLY); -+ if (-1 == fd) -+ goto err; -+ -+ lseek(fd, 0, SEEK_SET); -+ *size = lseek(fd, 0, SEEK_END); -+ -+ block = malloc(sizeof(*block)); -+ if (NULL == block) -+ goto err; -+ memset(block, 0, sizeof(*block)); -+ block->mmap_len = *size; -+ block->mmap_ptr = mmap(NULL, block->mmap_len, PROT_READ, MAP_SHARED, fd, 0); -+ if (MAP_FAILED == block->mmap_ptr) -+ goto err; -+ block->next = dom->memblocks; -+ dom->memblocks = block; -+ dom->alloc_malloc += sizeof(*block); -+ dom->alloc_file_map += block->mmap_len; -+ close(fd); -+ if (*size > 100 * 1024) -+ print_mem(__FUNCTION__, *size); -+ return block->mmap_ptr; -+ -+ err: -+ if (-1 != fd) -+ close(fd); -+ if (block) -+ free(block); -+ return NULL; -+} -+ -+static void xc_dom_free_all(struct xc_dom_image *dom) -+{ -+ struct xc_dom_mem *block; -+ -+ while (NULL != (block = dom->memblocks)) -+ { -+ dom->memblocks = block->next; -+ if (block->mmap_ptr) -+ munmap(block->mmap_ptr, block->mmap_len); -+ free(block); -+ } -+} -+ -+char *xc_dom_strdup(struct xc_dom_image *dom, const char *str) -+{ -+ size_t len = strlen(str) + 1; -+ char *nstr = xc_dom_malloc(dom, len); -+ -+ if (NULL == nstr) -+ return NULL; -+ memcpy(nstr, str, len); -+ return nstr; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* read files, copy memory blocks, with transparent gunzip */ -+ -+size_t xc_dom_check_gzip(void *blob, size_t ziplen) -+{ -+ unsigned char *gzlen; -+ size_t unziplen; -+ -+ if (0 != strncmp(blob, "\037\213", 2)) -+ /* not gzipped */ -+ return 0; -+ -+ gzlen = blob + ziplen - 4; -+ unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0]; -+ if (unziplen < ziplen || unziplen > ziplen * 8) -+ { -+ xc_dom_printf -+ ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n", -+ __FUNCTION__, ziplen, unziplen); -+ return 0; -+ } -+ -+ return unziplen + 16; -+} -+ -+int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen) -+{ -+ z_stream zStream; -+ int rc; -+ -+ memset(&zStream, 0, sizeof(zStream)); -+ zStream.next_in = src; -+ zStream.avail_in = srclen; -+ zStream.next_out = dst; -+ zStream.avail_out = dstlen; -+ rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" */ -+ if (rc != Z_OK) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc); -+ return -1; -+ } -+ rc = inflate(&zStream, Z_FINISH); -+ if (rc != Z_STREAM_END) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc); -+ return -1; -+ } -+ -+ xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n", -+ __FUNCTION__, srclen, dstlen); -+ return 0; -+} -+ -+int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size) -+{ -+ void *unzip; -+ size_t unziplen; -+ -+ unziplen = xc_dom_check_gzip(*blob, *size); -+ if (0 == unziplen) -+ return 0; -+ -+ unzip = xc_dom_malloc(dom, unziplen); -+ if (NULL == unzip) -+ return -1; -+ -+ if (-1 == xc_dom_do_gunzip(*blob, *size, unzip, unziplen)) -+ return -1; -+ -+ *blob = unzip; -+ *size = unziplen; -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* domain memory */ -+ -+void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn, -+ xen_pfn_t count) -+{ -+ struct xc_dom_phys *phys; -+ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); -+ char *mode = "unset"; -+ -+ if (pfn > dom->total_pages) -+ { -+ xc_dom_printf("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")\n", -+ __FUNCTION__, pfn, dom->total_pages); -+ return NULL; -+ } -+ -+ /* already allocated? */ -+ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) -+ { -+ if (pfn >= phys->first + phys->count) -+ continue; -+ if (count) -+ { -+ /* size given: must be completely within the already allocated block */ -+ if (pfn + count <= phys->first) -+ continue; -+ if (pfn < phys->first || pfn + count > phys->first + phys->count) -+ { -+ xc_dom_printf("%s: request overlaps allocated block" -+ " (req 0x%" PRIpfn "+0x%" PRIpfn "," -+ " blk 0x%" PRIpfn "+0x%" PRIpfn ")\n", -+ __FUNCTION__, pfn, count, phys->first, -+ phys->count); -+ return NULL; -+ } -+ } -+ else -+ { -+ /* no size given: block must be allocated already, -+ just hand out a pointer to it */ -+ if (pfn < phys->first) -+ continue; -+ } -+ return phys->ptr + ((pfn - phys->first) << page_shift); -+ } -+ -+ /* allocating is allowed with size specified only */ -+ if (0 == count) -+ { -+ xc_dom_printf("%s: no block found, no size given," -+ " can't malloc (pfn 0x%" PRIpfn ")\n", __FUNCTION__, pfn); -+ return NULL; -+ } -+ -+ /* not found, no overlap => allocate */ -+ phys = xc_dom_malloc(dom, sizeof(*phys)); -+ if (NULL == phys) -+ return NULL; -+ memset(phys, 0, sizeof(*phys)); -+ phys->first = pfn; -+ phys->count = count; -+ -+ if (dom->guest_domid) -+ { -+ mode = "domU mapping"; -+ phys->ptr = xc_dom_boot_domU_map(dom, phys->first, phys->count); -+ if (NULL == phys->ptr) -+ return NULL; -+ dom->alloc_domU_map += phys->count << page_shift; -+ } -+ else -+ { -+ mode = "anonymous memory"; -+ phys->ptr = mmap(NULL, phys->count << page_shift, -+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -+ -1, 0); -+ if (MAP_FAILED == phys->ptr) -+ { -+ xc_dom_panic(XC_OUT_OF_MEMORY, -+ "%s: oom: can't allocate 0x%" PRIpfn " pages\n", -+ __FUNCTION__, count); -+ return NULL; -+ } -+ dom->alloc_mem_map += phys->count << page_shift; -+ } -+ -+#if 1 -+ xc_dom_printf("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p\n", -+ __FUNCTION__, mode, phys->first, phys->count, phys->ptr); -+#endif -+ phys->next = dom->phys_pages; -+ dom->phys_pages = phys; -+ return phys->ptr; -+} -+ -+int xc_dom_alloc_segment(struct xc_dom_image *dom, -+ struct xc_dom_seg *seg, char *name, -+ xen_vaddr_t start, xen_vaddr_t size) -+{ -+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); -+ xen_pfn_t pages = (size + page_size - 1) / page_size; -+ void *ptr; -+ -+ if (0 == start) -+ start = dom->virt_alloc_end; -+ -+ if (start & (page_size - 1)) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: segment start isn't page aligned (0x%" PRIx64 ")\n", -+ __FUNCTION__, start); -+ return -1; -+ } -+ if (start < dom->virt_alloc_end) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64 -+ ")\n", __FUNCTION__, start, dom->virt_alloc_end); -+ return -1; -+ } -+ -+ seg->vstart = start; -+ seg->vend = start + pages * page_size; -+ seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size; -+ dom->virt_alloc_end = seg->vend; -+ -+ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " -> 0x%" PRIx64 -+ " (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n", -+ __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages); -+ -+ /* map and clear pages */ -+ ptr = xc_dom_seg_to_ptr(dom, seg); -+ if (NULL == ptr) -+ return -1; -+ memset(ptr, 0, pages * page_size); -+ -+ return 0; -+} -+ -+int xc_dom_alloc_page(struct xc_dom_image *dom, char *name) -+{ -+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); -+ xen_vaddr_t start; -+ xen_pfn_t pfn; -+ -+ start = dom->virt_alloc_end; -+ dom->virt_alloc_end += page_size; -+ pfn = (start - dom->parms.virt_base) / page_size; -+ -+ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n", -+ __FUNCTION__, name, start, pfn); -+ return pfn; -+} -+ -+void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn) -+{ -+ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); -+ struct xc_dom_phys *phys, *prev = NULL; -+ -+ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) -+ { -+ if (pfn >= phys->first && pfn < phys->first + phys->count) -+ break; -+ prev = phys; -+ } -+ if (!phys) -+ { -+ xc_dom_printf("%s: Huh? no mapping with pfn 0x%" PRIpfn "\n", -+ __FUNCTION__, pfn); -+ return; -+ } -+ -+ munmap(phys->ptr, phys->count << page_shift); -+ if (prev) -+ prev->next = phys->next; -+ else -+ dom->phys_pages = phys->next; -+} -+ -+void xc_dom_unmap_all(struct xc_dom_image *dom) -+{ -+ while (dom->phys_pages) -+ xc_dom_unmap_one(dom, dom->phys_pages->first); -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* pluggable kernel loaders */ -+ -+static struct xc_dom_loader *first_loader = NULL; -+static struct xc_dom_arch *first_hook = NULL; -+ -+void xc_dom_register_loader(struct xc_dom_loader *loader) -+{ -+ loader->next = first_loader; -+ first_loader = loader; -+} -+ -+static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom) -+{ -+ struct xc_dom_loader *loader = first_loader; -+ -+ while (NULL != loader) -+ { -+ xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name); -+ if (0 == loader->probe(dom)) -+ { -+ xc_dom_printf("OK\n"); -+ return loader; -+ } -+ xc_dom_printf("failed\n"); -+ loader = loader->next; -+ } -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__); -+ return NULL; -+} -+ -+void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks) -+{ -+ hooks->next = first_hook; -+ first_hook = hooks; -+} -+ -+static struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type) -+{ -+ struct xc_dom_arch *hooks = first_hook; -+ -+ while (NULL != hooks) -+ { -+ if (0 == strcmp(hooks->guest_type, guest_type)) -+ return hooks; -+ hooks = hooks->next; -+ } -+ xc_dom_panic(XC_INVALID_KERNEL, -+ "%s: not found (type %s)\n", __FUNCTION__, guest_type); -+ return NULL; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* public interface */ -+ -+void xc_dom_release(struct xc_dom_image *dom) -+{ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ if (dom->phys_pages) -+ xc_dom_unmap_all(dom); -+ xc_dom_free_all(dom); -+ free(dom); -+} -+ -+struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features) -+{ -+ struct xc_dom_image *dom; -+ -+ xc_dom_printf("%s: cmdline=\"%s\", features=\"%s\"\n", -+ __FUNCTION__, cmdline, features); -+ dom = malloc(sizeof(*dom)); -+ if (!dom) -+ goto err; -+ -+ memset(dom, 0, sizeof(*dom)); -+ if (cmdline) -+ dom->cmdline = xc_dom_strdup(dom, cmdline); -+ if (features) -+ elf_xen_parse_features(features, dom->f_requested, NULL); -+ -+ dom->parms.virt_base = UNSET_ADDR; -+ dom->parms.virt_entry = UNSET_ADDR; -+ dom->parms.virt_hypercall = UNSET_ADDR; -+ dom->parms.virt_hv_start_low = UNSET_ADDR; -+ dom->parms.elf_paddr_offset = UNSET_ADDR; -+ -+ dom->alloc_malloc += sizeof(*dom); -+ return dom; -+ -+ err: -+ if (dom) -+ xc_dom_release(dom); -+ return NULL; -+} -+ -+int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename) -+{ -+ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); -+ dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size); -+ if (NULL == dom->kernel_blob) -+ return -1; -+ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); -+} -+ -+int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename) -+{ -+ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); -+ dom->ramdisk_blob = -+ xc_dom_malloc_filemap(dom, filename, &dom->ramdisk_size); -+ if (NULL == dom->ramdisk_blob) -+ return -1; -+// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); -+ return 0; -+} -+ -+int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t memsize) -+{ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ dom->kernel_blob = (void *)mem; -+ dom->kernel_size = memsize; -+ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); -+} -+ -+int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, -+ size_t memsize) -+{ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ dom->ramdisk_blob = (void *)mem; -+ dom->ramdisk_size = memsize; -+// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); -+ return 0; -+} -+ -+int xc_dom_parse_image(struct xc_dom_image *dom) -+{ -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* parse kernel image */ -+ dom->kernel_loader = xc_dom_find_loader(dom); -+ if (NULL == dom->kernel_loader) -+ goto err; -+ if (0 != dom->kernel_loader->parser(dom)) -+ goto err; -+ if (NULL == dom->guest_type) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "%s: guest_type not set\n", __FUNCTION__); -+ goto err; -+ } -+ -+ /* check features */ -+ for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) -+ { -+ dom->f_active[i] |= dom->f_requested[i]; /* cmd line */ -+ dom->f_active[i] |= dom->parms.f_required[i]; /* kernel */ -+ if ((dom->f_active[i] & dom->parms.f_supported[i]) != dom->f_active[i]) -+ { -+ xc_dom_panic(XC_INVALID_PARAM, -+ "%s: unsupported feature requested\n", __FUNCTION__); -+ goto err; -+ } -+ } -+ return 0; -+ -+ err: -+ return -1; -+} -+ -+int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb) -+{ -+ unsigned int page_shift; -+ xen_pfn_t nr_pages, pfn; -+ -+ dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type); -+ if (NULL == dom->arch_hooks) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", -+ __FUNCTION__); -+ return -1; -+ } -+ -+ page_shift = XC_DOM_PAGE_SHIFT(dom); -+ nr_pages = mem_mb << (20 - page_shift); -+ -+ xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n", -+ __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10)); -+ dom->total_pages = nr_pages; -+ -+ xc_dom_printf("%s: 0x%" PRIpfn " pages\n", -+ __FUNCTION__, dom->total_pages); -+ -+ /* setup initial p2m */ -+ dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); -+ for (pfn = 0; pfn < dom->total_pages; pfn++) -+ dom->p2m_host[pfn] = pfn; -+ return 0; -+} -+ -+int xc_dom_update_guest_p2m(struct xc_dom_image *dom) -+{ -+ uint32_t *p2m_32; -+ uint64_t *p2m_64; -+ xen_pfn_t i; -+ -+ if (!dom->p2m_guest) -+ return 0; -+ -+ switch (dom->arch_hooks->sizeof_pfn) -+ { -+ case 4: -+ xc_dom_printf("%s: dst 32bit, pages 0x%" PRIpfn " \n", -+ __FUNCTION__, dom->total_pages); -+ p2m_32 = dom->p2m_guest; -+ for (i = 0; i < dom->total_pages; i++) -+ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) -+ p2m_32[i] = dom->p2m_host[i]; -+ else -+ p2m_32[i] = (uint32_t) - 1; -+ break; -+ case 8: -+ xc_dom_printf("%s: dst 64bit, pages 0x%" PRIpfn " \n", -+ __FUNCTION__, dom->total_pages); -+ p2m_64 = dom->p2m_guest; -+ for (i = 0; i < dom->total_pages; i++) -+ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) -+ p2m_64[i] = dom->p2m_host[i]; -+ else -+ p2m_64[i] = (uint64_t) - 1; -+ break; -+ default: -+ xc_dom_panic(XC_INTERNAL_ERROR, -+ "sizeof_pfn is invalid (is %d, can be 4 or 8)", -+ dom->arch_hooks->sizeof_pfn); -+ return -1; -+ } -+ return 0; -+} -+ -+int xc_dom_build_image(struct xc_dom_image *dom) -+{ -+ unsigned int page_size; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* check for arch hooks */ -+ if (NULL == dom->arch_hooks) -+ { -+ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", -+ __FUNCTION__); -+ goto err; -+ } -+ page_size = XC_DOM_PAGE_SIZE(dom); -+ -+ /* 4MB align virtual base address */ -+ dom->parms.virt_base &= ~(((uint64_t)1<<22)-1); -+ -+ /* load kernel */ -+ if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel", -+ dom->kernel_seg.vstart, -+ dom->kernel_seg.vend - -+ dom->kernel_seg.vstart)) -+ goto err; -+ if (0 != dom->kernel_loader->loader(dom)) -+ goto err; -+ -+ /* load ramdisk */ -+ if (dom->ramdisk_blob) -+ { -+ size_t unziplen, ramdisklen; -+ void *ramdiskmap; -+ -+ unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size); -+ ramdisklen = unziplen ? unziplen : dom->ramdisk_size; -+ if (0 != xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0, -+ ramdisklen)) -+ goto err; -+ ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg); -+ if (unziplen) -+ { -+ if (-1 == xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size, -+ ramdiskmap, ramdisklen)) -+ goto err; -+ } -+ else -+ memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size); -+ } -+ -+ /* allocate other pages */ -+ if (0 != dom->arch_hooks->alloc_magic_pages(dom)) -+ goto err; -+ if (dom->arch_hooks->count_pgtables) -+ { -+ dom->arch_hooks->count_pgtables(dom); -+ if (dom->pgtables > 0) -+ if (0 != -+ xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0, -+ dom->pgtables * page_size)) -+ goto err; -+ } -+ if (dom->alloc_bootstack) -+ dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack"); -+ xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n", -+ __FUNCTION__, dom->virt_alloc_end); -+ xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n", -+ __FUNCTION__, dom->virt_pgtab_end); -+ return 0; -+ -+ err: -+ return -1; -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_ia64.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_ia64.c -@@ -0,0 +1,119 @@ -+/* -+ * Xen domain builder -- ia64 bits. -+ * -+ * Most architecture-specific code for ia64 goes here. -+ * - fill architecture-specific structs. -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int alloc_magic_pages(struct xc_dom_image *dom) -+{ -+ /* allocate special pages */ -+ dom->console_pfn = dom->total_pages -1; -+ dom->xenstore_pfn = dom->total_pages -2; -+ dom->start_info_pfn = dom->total_pages -3; -+ return 0; -+} -+ -+static int start_info_ia64(struct xc_dom_image *dom) -+{ -+ start_info_ia64_t *start_info = -+ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); -+ struct xen_ia64_boot_param_ia64 *bp = -+ (struct xen_ia64_boot_param_ia64 *)(start_info + 1); -+ -+ xc_dom_printf("%s\n", __FUNCTION__); -+ -+ memset(start_info, 0, sizeof(*start_info)); -+ sprintf(start_info->magic, dom->guest_type); -+ start_info->flags = dom->flags; -+ start_info->nr_pages = dom->total_pages; -+ start_info->store_mfn = dom->xenstore_pfn; -+ start_info->store_evtchn = dom->xenstore_evtchn; -+ start_info->console.domU.mfn = dom->console_pfn; -+ start_info->console.domU.evtchn = dom->console_evtchn; -+ -+ if (dom->ramdisk_blob) -+ { -+ start_info->mod_start = dom->ramdisk_seg.vstart; -+ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; -+ bp->initrd_start = start_info->mod_start; -+ bp->initrd_size = start_info->mod_len; -+ } -+ bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64) -+ + offsetof(start_info_t, cmd_line); -+ if (dom->cmdline) -+ { -+ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); -+ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; -+ } -+ return 0; -+} -+ -+static int shared_info_ia64(struct xc_dom_image *dom, void *ptr) -+{ -+ shared_info_ia64_t *shared_info = ptr; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ memset(shared_info, 0, sizeof(*shared_info)); -+ for (i = 0; i < MAX_VIRT_CPUS; i++) -+ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; -+ shared_info->arch.start_info_pfn = dom->start_info_pfn; -+ return 0; -+} -+ -+extern unsigned long xc_ia64_fpsr_default(void); -+ -+static int vcpu_ia64(struct xc_dom_image *dom, void *ptr) -+{ -+ vcpu_guest_context_ia64_t *ctxt = ptr; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* clear everything */ -+ memset(ctxt, 0, sizeof(*ctxt)); -+ -+ ctxt->flags = 0; -+ ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ -+ ctxt->user_regs.cr_iip = dom->parms.virt_entry; -+ ctxt->user_regs.cr_ifs = (uint64_t) 1 << 63; -+#ifdef __ia64__ /* FIXME */ -+ ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); -+#endif -+ ctxt->user_regs.r28 = (dom->start_info_pfn << PAGE_SHIFT_IA64) -+ + sizeof(start_info_ia64_t); -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static struct xc_dom_arch xc_dom_arch = { -+ .guest_type = "xen-3.0-ia64", -+ .page_shift = PAGE_SHIFT_IA64, -+ .alloc_magic_pages = alloc_magic_pages, -+ .start_info = start_info_ia64, -+ .shared_info = shared_info_ia64, -+ .vcpu = vcpu_ia64, -+}; -+ -+static void __init register_arch_hooks(void) -+{ -+ xc_dom_register_arch_hooks(&xc_dom_arch); -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_x86.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_x86.c -@@ -0,0 +1,561 @@ -+/* -+ * Xen domain builder -- i386 and x86_64 bits. -+ * -+ * Most architecture-specific code for x86 goes here. -+ * - prepare page tables. -+ * - fill architecture-specific structs. -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+/* ------------------------------------------------------------------------ */ -+ -+#define bits_to_mask(bits) (((xen_vaddr_t)1 << (bits))-1) -+#define round_down(addr, mask) ((addr) & ~(mask)) -+#define round_up(addr, mask) ((addr) | (mask)) -+ -+static inline unsigned long -+nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned long bits) -+{ -+ xen_vaddr_t mask = bits_to_mask(bits); -+ int tables; -+ -+ if (0 == bits) -+ return 0; /* unused */ -+ -+ if (8 * sizeof(unsigned long) == bits) -+ { -+ /* must be pgd, need one */ -+ start = 0; -+ end = -1; -+ tables = 1; -+ } -+ else -+ { -+ start = round_down(start, mask); -+ end = round_up(end, mask); -+ tables = ((end - start) >> bits) + 1; -+ } -+ -+ xc_dom_printf("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64 -+ " -> 0x%016" PRIx64 ", %d table(s)\n", -+ __FUNCTION__, mask, bits, start, end, tables); -+ return tables; -+} -+ -+static int count_pgtables(struct xc_dom_image *dom, int pae, -+ int l4_bits, int l3_bits, int l2_bits, int l1_bits) -+{ -+ int pages, extra_pages; -+ xen_vaddr_t try_virt_end; -+ -+ extra_pages = dom->alloc_bootstack ? 1 : 0; -+ extra_pages += dom->extra_pages; -+ extra_pages += 128; /* 512kB padding */ -+ pages = extra_pages; -+ for (;;) -+ { -+ try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86, -+ bits_to_mask(22)); /* 4MB alignment */ -+ dom->pg_l4 = -+ nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits); -+ dom->pg_l3 = -+ nr_page_tables(dom->parms.virt_base, try_virt_end, l3_bits); -+ dom->pg_l2 = -+ nr_page_tables(dom->parms.virt_base, try_virt_end, l2_bits); -+ dom->pg_l1 = -+ nr_page_tables(dom->parms.virt_base, try_virt_end, l1_bits); -+ if (pae && try_virt_end < 0xc0000000) -+ { -+ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); -+ dom->pg_l2++; -+ } -+ dom->pgtables = dom->pg_l4 + dom->pg_l3 + dom->pg_l2 + dom->pg_l1; -+ pages = dom->pgtables + extra_pages; -+ if (dom->virt_alloc_end + pages * PAGE_SIZE_X86 <= try_virt_end + 1) -+ break; -+ } -+ dom->virt_pgtab_end = try_virt_end + 1; -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* i386 pagetables */ -+ -+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) -+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -+#define L3_PROT (_PAGE_PRESENT) -+ -+static int count_pgtables_x86_32(struct xc_dom_image *dom) -+{ -+ return count_pgtables(dom, 0, 0, 0, 32, L2_PAGETABLE_SHIFT_I386); -+} -+ -+static int count_pgtables_x86_32_pae(struct xc_dom_image *dom) -+{ -+ return count_pgtables(dom, 1, 0, 32, -+ L3_PAGETABLE_SHIFT_PAE, L2_PAGETABLE_SHIFT_PAE); -+} -+ -+#define pfn_to_paddr(pfn) ((xen_paddr_t)(pfn) << PAGE_SHIFT_X86) -+ -+static int setup_pgtables_x86_32(struct xc_dom_image *dom) -+{ -+ xen_pfn_t l2pfn = dom->pgtables_seg.pfn; -+ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l2; -+ l2_pgentry_32_t *l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); -+ l1_pgentry_32_t *l1tab = NULL; -+ unsigned long l2off, l1off; -+ xen_vaddr_t addr; -+ xen_pfn_t pgpfn; -+ -+ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; -+ addr += PAGE_SIZE_X86) -+ { -+ if (NULL == l1tab) -+ { -+ /* get L1 tab, make L2 entry */ -+ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); -+ l2off = l2_table_offset_i386(addr); -+ l2tab[l2off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; -+ l1pfn++; -+ } -+ -+ /* make L1 entry */ -+ l1off = l1_table_offset_i386(addr); -+ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; -+ l1tab[l1off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; -+ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) -+ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ -+ if (L1_PAGETABLE_ENTRIES_I386 - 1 == l1off) -+ l1tab = NULL; -+ } -+ return 0; -+} -+ -+static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom) -+{ -+ xen_pfn_t l3pfn = dom->pgtables_seg.pfn; -+ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l3; -+ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l3 + dom->pg_l2; -+ l3_pgentry_64_t *l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); -+ l2_pgentry_64_t *l2tab = NULL; -+ l1_pgentry_64_t *l1tab = NULL; -+ unsigned long l3off, l2off, l1off; -+ xen_vaddr_t addr; -+ xen_pfn_t pgpfn; -+ -+ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; -+ addr += PAGE_SIZE_X86) -+ { -+ if (NULL == l2tab) -+ { -+ /* get L2 tab, make L3 entry */ -+ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); -+ l3off = l3_table_offset_pae(addr); -+ l3tab[l3off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; -+ l2pfn++; -+ } -+ -+ if (NULL == l1tab) -+ { -+ /* get L1 tab, make L2 entry */ -+ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); -+ l2off = l2_table_offset_pae(addr); -+ l2tab[l2off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; -+ if (L2_PAGETABLE_ENTRIES_PAE - 1 == l2off) -+ l2tab = NULL; -+ l1pfn++; -+ } -+ -+ /* make L1 entry */ -+ l1off = l1_table_offset_pae(addr); -+ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; -+ l1tab[l1off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; -+ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) -+ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ -+ if (L1_PAGETABLE_ENTRIES_PAE - 1 == l1off) -+ l1tab = NULL; -+ } -+ -+ if (dom->virt_pgtab_end <= 0xc0000000) -+ { -+ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); -+ l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; -+ } -+ return 0; -+} -+ -+#undef L1_PROT -+#undef L2_PROT -+#undef L3_PROT -+ -+/* ------------------------------------------------------------------------ */ -+/* x86_64 pagetables */ -+ -+static int count_pgtables_x86_64(struct xc_dom_image *dom) -+{ -+ return count_pgtables(dom, 0, -+ L4_PAGETABLE_SHIFT_X86_64 + 9, -+ L4_PAGETABLE_SHIFT_X86_64, -+ L3_PAGETABLE_SHIFT_X86_64, L2_PAGETABLE_SHIFT_X86_64); -+} -+ -+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) -+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -+#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -+#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -+ -+static int setup_pgtables_x86_64(struct xc_dom_image *dom) -+{ -+ xen_pfn_t l4pfn = dom->pgtables_seg.pfn; -+ xen_pfn_t l3pfn = dom->pgtables_seg.pfn + dom->pg_l4; -+ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3; -+ xen_pfn_t l1pfn = -+ dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3 + dom->pg_l2; -+ l4_pgentry_64_t *l4tab = xc_dom_pfn_to_ptr(dom, l4pfn, 1); -+ l3_pgentry_64_t *l3tab = NULL; -+ l2_pgentry_64_t *l2tab = NULL; -+ l1_pgentry_64_t *l1tab = NULL; -+ uint64_t l4off, l3off, l2off, l1off; -+ uint64_t addr; -+ xen_pfn_t pgpfn; -+ -+ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; -+ addr += PAGE_SIZE_X86) -+ { -+ if (NULL == l3tab) -+ { -+ /* get L3 tab, make L4 entry */ -+ l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); -+ l4off = l4_table_offset_x86_64(addr); -+ l4tab[l4off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT; -+ l3pfn++; -+ } -+ -+ if (NULL == l2tab) -+ { -+ /* get L2 tab, make L3 entry */ -+ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); -+ l3off = l3_table_offset_x86_64(addr); -+ l3tab[l3off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; -+ if (L3_PAGETABLE_ENTRIES_X86_64 - 1 == l3off) -+ l3tab = NULL; -+ l2pfn++; -+ } -+ -+ if (NULL == l1tab) -+ { -+ /* get L1 tab, make L2 entry */ -+ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); -+ l2off = l2_table_offset_x86_64(addr); -+ l2tab[l2off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; -+ if (L2_PAGETABLE_ENTRIES_X86_64 - 1 == l2off) -+ l2tab = NULL; -+ l1pfn++; -+ } -+ -+ /* make L1 entry */ -+ l1off = l1_table_offset_x86_64(addr); -+ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; -+ l1tab[l1off] = -+ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; -+ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) -+ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ -+ if (L1_PAGETABLE_ENTRIES_X86_64 - 1 == l1off) -+ l1tab = NULL; -+ } -+ return 0; -+} -+ -+#undef L1_PROT -+#undef L2_PROT -+#undef L3_PROT -+#undef L4_PROT -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int alloc_magic_pages(struct xc_dom_image *dom) -+{ -+ size_t p2m_size = dom->total_pages * dom->arch_hooks->sizeof_pfn; -+ -+ /* allocate phys2mach table */ -+ if (0 != xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size)) -+ return -1; -+ dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg); -+ -+ /* allocate special pages */ -+ dom->start_info_pfn = xc_dom_alloc_page(dom, "start info"); -+ dom->xenstore_pfn = xc_dom_alloc_page(dom, "xenstore"); -+ dom->console_pfn = xc_dom_alloc_page(dom, "console"); -+ if (xc_dom_feature_translated(dom)) -+ dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info"); -+ dom->alloc_bootstack = 1; -+ -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int start_info_x86_32(struct xc_dom_image *dom) -+{ -+ start_info_x86_32_t *start_info = -+ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); -+ xen_pfn_t shinfo = -+ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> -+ shared_info_mfn; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ sprintf(start_info->magic, dom->guest_type); -+ start_info->nr_pages = dom->total_pages; -+ start_info->shared_info = shinfo << PAGE_SHIFT_X86; -+ start_info->pt_base = dom->pgtables_seg.vstart; -+ start_info->nr_pt_frames = dom->pgtables; -+ start_info->mfn_list = dom->p2m_seg.vstart; -+ -+ start_info->flags = dom->flags; -+ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); -+ start_info->store_evtchn = dom->xenstore_evtchn; -+ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); -+ start_info->console.domU.evtchn = dom->console_evtchn; -+ -+ if (dom->ramdisk_blob) -+ { -+ start_info->mod_start = dom->ramdisk_seg.vstart; -+ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; -+ } -+ if (dom->cmdline) -+ { -+ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); -+ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; -+ } -+ return 0; -+} -+ -+static int start_info_x86_64(struct xc_dom_image *dom) -+{ -+ start_info_x86_64_t *start_info = -+ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); -+ xen_pfn_t shinfo = -+ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> -+ shared_info_mfn; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ sprintf(start_info->magic, dom->guest_type); -+ start_info->nr_pages = dom->total_pages; -+ start_info->shared_info = shinfo << PAGE_SHIFT_X86; -+ start_info->pt_base = dom->pgtables_seg.vstart; -+ start_info->nr_pt_frames = dom->pgtables; -+ start_info->mfn_list = dom->p2m_seg.vstart; -+ -+ start_info->flags = dom->flags; -+ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); -+ start_info->store_evtchn = dom->xenstore_evtchn; -+ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); -+ start_info->console.domU.evtchn = dom->console_evtchn; -+ -+ if (dom->ramdisk_blob) -+ { -+ start_info->mod_start = dom->ramdisk_seg.vstart; -+ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; -+ } -+ if (dom->cmdline) -+ { -+ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); -+ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; -+ } -+ return 0; -+} -+ -+static int shared_info_x86_32(struct xc_dom_image *dom, void *ptr) -+{ -+ shared_info_x86_32_t *shared_info = ptr; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ memset(shared_info, 0, sizeof(*shared_info)); -+ for (i = 0; i < MAX_VIRT_CPUS; i++) -+ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; -+ return 0; -+} -+ -+static int shared_info_x86_64(struct xc_dom_image *dom, void *ptr) -+{ -+ shared_info_x86_64_t *shared_info = ptr; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ memset(shared_info, 0, sizeof(*shared_info)); -+ for (i = 0; i < MAX_VIRT_CPUS; i++) -+ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr) -+{ -+ vcpu_guest_context_x86_32_t *ctxt = ptr; -+ xen_pfn_t cr3_pfn; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* clear everything */ -+ memset(ctxt, 0, sizeof(*ctxt)); -+ -+ /* Virtual IDT is empty at start-of-day. */ -+ for (i = 0; i < 256; i++) -+ { -+ ctxt->trap_ctxt[i].vector = i; -+ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_32; -+ } -+ -+ /* No callback handlers. */ -+ ctxt->event_callback_cs = FLAT_KERNEL_CS_X86_32; -+ ctxt->failsafe_callback_cs = FLAT_KERNEL_CS_X86_32; -+ -+ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32; -+ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32; -+ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32; -+ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32; -+ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32; -+ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32; -+ ctxt->user_regs.eip = dom->parms.virt_entry; -+ ctxt->user_regs.esp = -+ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; -+ ctxt->user_regs.esi = -+ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; -+ ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ -+ -+ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_32; -+ ctxt->kernel_sp = -+ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; -+ -+ ctxt->flags = VGCF_in_kernel_X86_32; -+ if (dom->parms.pae == 2 /* extended_cr3 */ || -+ dom->parms.pae == 3 /* bimodal */) -+ ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); -+ -+ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); -+ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn); -+ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", -+ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); -+ -+ return 0; -+} -+ -+static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr) -+{ -+ vcpu_guest_context_x86_64_t *ctxt = ptr; -+ xen_pfn_t cr3_pfn; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* clear everything */ -+ memset(ctxt, 0, sizeof(*ctxt)); -+ -+ /* Virtual IDT is empty at start-of-day. */ -+ for (i = 0; i < 256; i++) -+ { -+ ctxt->trap_ctxt[i].vector = i; -+ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_64; -+ } -+ -+ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64; -+ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64; -+ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_64; -+ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_64; -+ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_64; -+ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_64; -+ ctxt->user_regs.rip = dom->parms.virt_entry; -+ ctxt->user_regs.rsp = -+ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; -+ ctxt->user_regs.rsi = -+ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; -+ ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */ -+ -+ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_64; -+ ctxt->kernel_sp = -+ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; -+ -+ ctxt->flags = VGCF_in_kernel_X86_64; -+ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); -+ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn); -+ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", -+ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); -+ -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static struct xc_dom_arch xc_dom_32 = { -+ .guest_type = "xen-3.0-x86_32", -+ .page_shift = PAGE_SHIFT_X86, -+ .sizeof_pfn = 4, -+ .alloc_magic_pages = alloc_magic_pages, -+ .count_pgtables = count_pgtables_x86_32, -+ .setup_pgtables = setup_pgtables_x86_32, -+ .start_info = start_info_x86_32, -+ .shared_info = shared_info_x86_32, -+ .vcpu = vcpu_x86_32, -+}; -+static struct xc_dom_arch xc_dom_32_pae = { -+ .guest_type = "xen-3.0-x86_32p", -+ .page_shift = PAGE_SHIFT_X86, -+ .sizeof_pfn = 4, -+ .alloc_magic_pages = alloc_magic_pages, -+ .count_pgtables = count_pgtables_x86_32_pae, -+ .setup_pgtables = setup_pgtables_x86_32_pae, -+ .start_info = start_info_x86_32, -+ .shared_info = shared_info_x86_32, -+ .vcpu = vcpu_x86_32, -+}; -+ -+static struct xc_dom_arch xc_dom_64 = { -+ .guest_type = "xen-3.0-x86_64", -+ .page_shift = PAGE_SHIFT_X86, -+ .sizeof_pfn = 8, -+ .alloc_magic_pages = alloc_magic_pages, -+ .count_pgtables = count_pgtables_x86_64, -+ .setup_pgtables = setup_pgtables_x86_64, -+ .start_info = start_info_x86_64, -+ .shared_info = shared_info_x86_64, -+ .vcpu = vcpu_x86_64, -+}; -+ -+static void __init register_arch_hooks(void) -+{ -+ xc_dom_register_arch_hooks(&xc_dom_32); -+ xc_dom_register_arch_hooks(&xc_dom_32_pae); -+ xc_dom_register_arch_hooks(&xc_dom_64); -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c -@@ -0,0 +1,100 @@ -+/* -+ * Xen domain builder -- ia64 bits. -+ * -+ * Most architecture-specific code for ia64 goes here. -+ * - fill architecture-specific structs. -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int alloc_magic_pages(struct xc_dom_image *dom) -+{ -+ /* allocate special pages */ -+ dom->low_top--; /* shared_info */ -+ dom->xenstore_pfn = --dom->low_top; -+ dom->console_pfn = --dom->low_top; -+ dom->start_info_pfn = --dom->low_top; -+ return 0; -+} -+ -+static int start_info(struct xc_dom_image *dom) -+{ -+ start_info_t *si = -+ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); -+ -+ xc_dom_printf("%s\n", __FUNCTION__); -+ -+ snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); -+ -+ si->nr_pages = dom->total_pages; -+ si->shared_info = (dom->total_pages - 1) << PAGE_SHIFT; -+ si->store_mfn = dom->xenstore_pfn; -+ si->store_evtchn = dom->store_evtchn; -+ si->console.domU.mfn = dom->console_pfn; -+ si->console.domU.evtchn = dom->console_evtchn; -+ return 0; -+} -+ -+static int shared_info(struct xc_dom_image *dom, void *ptr) -+{ -+ shared_info_t *shared_info = ptr; -+ int i; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ memset(shared_info, 0, sizeof(*shared_info)); -+ return 0; -+} -+ -+static int vcpu(struct xc_dom_image *dom, void *ptr) -+{ -+ vcpu_guest_context_t *ctxt = ptr; -+ -+ xc_dom_printf("%s: called\n", __FUNCTION__); -+ -+ /* clear everything */ -+ memset(ctxt, 0, sizeof(*ctxt)); -+ -+ memset(&ctxt->user_regs, 0x55, sizeof(ctxt.user_regs)); -+ ctxt->user_regs.pc = dsi->v_kernentry; -+ ctxt->user_regs.msr = 0; -+ ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */ -+ ctxt->user_regs.gprs[3] = devtree_addr; -+ ctxt->user_regs.gprs[4] = kern_addr; -+ ctxt->user_regs.gprs[5] = 0; -+ -+ /* There is a buggy kernel that does not zero the "local_paca", so -+ * we must make sure this register is 0 */ -+ ctxt->user_regs.gprs[13] = 0; -+ -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static struct xc_dom_arch xc_dom_arch = { -+ .guest_type = "xen-3.0-powerpc64", -+ .page_shift = FIXME, -+ .alloc_magic_pages = alloc_magic_pages, -+ .start_info = start_info, -+ .shared_info = shared_info, -+ .vcpu = vcpu, -+}; -+ -+static void __init register_arch_hooks(void) -+{ -+ xc_dom_register_arch_hooks(&xc_dom_arch); -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_elfloader.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_elfloader.c -@@ -0,0 +1,283 @@ -+/* -+ * Xen domain builder -- ELF bits. -+ * -+ * Parse and load ELF kernel images. -+ * -+ * This code is licenced under the GPL. -+ * written 2006 by Gerd Hoffmann . -+ * -+ */ -+#include -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+#define XEN_VER "xen-3.0" -+ -+/* ------------------------------------------------------------------------ */ -+ -+static char *xc_dom_guest_type(struct xc_dom_image *dom, -+ struct elf_binary *elf) -+{ -+ uint64_t machine = elf_uval(elf, elf->ehdr, e_machine); -+ -+ switch (machine) { -+ case EM_386: -+ switch (dom->parms.pae) { -+ case 3 /* PAEKERN_bimodal */: -+ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) -+ return "xen-3.0-x86_32p"; -+ return "xen-3.0-x86_32"; -+ case PAEKERN_extended_cr3: -+ case PAEKERN_yes: -+ return "xen-3.0-x86_32p"; -+ break; -+ case PAEKERN_no: -+ default: -+ return "xen-3.0-x86_32"; -+ } -+ case EM_X86_64: -+ return "xen-3.0-x86_64"; -+ case EM_IA_64: -+ return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64"; -+ case EM_PPC64: -+ return "xen-3.0-powerpc64"; -+ default: -+ return "xen-3.0-unknown"; -+ } -+} -+ -+/* ------------------------------------------------------------------------ */ -+/* parse elf binary */ -+ -+static int check_elf_kernel(struct xc_dom_image *dom, int verbose) -+{ -+ if (NULL == dom->kernel_blob) -+ { -+ if (verbose) -+ xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ if (!elf_is_elfbinary(dom->kernel_blob)) -+ { -+ if (verbose) -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not an ELF image\n", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom) -+{ -+ return check_elf_kernel(dom, 0); -+} -+ -+static int xc_dom_load_elf_symtab(struct xc_dom_image *dom, -+ struct elf_binary *elf, int load) -+{ -+ struct elf_binary syms; -+ const elf_shdr *shdr, *shdr2; -+ xen_vaddr_t symtab, maxaddr; -+ char *hdr; -+ size_t size; -+ int h, count, type, i, tables = 0; -+ -+ if (elf_swap(elf)) { -+ xc_dom_printf("%s: non-native byte order, bsd symtab not supported\n", -+ __FUNCTION__); -+ return 0; -+ } -+ -+ if (load) { -+ if (!dom->bsd_symtab_start) -+ return 0; -+ size = dom->kernel_seg.vend - dom->bsd_symtab_start; -+ hdr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start); -+ *(int *)hdr = size - sizeof(int); -+ } else { -+ size = sizeof(int) + elf_size(elf, elf->ehdr) + -+ elf_shdr_count(elf) * elf_size(elf, shdr); -+ hdr = xc_dom_malloc(dom, size); -+ if (hdr == NULL) -+ return 0; -+ dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend); -+ } -+ -+ memcpy(hdr + sizeof(int), -+ elf->image, -+ elf_size(elf, elf->ehdr)); -+ memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr), -+ elf->image + elf_uval(elf, elf->ehdr, e_shoff), -+ elf_shdr_count(elf) * elf_size(elf, shdr)); -+ if (elf_64bit(elf)) { -+ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int)); -+ ehdr->e_phoff = 0; -+ ehdr->e_phentsize = 0; -+ ehdr->e_phnum = 0; -+ ehdr->e_shoff = elf_size(elf, elf->ehdr); -+ ehdr->e_shstrndx = SHN_UNDEF; -+ } else { -+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int)); -+ ehdr->e_phoff = 0; -+ ehdr->e_phentsize = 0; -+ ehdr->e_phnum = 0; -+ ehdr->e_shoff = elf_size(elf, elf->ehdr); -+ ehdr->e_shstrndx = SHN_UNDEF; -+ } -+ if (0 != elf_init(&syms, hdr + sizeof(int), size - sizeof(int))) -+ return -1; -+ if (xc_dom_logfile) -+ elf_set_logfile(&syms, xc_dom_logfile, 1); -+ -+ symtab = dom->bsd_symtab_start + sizeof(int); -+ maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) + -+ elf_shdr_count(&syms) * elf_size(&syms, shdr)); -+ -+ xc_dom_printf("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64 -+ " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "\n", -+ __FUNCTION__, load ? "load" : "parse", -+ dom->bsd_symtab_start, dom->kernel_seg.vend, symtab, maxaddr); -+ -+ count = elf_shdr_count(&syms); -+ for (h = 0; h < count; h++) -+ { -+ shdr = elf_shdr_by_index(&syms, h); -+ type = elf_uval(&syms, shdr, sh_type); -+ if (type == SHT_STRTAB) -+ { -+ /* Look for a strtab @i linked to symtab @h. */ -+ for (i = 0; i < count; i++) { -+ shdr2 = elf_shdr_by_index(&syms, i); -+ if ((elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) && -+ (elf_uval(&syms, shdr2, sh_link) == h)) -+ break; -+ } -+ /* Skip symtab @h if we found no corresponding strtab @i. */ -+ if (i == count) -+ { -+ if (elf_64bit(&syms)) -+ *(Elf64_Off*)(&shdr->e64.sh_offset) = 0; -+ else -+ *(Elf32_Off*)(&shdr->e32.sh_offset) = 0; -+ continue; -+ } -+ } -+ -+ if ((type == SHT_STRTAB) || (type == SHT_SYMTAB)) -+ { -+ /* Mangled to be based on ELF header location. */ -+ if (elf_64bit(&syms)) -+ *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab; -+ else -+ *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab; -+ size = elf_uval(&syms, shdr, sh_size); -+ maxaddr = elf_round_up(&syms, maxaddr + size); -+ tables++; -+ xc_dom_printf("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "\n", -+ __FUNCTION__, h, -+ type == SHT_SYMTAB ? "symtab" : "strtab", -+ size, maxaddr); -+ -+ if (load) { -+ shdr2 = elf_shdr_by_index(elf, h); -+ memcpy((void*)elf_section_start(&syms, shdr), -+ elf_section_start(elf, shdr2), -+ size); -+ } -+ } -+ -+ /* Name is NULL. */ -+ if (elf_64bit(&syms)) -+ *(Elf64_Half*)(&shdr->e64.sh_name) = 0; -+ else -+ *(Elf32_Word*)(&shdr->e32.sh_name) = 0; -+ } -+ -+ if (0 == tables) -+ { -+ xc_dom_printf("%s: no symbol table present\n", __FUNCTION__); -+ dom->bsd_symtab_start = 0; -+ return 0; -+ } -+ if (!load) -+ dom->kernel_seg.vend = maxaddr; -+ return 0; -+} -+ -+static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom) -+{ -+ struct elf_binary *elf; -+ int rc; -+ -+ rc = check_elf_kernel(dom, 1); -+ if (0 != rc) -+ return rc; -+ -+ elf = xc_dom_malloc(dom, sizeof(*elf)); -+ dom->private_loader = elf; -+ rc = elf_init(elf, dom->kernel_blob, dom->kernel_size); -+ if (xc_dom_logfile) -+ elf_set_logfile(elf, xc_dom_logfile, 1); -+ if (0 != rc) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n", -+ __FUNCTION__); -+ return rc; -+ } -+ -+ /* Find the section-header strings table. */ -+ if (NULL == elf->sec_strtab) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: ELF image has no shstrtab\n", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ /* parse binary and get xen meta info */ -+ elf_parse_binary(elf); -+ if (0 != (rc = elf_xen_parse(elf, &dom->parms))) -+ return rc; -+ -+ /* find kernel segment */ -+ dom->kernel_seg.vstart = dom->parms.virt_kstart; -+ dom->kernel_seg.vend = dom->parms.virt_kend; -+ -+ if (dom->parms.bsd_symtab) -+ xc_dom_load_elf_symtab(dom, elf, 0); -+ -+ dom->guest_type = xc_dom_guest_type(dom, elf); -+ xc_dom_printf("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", -+ __FUNCTION__, dom->guest_type, -+ dom->kernel_seg.vstart, dom->kernel_seg.vend); -+ return 0; -+} -+ -+static int xc_dom_load_elf_kernel(struct xc_dom_image *dom) -+{ -+ struct elf_binary *elf = dom->private_loader; -+ -+ elf->dest = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); -+ elf_load_binary(elf); -+ if (dom->parms.bsd_symtab) -+ xc_dom_load_elf_symtab(dom, elf, 1); -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static struct xc_dom_loader elf_loader = { -+ .name = "ELF-generic", -+ .probe = xc_dom_probe_elf_kernel, -+ .parser = xc_dom_parse_elf_kernel, -+ .loader = xc_dom_load_elf_kernel, -+}; -+ -+static void __init register_loader(void) -+{ -+ xc_dom_register_loader(&elf_loader); -+} -Index: build-32-release304-13138/tools/libxc/xc_dom_binloader.c -=================================================================== ---- /dev/null -+++ build-32-release304-13138/tools/libxc/xc_dom_binloader.c -@@ -0,0 +1,294 @@ -+/****************************************************************************** -+ * -+ * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are -+ * present. The only requirement is that it must have a xen_bin_image table -+ * somewhere in the first 8192 bytes, starting on a 32-bit aligned address. -+ * Those familiar with the multiboot specification should recognize this, it's -+ * (almost) the same as the multiboot header. -+ * The layout of the xen_bin_image table is: -+ * -+ * Offset Type Name Note -+ * 0 uint32_t magic required -+ * 4 uint32_t flags required -+ * 8 uint32_t checksum required -+ * 12 uint32_t header_addr required -+ * 16 uint32_t load_addr required -+ * 20 uint32_t load_end_addr required -+ * 24 uint32_t bss_end_addr required -+ * 28 uint32_t entry_addr required -+ * -+ * - magic -+ * Magic number identifying the table. For images to be loaded by Xen 3, the -+ * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set). -+ * - flags -+ * bit 0: indicates whether the image needs to be loaded on a page boundary -+ * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate -+ * that memory info should be passed to the image) -+ * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate -+ * that the bootloader should pass video mode info to the image) -+ * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate -+ * that the values in the fields header_addr - entry_addr are -+ * valid) -+ * All other bits should be set to 0. -+ * - checksum -+ * When added to "magic" and "flags", the resulting value should be 0. -+ * - header_addr -+ * Contains the virtual address corresponding to the beginning of the -+ * table - the memory location at which the magic value is supposed to be -+ * loaded. This field serves to synchronize the mapping between OS image -+ * offsets and virtual memory addresses. -+ * - load_addr -+ * Contains the virtual address of the beginning of the text segment. The -+ * offset in the OS image file at which to start loading is defined by the -+ * offset at which the table was found, minus (header addr - load addr). -+ * load addr must be less than or equal to header addr. -+ * - load_end_addr -+ * Contains the virtual address of the end of the data segment. -+ * (load_end_addr - load_addr) specifies how much data to load. This implies -+ * that the text and data segments must be consecutive in the OS image. If -+ * this field is zero, the domain builder assumes that the text and data -+ * segments occupy the whole OS image file. -+ * - bss_end_addr -+ * Contains the virtual address of the end of the bss segment. The domain -+ * builder initializes this area to zero, and reserves the memory it occupies -+ * to avoid placing boot modules and other data relevant to the loaded image -+ * in that area. If this field is zero, the domain builder assumes that no bss -+ * segment is present. -+ * - entry_addr -+ * The virtual address at which to start execution of the loaded image. -+ * -+ * Some of the field descriptions were copied from "The Multiboot -+ * Specification", Copyright 1995, 96 Bryan Ford , -+ * Erich Stefan Boleyn Copyright 1999, 2000, 2001, 2002 -+ * Free Software Foundation, Inc. -+ */ -+ -+#include -+#include -+ -+#include "xg_private.h" -+#include "xc_dom.h" -+ -+#define round_pgup(_p) (((_p)+(PAGE_SIZE_X86-1))&PAGE_MASK_X86) -+#define round_pgdown(_p) ((_p)&PAGE_MASK_X86) -+ -+struct xen_bin_image_table -+{ -+ uint32_t magic; -+ uint32_t flags; -+ uint32_t checksum; -+ uint32_t header_addr; -+ uint32_t load_addr; -+ uint32_t load_end_addr; -+ uint32_t bss_end_addr; -+ uint32_t entry_addr; -+}; -+ -+#define XEN_MULTIBOOT_MAGIC3 0x336ec578 -+ -+#define XEN_MULTIBOOT_FLAG_ALIGN4K 0x00000001 -+#define XEN_MULTIBOOT_FLAG_NEEDMEMINFO 0x00000002 -+#define XEN_MULTIBOOT_FLAG_NEEDVIDINFO 0x00000004 -+#define XEN_MULTIBOOT_FLAG_ADDRSVALID 0x00010000 -+#define XEN_MULTIBOOT_FLAG_PAE_SHIFT 14 -+#define XEN_MULTIBOOT_FLAG_PAE_MASK (3 << XEN_MULTIBOOT_FLAG_PAE_SHIFT) -+ -+/* Flags we test for */ -+#define FLAGS_MASK ((~ 0) & (~ XEN_MULTIBOOT_FLAG_ALIGN4K) & \ -+ (~ XEN_MULTIBOOT_FLAG_PAE_MASK)) -+#define FLAGS_REQUIRED XEN_MULTIBOOT_FLAG_ADDRSVALID -+ -+/* --------------------------------------------------------------------- */ -+ -+static struct xen_bin_image_table *find_table(struct xc_dom_image *dom) -+{ -+ struct xen_bin_image_table *table; -+ uint32_t *probe_ptr; -+ uint32_t *probe_end; -+ -+ probe_ptr = dom->kernel_blob; -+ probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table); -+ if ((void*)probe_end > dom->kernel_blob + 8192) -+ probe_end = dom->kernel_blob + 8192; -+ -+ for (table = NULL; probe_ptr < probe_end; probe_ptr++) -+ { -+ if (XEN_MULTIBOOT_MAGIC3 == *probe_ptr) -+ { -+ table = (struct xen_bin_image_table *) probe_ptr; -+ /* Checksum correct? */ -+ if (0 == table->magic + table->flags + table->checksum) -+ { -+ return table; -+ } -+ } -+ } -+ return NULL; -+} -+ -+static int xc_dom_probe_bin_kernel(struct xc_dom_image *dom) -+{ -+ struct xen_bin_image_table *table; -+ -+ table = find_table(dom); -+ if (!table) -+ return -EINVAL; -+ return 0; -+} -+ -+static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom) -+{ -+ struct xen_bin_image_table *image_info; -+ char *image = dom->kernel_blob; -+ size_t image_size = dom->kernel_size; -+ uint32_t start_addr; -+ uint32_t load_end_addr; -+ uint32_t bss_end_addr; -+ uint32_t pae_flags; -+ -+ image_info = find_table(dom); -+ if (!image_info) -+ return -EINVAL; -+ -+ xc_dom_printf("%s: multiboot header fields\n", __FUNCTION__); -+ xc_dom_printf(" flags: 0x%" PRIx32 "\n", image_info->flags); -+ xc_dom_printf(" header_addr: 0x%" PRIx32 "\n", image_info->header_addr); -+ xc_dom_printf(" load_addr: 0x%" PRIx32 "\n", image_info->load_addr); -+ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", image_info->load_end_addr); -+ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", image_info->bss_end_addr); -+ xc_dom_printf(" entry_addr: 0x%" PRIx32 "\n", image_info->entry_addr); -+ -+ /* Check the flags */ -+ if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) ) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, -+ "%s: xen_bin_image_table flags required " -+ "0x%08" PRIx32 " found 0x%08" PRIx32 "\n", -+ __FUNCTION__, FLAGS_REQUIRED, image_info->flags & FLAGS_MASK); -+ return -EINVAL; -+ } -+ -+ /* Sanity check on the addresses */ -+ if ( image_info->header_addr < image_info->load_addr || -+ ((char *) image_info - image) < -+ (image_info->header_addr - image_info->load_addr) ) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid header_addr.", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ start_addr = image_info->header_addr - ((char *)image_info - image); -+ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; -+ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; -+ -+ xc_dom_printf("%s: calculated addresses\n", __FUNCTION__); -+ xc_dom_printf(" start_addr: 0x%" PRIx32 "\n", start_addr); -+ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", load_end_addr); -+ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", bss_end_addr); -+ -+ if ( start_addr + image_size < load_end_addr ) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid load_end_addr.\n", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ if ( bss_end_addr < load_end_addr) -+ { -+ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.\n", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dom->kernel_seg.vstart = image_info->load_addr; -+ dom->kernel_seg.vend = bss_end_addr; -+ dom->parms.virt_base = start_addr; -+ dom->parms.virt_entry = image_info->entry_addr; -+ -+ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; -+ switch (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) { -+ case 0: -+ dom->guest_type = "xen-3.0-x86_32"; -+ break; -+ case 1: -+ dom->guest_type = "xen-3.0-x86_32p"; -+ break; -+ case 2: -+ dom->guest_type = "xen-3.0-x86_64"; -+ break; -+ case 3: -+ /* Kernel detects PAE at runtime. So try to figure whenever -+ * xen supports PAE and advertise a PAE-capable kernel in case -+ * it does. */ -+ dom->guest_type = "xen-3.0-x86_32"; -+ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) { -+ xc_dom_printf("%s: PAE fixup\n", __FUNCTION__); -+ dom->guest_type = "xen-3.0-x86_32p"; -+ dom->parms.pae = 2; -+ } -+ break; -+ } -+ return 0; -+} -+ -+static int xc_dom_load_bin_kernel(struct xc_dom_image *dom) -+{ -+ struct xen_bin_image_table *image_info; -+ char *image = dom->kernel_blob; -+ char *dest; -+ size_t image_size = dom->kernel_size; -+ uint32_t start_addr; -+ uint32_t load_end_addr; -+ uint32_t bss_end_addr; -+ uint32_t skip, text_size, bss_size; -+ uint32_t pae_flags; -+ -+ image_info = find_table(dom); -+ if (!image_info) -+ return -EINVAL; -+ -+ start_addr = image_info->header_addr - ((char *)image_info - image); -+ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; -+ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; -+ -+ /* It's possible that we need to skip the first part of the image */ -+ skip = image_info->load_addr - start_addr; -+ text_size = load_end_addr - image_info->load_addr; -+ bss_size = bss_end_addr - load_end_addr; -+ -+ xc_dom_printf("%s: calculated sizes\n", __FUNCTION__); -+ xc_dom_printf(" skip: 0x%" PRIx32 "\n", skip); -+ xc_dom_printf(" text_size: 0x%" PRIx32 "\n", text_size); -+ xc_dom_printf(" bss_size: 0x%" PRIx32 "\n", bss_size); -+ -+ dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart); -+ memcpy(dest, image + skip, text_size); -+ memset(dest + text_size, 0, bss_size); -+ -+ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; -+ if (3 == (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) && dom->guest_xc > 0) -+ { -+ } -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static struct xc_dom_loader bin_loader = { -+ .name = "multiboot-binary", -+ .probe = xc_dom_probe_bin_kernel, -+ .parser = xc_dom_parse_bin_kernel, -+ .loader = xc_dom_load_bin_kernel, -+}; -+ -+static void __init register_loader(void) -+{ -+ xc_dom_register_loader(&bin_loader); -+} -+ -+/* -+ * Local variables: -+ * c-basic-offset: 4 -+ * End: -+ */ +libxc domain builder rewrite, core bits. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/Makefile | 14 + tools/libxc/xc_dom.h | 261 +++++++++++++ + tools/libxc/xc_dom_binloader.c | 294 +++++++++++++++ + tools/libxc/xc_dom_boot.c | 592 +++++++++++++++++++++++++++++++ + tools/libxc/xc_dom_core.c | 776 +++++++++++++++++++++++++++++++++++++++++ + tools/libxc/xc_dom_elfloader.c | 283 ++++++++++++++ + tools/libxc/xc_dom_ia64.c | 119 ++++++ + tools/libxc/xc_dom_powerpc64.c | 100 +++++ + tools/libxc/xc_dom_x86.c | 561 +++++++++++++++++++++++++++++ + 9 files changed, 3000 insertions(+) + +Index: build-32-release304-13138/tools/libxc/Makefile +=================================================================== +--- build-32-release304-13138.orig/tools/libxc/Makefile ++++ build-32-release304-13138/tools/libxc/Makefile +@@ -44,6 +44,20 @@ $(LIBELF_SRCS) libelf-private.h: + # add libelf bits to libxc + GUEST_SRCS-y += $(LIBELF_SRCS) + ++# new domain builder ++GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c ++GUEST_SRCS-y += xc_dom_elfloader.c ++GUEST_SRCS-y += xc_dom_binloader.c ++ ++ifeq ($(CONFIG_POWERPC),y) ++# big endian boxes ++GUEST_SRCS-y += xc_dom_powerpc64.c ++else ++# little endian boxes ++GUEST_SRCS-y += xc_dom_x86.c ++GUEST_SRCS-y += xc_dom_ia64.c ++endif ++ + -include $(XEN_TARGET_ARCH)/Makefile + + CFLAGS += -Werror -Wmissing-prototypes +Index: build-32-release304-13138/tools/libxc/xc_dom.h +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom.h +@@ -0,0 +1,261 @@ ++#include ++ ++#define INVALID_P2M_ENTRY ((xen_pfn_t)-1) ++ ++/* --- typedefs and structs ---------------------------------------- */ ++ ++typedef uint64_t xen_vaddr_t; ++typedef uint64_t xen_paddr_t; ++ ++/* FIXME: temporary hack ... */ ++#ifndef PRIpfn ++#define PRIpfn "lx" ++#endif ++ ++struct xc_dom_seg { ++ xen_vaddr_t vstart; ++ xen_vaddr_t vend; ++ xen_pfn_t pfn; ++}; ++ ++struct xc_dom_mem { ++ struct xc_dom_mem *next; ++ void *mmap_ptr; ++ size_t mmap_len; ++ unsigned char memory[0]; ++}; ++ ++struct xc_dom_phys { ++ struct xc_dom_phys *next; ++ void *ptr; ++ xen_pfn_t first; ++ xen_pfn_t count; ++}; ++ ++struct xc_dom_image { ++ /* files */ ++ void *kernel_blob; ++ size_t kernel_size; ++ void *ramdisk_blob; ++ size_t ramdisk_size; ++ ++ /* arguments and parameters */ ++ char *cmdline; ++ uint32_t f_requested[XENFEAT_NR_SUBMAPS]; ++ ++ /* info from (elf) kernel image */ ++ struct elf_dom_parms parms; ++ char *guest_type; ++ ++ /* memory layout */ ++ struct xc_dom_seg kernel_seg; ++ struct xc_dom_seg ramdisk_seg; ++ struct xc_dom_seg p2m_seg; ++ struct xc_dom_seg pgtables_seg; ++ xen_pfn_t start_info_pfn; ++ xen_pfn_t console_pfn; ++ xen_pfn_t xenstore_pfn; ++ xen_pfn_t shared_info_pfn; ++ xen_pfn_t bootstack_pfn; ++ xen_vaddr_t virt_alloc_end; ++ xen_vaddr_t bsd_symtab_start; ++ ++ /* initial page tables */ ++ unsigned int pgtables; ++ unsigned int pg_l4; ++ unsigned int pg_l3; ++ unsigned int pg_l2; ++ unsigned int pg_l1; ++ unsigned int alloc_bootstack; ++ unsigned int extra_pages; ++ xen_vaddr_t virt_pgtab_end; ++ ++ /* other state info */ ++ uint32_t f_active[XENFEAT_NR_SUBMAPS]; ++ xen_pfn_t *p2m_host; ++ void *p2m_guest; ++ ++ /* physical memory */ ++ xen_pfn_t total_pages; ++ struct xc_dom_phys *phys_pages; ++ ++ /* malloc memory pool */ ++ struct xc_dom_mem *memblocks; ++ ++ /* memory footprint stats */ ++ size_t alloc_malloc; ++ size_t alloc_mem_map; ++ size_t alloc_file_map; ++ size_t alloc_domU_map; ++ ++ /* misc xen domain config stuff */ ++ unsigned long flags; ++ unsigned int console_evtchn; ++ unsigned int xenstore_evtchn; ++ xen_pfn_t shared_info_mfn; ++ ++ int guest_xc; ++ domid_t guest_domid; ++ int shadow_enabled; ++ ++ int xen_version; ++ xen_capabilities_info_t xen_caps; ++ ++ /* kernel loader, arch hooks */ ++ struct xc_dom_loader *kernel_loader; ++ void *private_loader; ++ ++ /* kernel loader */ ++ struct xc_dom_arch *arch_hooks; ++}; ++ ++/* --- pluggable kernel loader ------------------------------------- */ ++ ++struct xc_dom_loader { ++ char *name; ++ int (*probe) (struct xc_dom_image * dom); ++ int (*parser) (struct xc_dom_image * dom); ++ int (*loader) (struct xc_dom_image * dom); ++ ++ struct xc_dom_loader *next; ++}; ++ ++#define __init __attribute__ ((constructor)) ++void xc_dom_register_loader(struct xc_dom_loader *loader); ++ ++/* --- arch specific hooks ----------------------------------------- */ ++ ++struct xc_dom_arch { ++ /* pagetable setup */ ++ int (*alloc_magic_pages) (struct xc_dom_image * dom); ++ int (*count_pgtables) (struct xc_dom_image * dom); ++ int (*setup_pgtables) (struct xc_dom_image * dom); ++ ++ /* arch-specific data structs setup */ ++ int (*start_info) (struct xc_dom_image * dom); ++ int (*shared_info) (struct xc_dom_image * dom, void *shared_info); ++ int (*vcpu) (struct xc_dom_image * dom, void *vcpu_ctxt); ++ ++ char *guest_type; ++ int page_shift; ++ int sizeof_pfn; ++ ++ struct xc_dom_arch *next; ++}; ++void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks); ++ ++#define XC_DOM_PAGE_SHIFT(dom) ((dom)->arch_hooks->page_shift) ++#define XC_DOM_PAGE_SIZE(dom) (1 << (dom)->arch_hooks->page_shift) ++ ++/* --- main functions ---------------------------------------------- */ ++ ++struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features); ++void xc_dom_release_phys(struct xc_dom_image *dom); ++void xc_dom_release(struct xc_dom_image *dom); ++int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb); ++ ++size_t xc_dom_check_gzip(void *blob, size_t ziplen); ++int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen); ++int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size); ++ ++int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename); ++int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename); ++int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize); ++int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize); ++ ++int xc_dom_parse_image(struct xc_dom_image *dom); ++int xc_dom_build_image(struct xc_dom_image *dom); ++int xc_dom_update_guest_p2m(struct xc_dom_image *dom); ++ ++int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid); ++int xc_dom_boot_mem_init(struct xc_dom_image *dom); ++void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count); ++int xc_dom_boot_image(struct xc_dom_image *dom); ++int xc_dom_compat_check(struct xc_dom_image *dom); ++ ++/* --- debugging bits ---------------------------------------------- */ ++ ++extern FILE *xc_dom_logfile; ++ ++void xc_dom_loginit(void); ++int xc_dom_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); ++int xc_dom_panic_func(const char *file, int line, xc_error_code err, ++ const char *fmt, ...) ++ __attribute__ ((format(printf, 4, 5))); ++#define xc_dom_panic(err, fmt, args...) \ ++ xc_dom_panic_func(__FILE__, __LINE__, err, fmt, ## args) ++#define xc_dom_trace(mark) \ ++ xc_dom_printf("%s:%d: trace %s\n", __FILE__, __LINE__, mark) ++ ++void xc_dom_log_memory_footprint(struct xc_dom_image *dom); ++ ++/* --- simple memory pool ------------------------------------------ */ ++ ++void *xc_dom_malloc(struct xc_dom_image *dom, size_t size); ++void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size); ++void *xc_dom_malloc_filemap(struct xc_dom_image *dom, ++ const char *filename, size_t * size); ++char *xc_dom_strdup(struct xc_dom_image *dom, const char *str); ++ ++/* --- alloc memory pool ------------------------------------------- */ ++ ++int xc_dom_alloc_page(struct xc_dom_image *dom, char *name); ++int xc_dom_alloc_segment(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg, char *name, ++ xen_vaddr_t start, xen_vaddr_t size); ++ ++/* --- misc bits --------------------------------------------------- */ ++ ++void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first, ++ xen_pfn_t count); ++void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn); ++void xc_dom_unmap_all(struct xc_dom_image *dom); ++ ++static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg) ++{ ++ xen_vaddr_t segsize = seg->vend - seg->vstart; ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t pages = (segsize + page_size - 1) / page_size; ++ ++ return xc_dom_pfn_to_ptr(dom, seg->pfn, pages); ++} ++ ++static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom, ++ xen_vaddr_t vaddr) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t page = (vaddr - dom->parms.virt_base) / page_size; ++ unsigned int offset = (vaddr - dom->parms.virt_base) % page_size; ++ void *ptr = xc_dom_pfn_to_ptr(dom, page, 0); ++ ++ if (!ptr) ++ return NULL; ++ return ptr + offset; ++} ++ ++static inline int xc_dom_feature_translated(struct xc_dom_image *dom) ++{ ++ return elf_xen_feature_get(XENFEAT_auto_translated_physmap, dom->f_active); ++} ++ ++static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ if (dom->shadow_enabled) ++ return pfn; ++ return dom->p2m_host[pfn]; ++} ++ ++static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom, ++ xen_pfn_t pfn) ++{ ++ if (xc_dom_feature_translated(dom)) ++ return pfn; ++ return dom->p2m_host[pfn]; ++} ++ ++/* --- arch bits --------------------------------------------------- */ ++ +Index: build-32-release304-13138/tools/libxc/xc_dom_boot.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_boot.c +@@ -0,0 +1,592 @@ ++/* ++ * Xen domain builder -- xen booter. ++ * ++ * This is the code which actually boots a fresh ++ * prepared domain image as xen guest domain. ++ * ++ * ==> this is the only domain bilder code piece ++ * where xen hypercalls are allowed <== ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++#include ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int setup_hypercall_page(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ xen_pfn_t pfn; ++ int rc; ++ ++ if (-1 == dom->parms.virt_hypercall) ++ return 0; ++ pfn = (dom->parms.virt_hypercall - dom->parms.virt_base) ++ >> XC_DOM_PAGE_SHIFT(dom); ++ ++ xc_dom_printf("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "\n", __FUNCTION__, ++ dom->parms.virt_hypercall, pfn); ++ domctl.cmd = XEN_DOMCTL_hypercall_init; ++ domctl.domain = dom->guest_domid; ++ domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn); ++ rc = do_domctl(dom->guest_xc, &domctl); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++} ++ ++static int launch_vm(int xc, domid_t domid, void *ctxt) ++{ ++ DECLARE_DOMCTL; ++ int rc; ++ ++ xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt); ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.cmd = XEN_DOMCTL_setvcpucontext; ++ domctl.domain = domid; ++ domctl.u.vcpucontext.vcpu = 0; ++ set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc); ++ return rc; ++} ++ ++static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ xen_pfn_t dst; ++ int rc; ++ ++ if (0 == pfn) ++ return 0; ++ ++ dst = xc_dom_p2m_host(dom, pfn); ++ xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, pfn, dst); ++ rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn ++ ", rc=%d)\n", __FUNCTION__, pfn, rc); ++ return rc; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: x86 bits */ ++ ++#if defined(__i386__) || defined(__x86_64__) ++ ++static int x86_compat(int xc, domid_t domid, char *guest_type) ++{ ++#if defined(XEN_DOMCTL_set_address_size) ++ ++ /* stable api, 3.0.5 final */ ++ static const struct { ++ char *guest; ++ uint32_t size; ++ } types[] = { ++ { "xen-3.0-x86_32p", 32 }, ++ { "xen-3.0-x86_64", 64 }, ++ }; ++ DECLARE_DOMCTL; ++ int i,rc; ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.domain = domid; ++ domctl.cmd = XEN_DOMCTL_set_address_size; ++ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, guest_type)) ++ domctl.u.address_size.size = types[i].size; ++ if (0 == domctl.u.address_size.size) ++ /* nothing to do */ ++ return 0; ++ ++ xc_dom_printf("%s: guest %s, address size %" PRId32 "\n", __FUNCTION__, ++ guest_type, domctl.u.address_size.size); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_printf("%s: warning: failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++ ++#elif defined(XEN_DOMCTL_set_compat) ++ ++ /* temporary, 3.0.4 patches and 3.0.5 initial merge */ ++ static const struct { ++ char *guest; ++ unsigned long cmd; ++ } types[] = { ++ { "xen-3.0-x86_32p", XEN_DOMCTL_set_compat }, ++ { "xen-3.0-x86_64", XEN_DOMCTL_set_native }, ++ }; ++ DECLARE_DOMCTL; ++ int i,rc; ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.domain = domid; ++ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, guest_type)) ++ domctl.cmd = types[i].cmd; ++ if (0 == domctl.cmd) ++ /* nothing to do */ ++ return 0; ++ ++ xc_dom_printf("%s: guest %s, cmd %d\n", __FUNCTION__, ++ guest_type, domctl.cmd); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_printf("%s: warning: failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++ ++#else ++#warn compiling without compat/native switching ++ xc_dom_printf("%s: compiled without compat/native switching\n", __FUNCTION__); ++ return 0; ++#endif ++} ++ ++ ++static int x86_shadow(int xc, domid_t domid) ++{ ++ int rc, mode; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ mode = XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | ++ XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE; ++ ++ rc = xc_shadow_control(xc, domid, ++ XEN_DOMCTL_SHADOW_OP_ENABLE, ++ NULL, 0, NULL, mode, NULL); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: SHADOW_OP_ENABLE (mode=0x%x) failed (rc=%d)\n", ++ __FUNCTION__, mode, rc); ++ return rc; ++ } ++ xc_dom_printf("%s: shadow enabled (mode=0x%x)\n", __FUNCTION__, mode); ++ return rc; ++} ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ int rc = 0; ++ ++ x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type); ++ if (xc_dom_feature_translated(dom)) ++ { ++ dom->shadow_enabled = 1; ++ rc = x86_shadow(dom->guest_xc, dom->guest_domid); ++ } ++ return rc; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ static const struct { ++ char *guest; ++ unsigned long pgd_type; ++ } types[] = { ++ { "xen-3.0-x86_32", MMUEXT_PIN_L2_TABLE}, ++ { "xen-3.0-x86_32p", MMUEXT_PIN_L3_TABLE}, ++ { "xen-3.0-x86_64", MMUEXT_PIN_L4_TABLE}, ++ }; ++ unsigned long pgd_type = 0; ++ shared_info_t *shared_info; ++ xen_pfn_t shinfo; ++ int i, rc; ++ ++ for (i = 0; i < sizeof(types) / sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, dom->guest_type)) ++ pgd_type = types[i].pgd_type; ++ ++ if (!xc_dom_feature_translated(dom)) ++ { ++ /* paravirtualized guest */ ++ xc_dom_unmap_one(dom, dom->pgtables_seg.pfn); ++ rc = pin_table(dom->guest_xc, pgd_type, ++ xc_dom_p2m_host(dom, dom->pgtables_seg.pfn), ++ dom->guest_domid); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: pin_table failed (pfn 0x%" PRIpfn ", rc=%d)\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, rc); ++ return rc; ++ } ++ shinfo = dom->shared_info_mfn; ++ } ++ else ++ { ++ /* paravirtualized guest with auto-translation */ ++ struct xen_add_to_physmap xatp; ++ int i; ++ ++ /* Map shared info frame into guest physmap. */ ++ xatp.domid = dom->guest_domid; ++ xatp.space = XENMAPSPACE_shared_info; ++ xatp.idx = 0; ++ xatp.gpfn = dom->shared_info_pfn; ++ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); ++ if (rc != 0) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed " ++ "(pfn=0x%" PRIpfn ", rc=%d)\n", ++ __FUNCTION__, xatp.gpfn, rc); ++ return rc; ++ } ++ ++ /* Map grant table frames into guest physmap. */ ++ for (i = 0;; i++) ++ { ++ xatp.domid = dom->guest_domid; ++ xatp.space = XENMAPSPACE_grant_table; ++ xatp.idx = i; ++ xatp.gpfn = dom->total_pages + i; ++ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); ++ if (rc != 0) ++ { ++ if (i > 0 && errno == EINVAL) ++ { ++ xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__, ++ i); ++ break; ++ } ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: mapping grant tables failed " "(pfn=0x%" ++ PRIpfn ", rc=%d)\n", __FUNCTION__, xatp.gpfn, rc); ++ return rc; ++ } ++ } ++ shinfo = dom->shared_info_pfn; ++ } ++ ++ /* setup shared_info page */ ++ xc_dom_printf("%s: shared_info: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->shared_info_pfn, dom->shared_info_mfn); ++ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, ++ PAGE_SIZE_X86, ++ PROT_READ | PROT_WRITE, ++ shinfo); ++ if (NULL == shared_info) ++ return -1; ++ dom->arch_hooks->shared_info(dom, shared_info); ++ munmap(shared_info, PAGE_SIZE_X86); ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: ia64 */ ++ ++#elif defined(__ia64__) ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ int rc; ++ ++ xc_dom_printf("%s: setup firmware\n", __FUNCTION__); ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.cmd = XEN_DOMCTL_arch_setup; ++ domctl.domain = dom->guest_domid; ++ domctl.u.arch_setup.flags = 0; ++ ++ domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT) ++ + sizeof(start_info_t); ++ /* 3 = start info page, xenstore page and console page */ ++ domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT; ++ rc = do_domctl(dom->guest_xc, &domctl); ++ return rc; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ shared_info_t *shared_info; ++ ++ /* setup shared_info page */ ++ xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->shared_info_mfn); ++ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, ++ page_size, ++ PROT_READ | PROT_WRITE, ++ dom->shared_info_mfn); ++ if (NULL == shared_info) ++ return -1; ++ dom->arch_hooks->shared_info(dom, shared_info); ++ munmap(shared_info, page_size); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: powerpc */ ++ ++#elif defined(__powerpc64__) ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ start_info_t *si = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ ++ xc_dom_printf("%s: TODO: setup devtree\n", __FUNCTION__); ++ ++#if 0 ++ load_devtree(dom->guest_xc, ++ dom->guest_domid, ++ dom->p2m_host, ++ devtree, // FIXME ++ devtree_addr, // FIXME ++ dom->ramdisk_seg.vstart, ++ dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart, ++ si, ++ dom->start_info_pfn << PAGE_SHIFT); ++#endif ++ return rc; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: other */ ++ ++#else ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++#endif /* arch stuff */ ++ ++/* ------------------------------------------------------------------------ */ ++ ++int xc_dom_compat_check(struct xc_dom_image *dom) ++{ ++ xen_capabilities_info_t xen_caps; ++ char *item, *ptr; ++ int match, found = 0; ++ ++ strcpy(xen_caps, dom->xen_caps); ++ for (item = strtok_r(xen_caps, " ", &ptr); ++ NULL != item; item = strtok_r(NULL, " ", &ptr)) ++ { ++ match = (0 == strcmp(dom->guest_type, item)); ++ xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__, ++ item, match ? " <= matches" : ""); ++ if (match) ++ found++; ++ } ++ if (!found) ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: guest type %s not supported by xen kernel, sorry\n", ++ __FUNCTION__, dom->guest_type); ++ ++ return found; ++} ++ ++int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid) ++{ ++ dom->guest_xc = xc; ++ dom->guest_domid = domid; ++ ++ dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL); ++ if (xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0) { ++ xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities"); ++ return -1; ++ } ++ xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__, ++ dom->xen_version >> 16, dom->xen_version & 0xff, ++ dom->xen_caps); ++ return 0; ++} ++ ++int xc_dom_boot_mem_init(struct xc_dom_image *dom) ++{ ++ long rc; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ if (0 != (rc = arch_setup_meminit(dom))) ++ return rc; ++ ++ /* allocate guest memory */ ++ rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, ++ dom->total_pages, 0, 0, ++ dom->p2m_host); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_OUT_OF_MEMORY, ++ "%s: can't allocate low memory for domain\n", ++ __FUNCTION__); ++ return rc; ++ } ++ ++ return 0; ++} ++ ++void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count) ++{ ++ int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ privcmd_mmap_entry_t *entries; ++ void *ptr; ++ int i, rc; ++ ++ entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); ++ if (NULL == entries) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [malloc]\n", __FUNCTION__, pfn, count); ++ return NULL; ++ } ++ ++ ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE, ++ MAP_SHARED, dom->guest_xc, 0); ++ if (MAP_FAILED == ptr) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [mmap]\n", __FUNCTION__, pfn, count); ++ return NULL; ++ } ++ ++ for (i = 0; i < count; i++) ++ { ++ entries[i].va = (uintptr_t) ptr + (i << page_shift); ++ entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); ++ entries[i].npages = 1; ++ } ++ ++ rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, entries, count); ++ if (rc < 0) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc); ++ return NULL; ++ } ++ return ptr; ++} ++ ++int xc_dom_boot_image(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ void *ctxt; ++ int rc; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* misc ia64 stuff*/ ++ if (0 != (rc = arch_setup_bootearly(dom))) ++ return rc; ++ ++ /* collect some info */ ++ domctl.cmd = XEN_DOMCTL_getdomaininfo; ++ domctl.domain = dom->guest_domid; ++ rc = do_domctl(dom->guest_xc, &domctl); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: getdomaininfo failed (rc=%d)\n", __FUNCTION__, rc); ++ return rc; ++ } ++ if (domctl.domain != dom->guest_domid) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: Huh? domid mismatch (%d != %d)\n", __FUNCTION__, ++ domctl.domain, dom->guest_domid); ++ return -1; ++ } ++ dom->shared_info_mfn = domctl.u.getdomaininfo.shared_info_frame; ++ ++ /* sanity checks */ ++ if (!xc_dom_compat_check(dom)) ++ return -1; ++ ++ /* initial mm setup */ ++ if (0 != (rc = xc_dom_update_guest_p2m(dom))) ++ return rc; ++ if (dom->arch_hooks->setup_pgtables) ++ if (0 != (rc = dom->arch_hooks->setup_pgtables(dom))) ++ return rc; ++ ++ if (0 != (rc = clear_page(dom, dom->console_pfn))) ++ return rc; ++ if (0 != (rc = clear_page(dom, dom->xenstore_pfn))) ++ return rc; ++ ++ /* start info page */ ++ if (dom->arch_hooks->start_info) ++ dom->arch_hooks->start_info(dom); ++ ++ /* hypercall page */ ++ if (0 != (rc = setup_hypercall_page(dom))) ++ return rc; ++ xc_dom_log_memory_footprint(dom); ++ ++ /* misc x86 stuff */ ++ if (0 != (rc = arch_setup_bootlate(dom))) ++ return rc; ++ ++ /* let the vm run */ ++ ctxt = xc_dom_malloc(dom, PAGE_SIZE * 2 /* FIXME */ ); ++ memset(ctxt, 0, PAGE_SIZE * 2); ++ if (0 != (rc = dom->arch_hooks->vcpu(dom, ctxt))) ++ return rc; ++ xc_dom_unmap_all(dom); ++ rc = launch_vm(dom->guest_xc, dom->guest_domid, ctxt); ++ ++ return rc; ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_core.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_core.c +@@ -0,0 +1,776 @@ ++/* ++ * Xen domain builder -- core bits. ++ * ++ * The core code goes here: ++ * - allocate and release domain structs. ++ * - memory management functions. ++ * - misc helper functions. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++/* debugging */ ++ ++FILE *xc_dom_logfile = NULL; ++ ++void xc_dom_loginit(void) ++{ ++ if (xc_dom_logfile) ++ return; ++ xc_dom_logfile = fopen("/var/log/xen/domain-builder-ng.log", "a"); ++ setvbuf(xc_dom_logfile, NULL, _IONBF, 0); ++ xc_dom_printf("### ----- xc domain builder logfile opened -----\n"); ++} ++ ++int xc_dom_printf(const char *fmt, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int rc; ++ ++ if (!xc_dom_logfile) ++ return 0; ++ ++ va_start(args, fmt); ++ rc = vsnprintf(buf, sizeof(buf), fmt, args); ++ va_end(args); ++ rc = fwrite(buf, rc, 1, xc_dom_logfile); ++ ++ return rc; ++} ++ ++int xc_dom_panic_func(const char *file, int line, xc_error_code err, ++ const char *fmt, ...) ++{ ++ va_list args; ++ FILE *fp = stderr; ++ int rc = 0; ++ char pos[256]; ++ char msg[XC_MAX_ERROR_MSG_LEN]; ++ ++ if (xc_dom_logfile) ++ fp = xc_dom_logfile; ++ ++ snprintf(pos, sizeof(pos), "%s:%d: panic: ", file, line); ++ va_start(args, fmt); ++ vsnprintf(msg, sizeof(msg), fmt, args); ++ va_end(args); ++ xc_set_error(err, "%s", msg); ++ rc = fprintf(fp, "%s%s", pos, msg); ++ return rc; ++} ++ ++static void print_mem(const char *name, size_t mem) ++{ ++ if (mem > 32 * 1024 * 1024) ++ xc_dom_printf("%-24s : %zd MB\n", name, mem / (1024 * 1024)); ++ else if (mem > 32 * 1024) ++ xc_dom_printf("%-24s : %zd kB\n", name, mem / 1024); ++ else ++ xc_dom_printf("%-24s : %zd bytes\n", name, mem); ++} ++ ++void xc_dom_log_memory_footprint(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("domain builder memory footprint\n"); ++ xc_dom_printf(" allocated\n"); ++ print_mem(" malloc", dom->alloc_malloc); ++ print_mem(" anon mmap", dom->alloc_mem_map); ++ xc_dom_printf(" mapped\n"); ++ print_mem(" file mmap", dom->alloc_file_map); ++ print_mem(" domU mmap", dom->alloc_domU_map); ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* simple memory pool */ ++ ++void *xc_dom_malloc(struct xc_dom_image *dom, size_t size) ++{ ++ struct xc_dom_mem *block; ++ ++ block = malloc(sizeof(*block) + size); ++ if (NULL == block) ++ return NULL; ++ memset(block, 0, sizeof(*block) + size); ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block) + size; ++ if (size > 100 * 1024) ++ print_mem(__FUNCTION__, size); ++ return block->memory; ++} ++ ++void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size) ++{ ++ struct xc_dom_mem *block; ++ ++ block = malloc(sizeof(*block)); ++ if (NULL == block) ++ return NULL; ++ memset(block, 0, sizeof(*block)); ++ block->mmap_len = size; ++ block->mmap_ptr = mmap(NULL, block->mmap_len, ++ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, 0); ++ if (MAP_FAILED == block->mmap_ptr) ++ { ++ free(block); ++ return NULL; ++ } ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block); ++ dom->alloc_mem_map += block->mmap_len; ++ if (size > 100 * 1024) ++ print_mem(__FUNCTION__, size); ++ return block->mmap_ptr; ++} ++ ++void *xc_dom_malloc_filemap(struct xc_dom_image *dom, ++ const char *filename, size_t * size) ++{ ++ struct xc_dom_mem *block = NULL; ++ int fd = -1; ++ ++ fd = open(filename, O_RDONLY); ++ if (-1 == fd) ++ goto err; ++ ++ lseek(fd, 0, SEEK_SET); ++ *size = lseek(fd, 0, SEEK_END); ++ ++ block = malloc(sizeof(*block)); ++ if (NULL == block) ++ goto err; ++ memset(block, 0, sizeof(*block)); ++ block->mmap_len = *size; ++ block->mmap_ptr = mmap(NULL, block->mmap_len, PROT_READ, MAP_SHARED, fd, 0); ++ if (MAP_FAILED == block->mmap_ptr) ++ goto err; ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block); ++ dom->alloc_file_map += block->mmap_len; ++ close(fd); ++ if (*size > 100 * 1024) ++ print_mem(__FUNCTION__, *size); ++ return block->mmap_ptr; ++ ++ err: ++ if (-1 != fd) ++ close(fd); ++ if (block) ++ free(block); ++ return NULL; ++} ++ ++static void xc_dom_free_all(struct xc_dom_image *dom) ++{ ++ struct xc_dom_mem *block; ++ ++ while (NULL != (block = dom->memblocks)) ++ { ++ dom->memblocks = block->next; ++ if (block->mmap_ptr) ++ munmap(block->mmap_ptr, block->mmap_len); ++ free(block); ++ } ++} ++ ++char *xc_dom_strdup(struct xc_dom_image *dom, const char *str) ++{ ++ size_t len = strlen(str) + 1; ++ char *nstr = xc_dom_malloc(dom, len); ++ ++ if (NULL == nstr) ++ return NULL; ++ memcpy(nstr, str, len); ++ return nstr; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* read files, copy memory blocks, with transparent gunzip */ ++ ++size_t xc_dom_check_gzip(void *blob, size_t ziplen) ++{ ++ unsigned char *gzlen; ++ size_t unziplen; ++ ++ if (0 != strncmp(blob, "\037\213", 2)) ++ /* not gzipped */ ++ return 0; ++ ++ gzlen = blob + ziplen - 4; ++ unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0]; ++ if (unziplen < ziplen || unziplen > ziplen * 8) ++ { ++ xc_dom_printf ++ ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n", ++ __FUNCTION__, ziplen, unziplen); ++ return 0; ++ } ++ ++ return unziplen + 16; ++} ++ ++int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen) ++{ ++ z_stream zStream; ++ int rc; ++ ++ memset(&zStream, 0, sizeof(zStream)); ++ zStream.next_in = src; ++ zStream.avail_in = srclen; ++ zStream.next_out = dst; ++ zStream.avail_out = dstlen; ++ rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" */ ++ if (rc != Z_OK) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc); ++ return -1; ++ } ++ rc = inflate(&zStream, Z_FINISH); ++ if (rc != Z_STREAM_END) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc); ++ return -1; ++ } ++ ++ xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n", ++ __FUNCTION__, srclen, dstlen); ++ return 0; ++} ++ ++int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size) ++{ ++ void *unzip; ++ size_t unziplen; ++ ++ unziplen = xc_dom_check_gzip(*blob, *size); ++ if (0 == unziplen) ++ return 0; ++ ++ unzip = xc_dom_malloc(dom, unziplen); ++ if (NULL == unzip) ++ return -1; ++ ++ if (-1 == xc_dom_do_gunzip(*blob, *size, unzip, unziplen)) ++ return -1; ++ ++ *blob = unzip; ++ *size = unziplen; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* domain memory */ ++ ++void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count) ++{ ++ struct xc_dom_phys *phys; ++ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ char *mode = "unset"; ++ ++ if (pfn > dom->total_pages) ++ { ++ xc_dom_printf("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")\n", ++ __FUNCTION__, pfn, dom->total_pages); ++ return NULL; ++ } ++ ++ /* already allocated? */ ++ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) ++ { ++ if (pfn >= phys->first + phys->count) ++ continue; ++ if (count) ++ { ++ /* size given: must be completely within the already allocated block */ ++ if (pfn + count <= phys->first) ++ continue; ++ if (pfn < phys->first || pfn + count > phys->first + phys->count) ++ { ++ xc_dom_printf("%s: request overlaps allocated block" ++ " (req 0x%" PRIpfn "+0x%" PRIpfn "," ++ " blk 0x%" PRIpfn "+0x%" PRIpfn ")\n", ++ __FUNCTION__, pfn, count, phys->first, ++ phys->count); ++ return NULL; ++ } ++ } ++ else ++ { ++ /* no size given: block must be allocated already, ++ just hand out a pointer to it */ ++ if (pfn < phys->first) ++ continue; ++ } ++ return phys->ptr + ((pfn - phys->first) << page_shift); ++ } ++ ++ /* allocating is allowed with size specified only */ ++ if (0 == count) ++ { ++ xc_dom_printf("%s: no block found, no size given," ++ " can't malloc (pfn 0x%" PRIpfn ")\n", __FUNCTION__, pfn); ++ return NULL; ++ } ++ ++ /* not found, no overlap => allocate */ ++ phys = xc_dom_malloc(dom, sizeof(*phys)); ++ if (NULL == phys) ++ return NULL; ++ memset(phys, 0, sizeof(*phys)); ++ phys->first = pfn; ++ phys->count = count; ++ ++ if (dom->guest_domid) ++ { ++ mode = "domU mapping"; ++ phys->ptr = xc_dom_boot_domU_map(dom, phys->first, phys->count); ++ if (NULL == phys->ptr) ++ return NULL; ++ dom->alloc_domU_map += phys->count << page_shift; ++ } ++ else ++ { ++ mode = "anonymous memory"; ++ phys->ptr = mmap(NULL, phys->count << page_shift, ++ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, 0); ++ if (MAP_FAILED == phys->ptr) ++ { ++ xc_dom_panic(XC_OUT_OF_MEMORY, ++ "%s: oom: can't allocate 0x%" PRIpfn " pages\n", ++ __FUNCTION__, count); ++ return NULL; ++ } ++ dom->alloc_mem_map += phys->count << page_shift; ++ } ++ ++#if 1 ++ xc_dom_printf("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p\n", ++ __FUNCTION__, mode, phys->first, phys->count, phys->ptr); ++#endif ++ phys->next = dom->phys_pages; ++ dom->phys_pages = phys; ++ return phys->ptr; ++} ++ ++int xc_dom_alloc_segment(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg, char *name, ++ xen_vaddr_t start, xen_vaddr_t size) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t pages = (size + page_size - 1) / page_size; ++ void *ptr; ++ ++ if (0 == start) ++ start = dom->virt_alloc_end; ++ ++ if (start & (page_size - 1)) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: segment start isn't page aligned (0x%" PRIx64 ")\n", ++ __FUNCTION__, start); ++ return -1; ++ } ++ if (start < dom->virt_alloc_end) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64 ++ ")\n", __FUNCTION__, start, dom->virt_alloc_end); ++ return -1; ++ } ++ ++ seg->vstart = start; ++ seg->vend = start + pages * page_size; ++ seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size; ++ dom->virt_alloc_end = seg->vend; ++ ++ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " -> 0x%" PRIx64 ++ " (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n", ++ __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages); ++ ++ /* map and clear pages */ ++ ptr = xc_dom_seg_to_ptr(dom, seg); ++ if (NULL == ptr) ++ return -1; ++ memset(ptr, 0, pages * page_size); ++ ++ return 0; ++} ++ ++int xc_dom_alloc_page(struct xc_dom_image *dom, char *name) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_vaddr_t start; ++ xen_pfn_t pfn; ++ ++ start = dom->virt_alloc_end; ++ dom->virt_alloc_end += page_size; ++ pfn = (start - dom->parms.virt_base) / page_size; ++ ++ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n", ++ __FUNCTION__, name, start, pfn); ++ return pfn; ++} ++ ++void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ struct xc_dom_phys *phys, *prev = NULL; ++ ++ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) ++ { ++ if (pfn >= phys->first && pfn < phys->first + phys->count) ++ break; ++ prev = phys; ++ } ++ if (!phys) ++ { ++ xc_dom_printf("%s: Huh? no mapping with pfn 0x%" PRIpfn "\n", ++ __FUNCTION__, pfn); ++ return; ++ } ++ ++ munmap(phys->ptr, phys->count << page_shift); ++ if (prev) ++ prev->next = phys->next; ++ else ++ dom->phys_pages = phys->next; ++} ++ ++void xc_dom_unmap_all(struct xc_dom_image *dom) ++{ ++ while (dom->phys_pages) ++ xc_dom_unmap_one(dom, dom->phys_pages->first); ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* pluggable kernel loaders */ ++ ++static struct xc_dom_loader *first_loader = NULL; ++static struct xc_dom_arch *first_hook = NULL; ++ ++void xc_dom_register_loader(struct xc_dom_loader *loader) ++{ ++ loader->next = first_loader; ++ first_loader = loader; ++} ++ ++static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom) ++{ ++ struct xc_dom_loader *loader = first_loader; ++ ++ while (NULL != loader) ++ { ++ xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name); ++ if (0 == loader->probe(dom)) ++ { ++ xc_dom_printf("OK\n"); ++ return loader; ++ } ++ xc_dom_printf("failed\n"); ++ loader = loader->next; ++ } ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__); ++ return NULL; ++} ++ ++void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks) ++{ ++ hooks->next = first_hook; ++ first_hook = hooks; ++} ++ ++static struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type) ++{ ++ struct xc_dom_arch *hooks = first_hook; ++ ++ while (NULL != hooks) ++ { ++ if (0 == strcmp(hooks->guest_type, guest_type)) ++ return hooks; ++ hooks = hooks->next; ++ } ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: not found (type %s)\n", __FUNCTION__, guest_type); ++ return NULL; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* public interface */ ++ ++void xc_dom_release(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ if (dom->phys_pages) ++ xc_dom_unmap_all(dom); ++ xc_dom_free_all(dom); ++ free(dom); ++} ++ ++struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features) ++{ ++ struct xc_dom_image *dom; ++ ++ xc_dom_printf("%s: cmdline=\"%s\", features=\"%s\"\n", ++ __FUNCTION__, cmdline, features); ++ dom = malloc(sizeof(*dom)); ++ if (!dom) ++ goto err; ++ ++ memset(dom, 0, sizeof(*dom)); ++ if (cmdline) ++ dom->cmdline = xc_dom_strdup(dom, cmdline); ++ if (features) ++ elf_xen_parse_features(features, dom->f_requested, NULL); ++ ++ dom->parms.virt_base = UNSET_ADDR; ++ dom->parms.virt_entry = UNSET_ADDR; ++ dom->parms.virt_hypercall = UNSET_ADDR; ++ dom->parms.virt_hv_start_low = UNSET_ADDR; ++ dom->parms.elf_paddr_offset = UNSET_ADDR; ++ ++ dom->alloc_malloc += sizeof(*dom); ++ return dom; ++ ++ err: ++ if (dom) ++ xc_dom_release(dom); ++ return NULL; ++} ++ ++int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename) ++{ ++ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); ++ dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size); ++ if (NULL == dom->kernel_blob) ++ return -1; ++ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); ++} ++ ++int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename) ++{ ++ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); ++ dom->ramdisk_blob = ++ xc_dom_malloc_filemap(dom, filename, &dom->ramdisk_size); ++ if (NULL == dom->ramdisk_blob) ++ return -1; ++// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); ++ return 0; ++} ++ ++int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t memsize) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ dom->kernel_blob = (void *)mem; ++ dom->kernel_size = memsize; ++ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); ++} ++ ++int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ dom->ramdisk_blob = (void *)mem; ++ dom->ramdisk_size = memsize; ++// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); ++ return 0; ++} ++ ++int xc_dom_parse_image(struct xc_dom_image *dom) ++{ ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* parse kernel image */ ++ dom->kernel_loader = xc_dom_find_loader(dom); ++ if (NULL == dom->kernel_loader) ++ goto err; ++ if (0 != dom->kernel_loader->parser(dom)) ++ goto err; ++ if (NULL == dom->guest_type) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: guest_type not set\n", __FUNCTION__); ++ goto err; ++ } ++ ++ /* check features */ ++ for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) ++ { ++ dom->f_active[i] |= dom->f_requested[i]; /* cmd line */ ++ dom->f_active[i] |= dom->parms.f_required[i]; /* kernel */ ++ if ((dom->f_active[i] & dom->parms.f_supported[i]) != dom->f_active[i]) ++ { ++ xc_dom_panic(XC_INVALID_PARAM, ++ "%s: unsupported feature requested\n", __FUNCTION__); ++ goto err; ++ } ++ } ++ return 0; ++ ++ err: ++ return -1; ++} ++ ++int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb) ++{ ++ unsigned int page_shift; ++ xen_pfn_t nr_pages, pfn; ++ ++ dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type); ++ if (NULL == dom->arch_hooks) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", ++ __FUNCTION__); ++ return -1; ++ } ++ ++ page_shift = XC_DOM_PAGE_SHIFT(dom); ++ nr_pages = mem_mb << (20 - page_shift); ++ ++ xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n", ++ __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10)); ++ dom->total_pages = nr_pages; ++ ++ xc_dom_printf("%s: 0x%" PRIpfn " pages\n", ++ __FUNCTION__, dom->total_pages); ++ ++ /* setup initial p2m */ ++ dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); ++ for (pfn = 0; pfn < dom->total_pages; pfn++) ++ dom->p2m_host[pfn] = pfn; ++ return 0; ++} ++ ++int xc_dom_update_guest_p2m(struct xc_dom_image *dom) ++{ ++ uint32_t *p2m_32; ++ uint64_t *p2m_64; ++ xen_pfn_t i; ++ ++ if (!dom->p2m_guest) ++ return 0; ++ ++ switch (dom->arch_hooks->sizeof_pfn) ++ { ++ case 4: ++ xc_dom_printf("%s: dst 32bit, pages 0x%" PRIpfn " \n", ++ __FUNCTION__, dom->total_pages); ++ p2m_32 = dom->p2m_guest; ++ for (i = 0; i < dom->total_pages; i++) ++ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) ++ p2m_32[i] = dom->p2m_host[i]; ++ else ++ p2m_32[i] = (uint32_t) - 1; ++ break; ++ case 8: ++ xc_dom_printf("%s: dst 64bit, pages 0x%" PRIpfn " \n", ++ __FUNCTION__, dom->total_pages); ++ p2m_64 = dom->p2m_guest; ++ for (i = 0; i < dom->total_pages; i++) ++ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) ++ p2m_64[i] = dom->p2m_host[i]; ++ else ++ p2m_64[i] = (uint64_t) - 1; ++ break; ++ default: ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "sizeof_pfn is invalid (is %d, can be 4 or 8)", ++ dom->arch_hooks->sizeof_pfn); ++ return -1; ++ } ++ return 0; ++} ++ ++int xc_dom_build_image(struct xc_dom_image *dom) ++{ ++ unsigned int page_size; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* check for arch hooks */ ++ if (NULL == dom->arch_hooks) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", ++ __FUNCTION__); ++ goto err; ++ } ++ page_size = XC_DOM_PAGE_SIZE(dom); ++ ++ /* 4MB align virtual base address */ ++ dom->parms.virt_base &= ~(((uint64_t)1<<22)-1); ++ ++ /* load kernel */ ++ if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel", ++ dom->kernel_seg.vstart, ++ dom->kernel_seg.vend - ++ dom->kernel_seg.vstart)) ++ goto err; ++ if (0 != dom->kernel_loader->loader(dom)) ++ goto err; ++ ++ /* load ramdisk */ ++ if (dom->ramdisk_blob) ++ { ++ size_t unziplen, ramdisklen; ++ void *ramdiskmap; ++ ++ unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size); ++ ramdisklen = unziplen ? unziplen : dom->ramdisk_size; ++ if (0 != xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0, ++ ramdisklen)) ++ goto err; ++ ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg); ++ if (unziplen) ++ { ++ if (-1 == xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size, ++ ramdiskmap, ramdisklen)) ++ goto err; ++ } ++ else ++ memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size); ++ } ++ ++ /* allocate other pages */ ++ if (0 != dom->arch_hooks->alloc_magic_pages(dom)) ++ goto err; ++ if (dom->arch_hooks->count_pgtables) ++ { ++ dom->arch_hooks->count_pgtables(dom); ++ if (dom->pgtables > 0) ++ if (0 != ++ xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0, ++ dom->pgtables * page_size)) ++ goto err; ++ } ++ if (dom->alloc_bootstack) ++ dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack"); ++ xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->virt_alloc_end); ++ xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->virt_pgtab_end); ++ return 0; ++ ++ err: ++ return -1; ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_ia64.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_ia64.c +@@ -0,0 +1,119 @@ ++/* ++ * Xen domain builder -- ia64 bits. ++ * ++ * Most architecture-specific code for ia64 goes here. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ /* allocate special pages */ ++ dom->console_pfn = dom->total_pages -1; ++ dom->xenstore_pfn = dom->total_pages -2; ++ dom->start_info_pfn = dom->total_pages -3; ++ return 0; ++} ++ ++static int start_info_ia64(struct xc_dom_image *dom) ++{ ++ start_info_ia64_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ struct xen_ia64_boot_param_ia64 *bp = ++ (struct xen_ia64_boot_param_ia64 *)(start_info + 1); ++ ++ xc_dom_printf("%s\n", __FUNCTION__); ++ ++ memset(start_info, 0, sizeof(*start_info)); ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->flags = dom->flags; ++ start_info->nr_pages = dom->total_pages; ++ start_info->store_mfn = dom->xenstore_pfn; ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = dom->console_pfn; ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ bp->initrd_start = start_info->mod_start; ++ bp->initrd_size = start_info->mod_len; ++ } ++ bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64) ++ + offsetof(start_info_t, cmd_line); ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int shared_info_ia64(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_ia64_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ shared_info->arch.start_info_pfn = dom->start_info_pfn; ++ return 0; ++} ++ ++extern unsigned long xc_ia64_fpsr_default(void); ++ ++static int vcpu_ia64(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_ia64_t *ctxt = ptr; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ ctxt->flags = 0; ++ ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ ++ ctxt->user_regs.cr_iip = dom->parms.virt_entry; ++ ctxt->user_regs.cr_ifs = (uint64_t) 1 << 63; ++#ifdef __ia64__ /* FIXME */ ++ ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); ++#endif ++ ctxt->user_regs.r28 = (dom->start_info_pfn << PAGE_SHIFT_IA64) ++ + sizeof(start_info_ia64_t); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_arch = { ++ .guest_type = "xen-3.0-ia64", ++ .page_shift = PAGE_SHIFT_IA64, ++ .alloc_magic_pages = alloc_magic_pages, ++ .start_info = start_info_ia64, ++ .shared_info = shared_info_ia64, ++ .vcpu = vcpu_ia64, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_arch); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_x86.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_x86.c +@@ -0,0 +1,561 @@ ++/* ++ * Xen domain builder -- i386 and x86_64 bits. ++ * ++ * Most architecture-specific code for x86 goes here. ++ * - prepare page tables. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++#define bits_to_mask(bits) (((xen_vaddr_t)1 << (bits))-1) ++#define round_down(addr, mask) ((addr) & ~(mask)) ++#define round_up(addr, mask) ((addr) | (mask)) ++ ++static inline unsigned long ++nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned long bits) ++{ ++ xen_vaddr_t mask = bits_to_mask(bits); ++ int tables; ++ ++ if (0 == bits) ++ return 0; /* unused */ ++ ++ if (8 * sizeof(unsigned long) == bits) ++ { ++ /* must be pgd, need one */ ++ start = 0; ++ end = -1; ++ tables = 1; ++ } ++ else ++ { ++ start = round_down(start, mask); ++ end = round_up(end, mask); ++ tables = ((end - start) >> bits) + 1; ++ } ++ ++ xc_dom_printf("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64 ++ " -> 0x%016" PRIx64 ", %d table(s)\n", ++ __FUNCTION__, mask, bits, start, end, tables); ++ return tables; ++} ++ ++static int count_pgtables(struct xc_dom_image *dom, int pae, ++ int l4_bits, int l3_bits, int l2_bits, int l1_bits) ++{ ++ int pages, extra_pages; ++ xen_vaddr_t try_virt_end; ++ ++ extra_pages = dom->alloc_bootstack ? 1 : 0; ++ extra_pages += dom->extra_pages; ++ extra_pages += 128; /* 512kB padding */ ++ pages = extra_pages; ++ for (;;) ++ { ++ try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86, ++ bits_to_mask(22)); /* 4MB alignment */ ++ dom->pg_l4 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits); ++ dom->pg_l3 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l3_bits); ++ dom->pg_l2 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l2_bits); ++ dom->pg_l1 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l1_bits); ++ if (pae && try_virt_end < 0xc0000000) ++ { ++ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); ++ dom->pg_l2++; ++ } ++ dom->pgtables = dom->pg_l4 + dom->pg_l3 + dom->pg_l2 + dom->pg_l1; ++ pages = dom->pgtables + extra_pages; ++ if (dom->virt_alloc_end + pages * PAGE_SIZE_X86 <= try_virt_end + 1) ++ break; ++ } ++ dom->virt_pgtab_end = try_virt_end + 1; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* i386 pagetables */ ++ ++#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) ++#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L3_PROT (_PAGE_PRESENT) ++ ++static int count_pgtables_x86_32(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 0, 0, 0, 32, L2_PAGETABLE_SHIFT_I386); ++} ++ ++static int count_pgtables_x86_32_pae(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 1, 0, 32, ++ L3_PAGETABLE_SHIFT_PAE, L2_PAGETABLE_SHIFT_PAE); ++} ++ ++#define pfn_to_paddr(pfn) ((xen_paddr_t)(pfn) << PAGE_SHIFT_X86) ++ ++static int setup_pgtables_x86_32(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l2; ++ l2_pgentry_32_t *l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l1_pgentry_32_t *l1tab = NULL; ++ unsigned long l2off, l1off; ++ xen_vaddr_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_i386(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_i386(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_I386 - 1 == l1off) ++ l1tab = NULL; ++ } ++ return 0; ++} ++ ++static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l3pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l3; ++ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l3 + dom->pg_l2; ++ l3_pgentry_64_t *l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); ++ l2_pgentry_64_t *l2tab = NULL; ++ l1_pgentry_64_t *l1tab = NULL; ++ unsigned long l3off, l2off, l1off; ++ xen_vaddr_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l2tab) ++ { ++ /* get L2 tab, make L3 entry */ ++ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l3off = l3_table_offset_pae(addr); ++ l3tab[l3off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ l2pfn++; ++ } ++ ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_pae(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ if (L2_PAGETABLE_ENTRIES_PAE - 1 == l2off) ++ l2tab = NULL; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_pae(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_PAE - 1 == l1off) ++ l1tab = NULL; ++ } ++ ++ if (dom->virt_pgtab_end <= 0xc0000000) ++ { ++ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); ++ l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ } ++ return 0; ++} ++ ++#undef L1_PROT ++#undef L2_PROT ++#undef L3_PROT ++ ++/* ------------------------------------------------------------------------ */ ++/* x86_64 pagetables */ ++ ++static int count_pgtables_x86_64(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 0, ++ L4_PAGETABLE_SHIFT_X86_64 + 9, ++ L4_PAGETABLE_SHIFT_X86_64, ++ L3_PAGETABLE_SHIFT_X86_64, L2_PAGETABLE_SHIFT_X86_64); ++} ++ ++#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) ++#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++ ++static int setup_pgtables_x86_64(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l4pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l3pfn = dom->pgtables_seg.pfn + dom->pg_l4; ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3; ++ xen_pfn_t l1pfn = ++ dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3 + dom->pg_l2; ++ l4_pgentry_64_t *l4tab = xc_dom_pfn_to_ptr(dom, l4pfn, 1); ++ l3_pgentry_64_t *l3tab = NULL; ++ l2_pgentry_64_t *l2tab = NULL; ++ l1_pgentry_64_t *l1tab = NULL; ++ uint64_t l4off, l3off, l2off, l1off; ++ uint64_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l3tab) ++ { ++ /* get L3 tab, make L4 entry */ ++ l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); ++ l4off = l4_table_offset_x86_64(addr); ++ l4tab[l4off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT; ++ l3pfn++; ++ } ++ ++ if (NULL == l2tab) ++ { ++ /* get L2 tab, make L3 entry */ ++ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l3off = l3_table_offset_x86_64(addr); ++ l3tab[l3off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ if (L3_PAGETABLE_ENTRIES_X86_64 - 1 == l3off) ++ l3tab = NULL; ++ l2pfn++; ++ } ++ ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_x86_64(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ if (L2_PAGETABLE_ENTRIES_X86_64 - 1 == l2off) ++ l2tab = NULL; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_x86_64(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_X86_64 - 1 == l1off) ++ l1tab = NULL; ++ } ++ return 0; ++} ++ ++#undef L1_PROT ++#undef L2_PROT ++#undef L3_PROT ++#undef L4_PROT ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ size_t p2m_size = dom->total_pages * dom->arch_hooks->sizeof_pfn; ++ ++ /* allocate phys2mach table */ ++ if (0 != xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size)) ++ return -1; ++ dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg); ++ ++ /* allocate special pages */ ++ dom->start_info_pfn = xc_dom_alloc_page(dom, "start info"); ++ dom->xenstore_pfn = xc_dom_alloc_page(dom, "xenstore"); ++ dom->console_pfn = xc_dom_alloc_page(dom, "console"); ++ if (xc_dom_feature_translated(dom)) ++ dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info"); ++ dom->alloc_bootstack = 1; ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int start_info_x86_32(struct xc_dom_image *dom) ++{ ++ start_info_x86_32_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ xen_pfn_t shinfo = ++ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> ++ shared_info_mfn; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->nr_pages = dom->total_pages; ++ start_info->shared_info = shinfo << PAGE_SHIFT_X86; ++ start_info->pt_base = dom->pgtables_seg.vstart; ++ start_info->nr_pt_frames = dom->pgtables; ++ start_info->mfn_list = dom->p2m_seg.vstart; ++ ++ start_info->flags = dom->flags; ++ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ } ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int start_info_x86_64(struct xc_dom_image *dom) ++{ ++ start_info_x86_64_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ xen_pfn_t shinfo = ++ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> ++ shared_info_mfn; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->nr_pages = dom->total_pages; ++ start_info->shared_info = shinfo << PAGE_SHIFT_X86; ++ start_info->pt_base = dom->pgtables_seg.vstart; ++ start_info->nr_pt_frames = dom->pgtables; ++ start_info->mfn_list = dom->p2m_seg.vstart; ++ ++ start_info->flags = dom->flags; ++ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ } ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int shared_info_x86_32(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_x86_32_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ return 0; ++} ++ ++static int shared_info_x86_64(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_x86_64_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_x86_32_t *ctxt = ptr; ++ xen_pfn_t cr3_pfn; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ /* Virtual IDT is empty at start-of-day. */ ++ for (i = 0; i < 256; i++) ++ { ++ ctxt->trap_ctxt[i].vector = i; ++ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_32; ++ } ++ ++ /* No callback handlers. */ ++ ctxt->event_callback_cs = FLAT_KERNEL_CS_X86_32; ++ ctxt->failsafe_callback_cs = FLAT_KERNEL_CS_X86_32; ++ ++ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32; ++ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32; ++ ctxt->user_regs.eip = dom->parms.virt_entry; ++ ctxt->user_regs.esp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ctxt->user_regs.esi = ++ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ++ ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ ++ ++ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_32; ++ ctxt->kernel_sp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ++ ctxt->flags = VGCF_in_kernel_X86_32; ++ if (dom->parms.pae == 2 /* extended_cr3 */ || ++ dom->parms.pae == 3 /* bimodal */) ++ ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); ++ ++ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ++ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn); ++ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); ++ ++ return 0; ++} ++ ++static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_x86_64_t *ctxt = ptr; ++ xen_pfn_t cr3_pfn; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ /* Virtual IDT is empty at start-of-day. */ ++ for (i = 0; i < 256; i++) ++ { ++ ctxt->trap_ctxt[i].vector = i; ++ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_64; ++ } ++ ++ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_64; ++ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_64; ++ ctxt->user_regs.rip = dom->parms.virt_entry; ++ ctxt->user_regs.rsp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ctxt->user_regs.rsi = ++ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ++ ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */ ++ ++ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_64; ++ ctxt->kernel_sp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ++ ctxt->flags = VGCF_in_kernel_X86_64; ++ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ++ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn); ++ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_32 = { ++ .guest_type = "xen-3.0-x86_32", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 4, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_32, ++ .setup_pgtables = setup_pgtables_x86_32, ++ .start_info = start_info_x86_32, ++ .shared_info = shared_info_x86_32, ++ .vcpu = vcpu_x86_32, ++}; ++static struct xc_dom_arch xc_dom_32_pae = { ++ .guest_type = "xen-3.0-x86_32p", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 4, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_32_pae, ++ .setup_pgtables = setup_pgtables_x86_32_pae, ++ .start_info = start_info_x86_32, ++ .shared_info = shared_info_x86_32, ++ .vcpu = vcpu_x86_32, ++}; ++ ++static struct xc_dom_arch xc_dom_64 = { ++ .guest_type = "xen-3.0-x86_64", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 8, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_64, ++ .setup_pgtables = setup_pgtables_x86_64, ++ .start_info = start_info_x86_64, ++ .shared_info = shared_info_x86_64, ++ .vcpu = vcpu_x86_64, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_32); ++ xc_dom_register_arch_hooks(&xc_dom_32_pae); ++ xc_dom_register_arch_hooks(&xc_dom_64); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c +@@ -0,0 +1,100 @@ ++/* ++ * Xen domain builder -- ia64 bits. ++ * ++ * Most architecture-specific code for ia64 goes here. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ /* allocate special pages */ ++ dom->low_top--; /* shared_info */ ++ dom->xenstore_pfn = --dom->low_top; ++ dom->console_pfn = --dom->low_top; ++ dom->start_info_pfn = --dom->low_top; ++ return 0; ++} ++ ++static int start_info(struct xc_dom_image *dom) ++{ ++ start_info_t *si = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ ++ xc_dom_printf("%s\n", __FUNCTION__); ++ ++ snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); ++ ++ si->nr_pages = dom->total_pages; ++ si->shared_info = (dom->total_pages - 1) << PAGE_SHIFT; ++ si->store_mfn = dom->xenstore_pfn; ++ si->store_evtchn = dom->store_evtchn; ++ si->console.domU.mfn = dom->console_pfn; ++ si->console.domU.evtchn = dom->console_evtchn; ++ return 0; ++} ++ ++static int shared_info(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ return 0; ++} ++ ++static int vcpu(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_t *ctxt = ptr; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ memset(&ctxt->user_regs, 0x55, sizeof(ctxt.user_regs)); ++ ctxt->user_regs.pc = dsi->v_kernentry; ++ ctxt->user_regs.msr = 0; ++ ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */ ++ ctxt->user_regs.gprs[3] = devtree_addr; ++ ctxt->user_regs.gprs[4] = kern_addr; ++ ctxt->user_regs.gprs[5] = 0; ++ ++ /* There is a buggy kernel that does not zero the "local_paca", so ++ * we must make sure this register is 0 */ ++ ctxt->user_regs.gprs[13] = 0; ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_arch = { ++ .guest_type = "xen-3.0-powerpc64", ++ .page_shift = FIXME, ++ .alloc_magic_pages = alloc_magic_pages, ++ .start_info = start_info, ++ .shared_info = shared_info, ++ .vcpu = vcpu, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_arch); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_elfloader.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_elfloader.c +@@ -0,0 +1,283 @@ ++/* ++ * Xen domain builder -- ELF bits. ++ * ++ * Parse and load ELF kernel images. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++#define XEN_VER "xen-3.0" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static char *xc_dom_guest_type(struct xc_dom_image *dom, ++ struct elf_binary *elf) ++{ ++ uint64_t machine = elf_uval(elf, elf->ehdr, e_machine); ++ ++ switch (machine) { ++ case EM_386: ++ switch (dom->parms.pae) { ++ case 3 /* PAEKERN_bimodal */: ++ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) ++ return "xen-3.0-x86_32p"; ++ return "xen-3.0-x86_32"; ++ case PAEKERN_extended_cr3: ++ case PAEKERN_yes: ++ return "xen-3.0-x86_32p"; ++ break; ++ case PAEKERN_no: ++ default: ++ return "xen-3.0-x86_32"; ++ } ++ case EM_X86_64: ++ return "xen-3.0-x86_64"; ++ case EM_IA_64: ++ return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64"; ++ case EM_PPC64: ++ return "xen-3.0-powerpc64"; ++ default: ++ return "xen-3.0-unknown"; ++ } ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* parse elf binary */ ++ ++static int check_elf_kernel(struct xc_dom_image *dom, int verbose) ++{ ++ if (NULL == dom->kernel_blob) ++ { ++ if (verbose) ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ if (!elf_is_elfbinary(dom->kernel_blob)) ++ { ++ if (verbose) ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not an ELF image\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom) ++{ ++ return check_elf_kernel(dom, 0); ++} ++ ++static int xc_dom_load_elf_symtab(struct xc_dom_image *dom, ++ struct elf_binary *elf, int load) ++{ ++ struct elf_binary syms; ++ const elf_shdr *shdr, *shdr2; ++ xen_vaddr_t symtab, maxaddr; ++ char *hdr; ++ size_t size; ++ int h, count, type, i, tables = 0; ++ ++ if (elf_swap(elf)) { ++ xc_dom_printf("%s: non-native byte order, bsd symtab not supported\n", ++ __FUNCTION__); ++ return 0; ++ } ++ ++ if (load) { ++ if (!dom->bsd_symtab_start) ++ return 0; ++ size = dom->kernel_seg.vend - dom->bsd_symtab_start; ++ hdr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start); ++ *(int *)hdr = size - sizeof(int); ++ } else { ++ size = sizeof(int) + elf_size(elf, elf->ehdr) + ++ elf_shdr_count(elf) * elf_size(elf, shdr); ++ hdr = xc_dom_malloc(dom, size); ++ if (hdr == NULL) ++ return 0; ++ dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend); ++ } ++ ++ memcpy(hdr + sizeof(int), ++ elf->image, ++ elf_size(elf, elf->ehdr)); ++ memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr), ++ elf->image + elf_uval(elf, elf->ehdr, e_shoff), ++ elf_shdr_count(elf) * elf_size(elf, shdr)); ++ if (elf_64bit(elf)) { ++ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int)); ++ ehdr->e_phoff = 0; ++ ehdr->e_phentsize = 0; ++ ehdr->e_phnum = 0; ++ ehdr->e_shoff = elf_size(elf, elf->ehdr); ++ ehdr->e_shstrndx = SHN_UNDEF; ++ } else { ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int)); ++ ehdr->e_phoff = 0; ++ ehdr->e_phentsize = 0; ++ ehdr->e_phnum = 0; ++ ehdr->e_shoff = elf_size(elf, elf->ehdr); ++ ehdr->e_shstrndx = SHN_UNDEF; ++ } ++ if (0 != elf_init(&syms, hdr + sizeof(int), size - sizeof(int))) ++ return -1; ++ if (xc_dom_logfile) ++ elf_set_logfile(&syms, xc_dom_logfile, 1); ++ ++ symtab = dom->bsd_symtab_start + sizeof(int); ++ maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) + ++ elf_shdr_count(&syms) * elf_size(&syms, shdr)); ++ ++ xc_dom_printf("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64 ++ " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "\n", ++ __FUNCTION__, load ? "load" : "parse", ++ dom->bsd_symtab_start, dom->kernel_seg.vend, symtab, maxaddr); ++ ++ count = elf_shdr_count(&syms); ++ for (h = 0; h < count; h++) ++ { ++ shdr = elf_shdr_by_index(&syms, h); ++ type = elf_uval(&syms, shdr, sh_type); ++ if (type == SHT_STRTAB) ++ { ++ /* Look for a strtab @i linked to symtab @h. */ ++ for (i = 0; i < count; i++) { ++ shdr2 = elf_shdr_by_index(&syms, i); ++ if ((elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) && ++ (elf_uval(&syms, shdr2, sh_link) == h)) ++ break; ++ } ++ /* Skip symtab @h if we found no corresponding strtab @i. */ ++ if (i == count) ++ { ++ if (elf_64bit(&syms)) ++ *(Elf64_Off*)(&shdr->e64.sh_offset) = 0; ++ else ++ *(Elf32_Off*)(&shdr->e32.sh_offset) = 0; ++ continue; ++ } ++ } ++ ++ if ((type == SHT_STRTAB) || (type == SHT_SYMTAB)) ++ { ++ /* Mangled to be based on ELF header location. */ ++ if (elf_64bit(&syms)) ++ *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab; ++ else ++ *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab; ++ size = elf_uval(&syms, shdr, sh_size); ++ maxaddr = elf_round_up(&syms, maxaddr + size); ++ tables++; ++ xc_dom_printf("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "\n", ++ __FUNCTION__, h, ++ type == SHT_SYMTAB ? "symtab" : "strtab", ++ size, maxaddr); ++ ++ if (load) { ++ shdr2 = elf_shdr_by_index(elf, h); ++ memcpy((void*)elf_section_start(&syms, shdr), ++ elf_section_start(elf, shdr2), ++ size); ++ } ++ } ++ ++ /* Name is NULL. */ ++ if (elf_64bit(&syms)) ++ *(Elf64_Half*)(&shdr->e64.sh_name) = 0; ++ else ++ *(Elf32_Word*)(&shdr->e32.sh_name) = 0; ++ } ++ ++ if (0 == tables) ++ { ++ xc_dom_printf("%s: no symbol table present\n", __FUNCTION__); ++ dom->bsd_symtab_start = 0; ++ return 0; ++ } ++ if (!load) ++ dom->kernel_seg.vend = maxaddr; ++ return 0; ++} ++ ++static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom) ++{ ++ struct elf_binary *elf; ++ int rc; ++ ++ rc = check_elf_kernel(dom, 1); ++ if (0 != rc) ++ return rc; ++ ++ elf = xc_dom_malloc(dom, sizeof(*elf)); ++ dom->private_loader = elf; ++ rc = elf_init(elf, dom->kernel_blob, dom->kernel_size); ++ if (xc_dom_logfile) ++ elf_set_logfile(elf, xc_dom_logfile, 1); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n", ++ __FUNCTION__); ++ return rc; ++ } ++ ++ /* Find the section-header strings table. */ ++ if (NULL == elf->sec_strtab) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: ELF image has no shstrtab\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ /* parse binary and get xen meta info */ ++ elf_parse_binary(elf); ++ if (0 != (rc = elf_xen_parse(elf, &dom->parms))) ++ return rc; ++ ++ /* find kernel segment */ ++ dom->kernel_seg.vstart = dom->parms.virt_kstart; ++ dom->kernel_seg.vend = dom->parms.virt_kend; ++ ++ if (dom->parms.bsd_symtab) ++ xc_dom_load_elf_symtab(dom, elf, 0); ++ ++ dom->guest_type = xc_dom_guest_type(dom, elf); ++ xc_dom_printf("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->guest_type, ++ dom->kernel_seg.vstart, dom->kernel_seg.vend); ++ return 0; ++} ++ ++static int xc_dom_load_elf_kernel(struct xc_dom_image *dom) ++{ ++ struct elf_binary *elf = dom->private_loader; ++ ++ elf->dest = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); ++ elf_load_binary(elf); ++ if (dom->parms.bsd_symtab) ++ xc_dom_load_elf_symtab(dom, elf, 1); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_loader elf_loader = { ++ .name = "ELF-generic", ++ .probe = xc_dom_probe_elf_kernel, ++ .parser = xc_dom_parse_elf_kernel, ++ .loader = xc_dom_load_elf_kernel, ++}; ++ ++static void __init register_loader(void) ++{ ++ xc_dom_register_loader(&elf_loader); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_binloader.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_binloader.c +@@ -0,0 +1,294 @@ ++/****************************************************************************** ++ * ++ * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are ++ * present. The only requirement is that it must have a xen_bin_image table ++ * somewhere in the first 8192 bytes, starting on a 32-bit aligned address. ++ * Those familiar with the multiboot specification should recognize this, it's ++ * (almost) the same as the multiboot header. ++ * The layout of the xen_bin_image table is: ++ * ++ * Offset Type Name Note ++ * 0 uint32_t magic required ++ * 4 uint32_t flags required ++ * 8 uint32_t checksum required ++ * 12 uint32_t header_addr required ++ * 16 uint32_t load_addr required ++ * 20 uint32_t load_end_addr required ++ * 24 uint32_t bss_end_addr required ++ * 28 uint32_t entry_addr required ++ * ++ * - magic ++ * Magic number identifying the table. For images to be loaded by Xen 3, the ++ * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set). ++ * - flags ++ * bit 0: indicates whether the image needs to be loaded on a page boundary ++ * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate ++ * that memory info should be passed to the image) ++ * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate ++ * that the bootloader should pass video mode info to the image) ++ * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate ++ * that the values in the fields header_addr - entry_addr are ++ * valid) ++ * All other bits should be set to 0. ++ * - checksum ++ * When added to "magic" and "flags", the resulting value should be 0. ++ * - header_addr ++ * Contains the virtual address corresponding to the beginning of the ++ * table - the memory location at which the magic value is supposed to be ++ * loaded. This field serves to synchronize the mapping between OS image ++ * offsets and virtual memory addresses. ++ * - load_addr ++ * Contains the virtual address of the beginning of the text segment. The ++ * offset in the OS image file at which to start loading is defined by the ++ * offset at which the table was found, minus (header addr - load addr). ++ * load addr must be less than or equal to header addr. ++ * - load_end_addr ++ * Contains the virtual address of the end of the data segment. ++ * (load_end_addr - load_addr) specifies how much data to load. This implies ++ * that the text and data segments must be consecutive in the OS image. If ++ * this field is zero, the domain builder assumes that the text and data ++ * segments occupy the whole OS image file. ++ * - bss_end_addr ++ * Contains the virtual address of the end of the bss segment. The domain ++ * builder initializes this area to zero, and reserves the memory it occupies ++ * to avoid placing boot modules and other data relevant to the loaded image ++ * in that area. If this field is zero, the domain builder assumes that no bss ++ * segment is present. ++ * - entry_addr ++ * The virtual address at which to start execution of the loaded image. ++ * ++ * Some of the field descriptions were copied from "The Multiboot ++ * Specification", Copyright 1995, 96 Bryan Ford , ++ * Erich Stefan Boleyn Copyright 1999, 2000, 2001, 2002 ++ * Free Software Foundation, Inc. ++ */ ++ ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++#define round_pgup(_p) (((_p)+(PAGE_SIZE_X86-1))&PAGE_MASK_X86) ++#define round_pgdown(_p) ((_p)&PAGE_MASK_X86) ++ ++struct xen_bin_image_table ++{ ++ uint32_t magic; ++ uint32_t flags; ++ uint32_t checksum; ++ uint32_t header_addr; ++ uint32_t load_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t entry_addr; ++}; ++ ++#define XEN_MULTIBOOT_MAGIC3 0x336ec578 ++ ++#define XEN_MULTIBOOT_FLAG_ALIGN4K 0x00000001 ++#define XEN_MULTIBOOT_FLAG_NEEDMEMINFO 0x00000002 ++#define XEN_MULTIBOOT_FLAG_NEEDVIDINFO 0x00000004 ++#define XEN_MULTIBOOT_FLAG_ADDRSVALID 0x00010000 ++#define XEN_MULTIBOOT_FLAG_PAE_SHIFT 14 ++#define XEN_MULTIBOOT_FLAG_PAE_MASK (3 << XEN_MULTIBOOT_FLAG_PAE_SHIFT) ++ ++/* Flags we test for */ ++#define FLAGS_MASK ((~ 0) & (~ XEN_MULTIBOOT_FLAG_ALIGN4K) & \ ++ (~ XEN_MULTIBOOT_FLAG_PAE_MASK)) ++#define FLAGS_REQUIRED XEN_MULTIBOOT_FLAG_ADDRSVALID ++ ++/* --------------------------------------------------------------------- */ ++ ++static struct xen_bin_image_table *find_table(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *table; ++ uint32_t *probe_ptr; ++ uint32_t *probe_end; ++ ++ probe_ptr = dom->kernel_blob; ++ probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table); ++ if ((void*)probe_end > dom->kernel_blob + 8192) ++ probe_end = dom->kernel_blob + 8192; ++ ++ for (table = NULL; probe_ptr < probe_end; probe_ptr++) ++ { ++ if (XEN_MULTIBOOT_MAGIC3 == *probe_ptr) ++ { ++ table = (struct xen_bin_image_table *) probe_ptr; ++ /* Checksum correct? */ ++ if (0 == table->magic + table->flags + table->checksum) ++ { ++ return table; ++ } ++ } ++ } ++ return NULL; ++} ++ ++static int xc_dom_probe_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *table; ++ ++ table = find_table(dom); ++ if (!table) ++ return -EINVAL; ++ return 0; ++} ++ ++static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *image_info; ++ char *image = dom->kernel_blob; ++ size_t image_size = dom->kernel_size; ++ uint32_t start_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t pae_flags; ++ ++ image_info = find_table(dom); ++ if (!image_info) ++ return -EINVAL; ++ ++ xc_dom_printf("%s: multiboot header fields\n", __FUNCTION__); ++ xc_dom_printf(" flags: 0x%" PRIx32 "\n", image_info->flags); ++ xc_dom_printf(" header_addr: 0x%" PRIx32 "\n", image_info->header_addr); ++ xc_dom_printf(" load_addr: 0x%" PRIx32 "\n", image_info->load_addr); ++ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", image_info->load_end_addr); ++ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", image_info->bss_end_addr); ++ xc_dom_printf(" entry_addr: 0x%" PRIx32 "\n", image_info->entry_addr); ++ ++ /* Check the flags */ ++ if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: xen_bin_image_table flags required " ++ "0x%08" PRIx32 " found 0x%08" PRIx32 "\n", ++ __FUNCTION__, FLAGS_REQUIRED, image_info->flags & FLAGS_MASK); ++ return -EINVAL; ++ } ++ ++ /* Sanity check on the addresses */ ++ if ( image_info->header_addr < image_info->load_addr || ++ ((char *) image_info - image) < ++ (image_info->header_addr - image_info->load_addr) ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid header_addr.", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ start_addr = image_info->header_addr - ((char *)image_info - image); ++ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; ++ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; ++ ++ xc_dom_printf("%s: calculated addresses\n", __FUNCTION__); ++ xc_dom_printf(" start_addr: 0x%" PRIx32 "\n", start_addr); ++ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", load_end_addr); ++ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", bss_end_addr); ++ ++ if ( start_addr + image_size < load_end_addr ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid load_end_addr.\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ if ( bss_end_addr < load_end_addr) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ dom->kernel_seg.vstart = image_info->load_addr; ++ dom->kernel_seg.vend = bss_end_addr; ++ dom->parms.virt_base = start_addr; ++ dom->parms.virt_entry = image_info->entry_addr; ++ ++ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; ++ switch (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) { ++ case 0: ++ dom->guest_type = "xen-3.0-x86_32"; ++ break; ++ case 1: ++ dom->guest_type = "xen-3.0-x86_32p"; ++ break; ++ case 2: ++ dom->guest_type = "xen-3.0-x86_64"; ++ break; ++ case 3: ++ /* Kernel detects PAE at runtime. So try to figure whenever ++ * xen supports PAE and advertise a PAE-capable kernel in case ++ * it does. */ ++ dom->guest_type = "xen-3.0-x86_32"; ++ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) { ++ xc_dom_printf("%s: PAE fixup\n", __FUNCTION__); ++ dom->guest_type = "xen-3.0-x86_32p"; ++ dom->parms.pae = 2; ++ } ++ break; ++ } ++ return 0; ++} ++ ++static int xc_dom_load_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *image_info; ++ char *image = dom->kernel_blob; ++ char *dest; ++ size_t image_size = dom->kernel_size; ++ uint32_t start_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t skip, text_size, bss_size; ++ uint32_t pae_flags; ++ ++ image_info = find_table(dom); ++ if (!image_info) ++ return -EINVAL; ++ ++ start_addr = image_info->header_addr - ((char *)image_info - image); ++ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; ++ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; ++ ++ /* It's possible that we need to skip the first part of the image */ ++ skip = image_info->load_addr - start_addr; ++ text_size = load_end_addr - image_info->load_addr; ++ bss_size = bss_end_addr - load_end_addr; ++ ++ xc_dom_printf("%s: calculated sizes\n", __FUNCTION__); ++ xc_dom_printf(" skip: 0x%" PRIx32 "\n", skip); ++ xc_dom_printf(" text_size: 0x%" PRIx32 "\n", text_size); ++ xc_dom_printf(" bss_size: 0x%" PRIx32 "\n", bss_size); ++ ++ dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart); ++ memcpy(dest, image + skip, text_size); ++ memset(dest + text_size, 0, bss_size); ++ ++ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; ++ if (3 == (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) && dom->guest_xc > 0) ++ { ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_loader bin_loader = { ++ .name = "multiboot-binary", ++ .probe = xc_dom_probe_bin_kernel, ++ .parser = xc_dom_parse_bin_kernel, ++ .loader = xc_dom_load_bin_kernel, ++}; ++ ++static void __init register_loader(void) ++{ ++ xc_dom_register_loader(&bin_loader); ++} ++ ++/* ++ * Local variables: ++ * c-basic-offset: 4 ++ * End: ++ */ diff --git a/tools-readnotes-gunzip.diff b/tools-readnotes-gunzip.diff index 4d1a5a6..0912ede 100644 --- a/tools-readnotes-gunzip.diff +++ b/tools-readnotes-gunzip.diff @@ -1,46 +1,46 @@ -Support transparant gunzipping in the readnotes utility. - -Signed-off-by: Gerd Hoffmann ---- - tools/xcutils/readnotes.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -Index: build-32-release304-13138/tools/xcutils/readnotes.c -=================================================================== ---- build-32-release304-13138.orig/tools/xcutils/readnotes.c -+++ build-32-release304-13138/tools/xcutils/readnotes.c -@@ -11,6 +11,7 @@ - #include - - #include -+#include /* gunzip bits */ - - #include - -@@ -33,8 +34,8 @@ static void print_numeric_note(const cha - int main(int argc, char **argv) - { - const char *f; -- int fd,h,size,count; -- void *image; -+ int fd,h,size,usize,count; -+ void *image,*tmp; - struct stat st; - struct elf_binary elf; - const elf_shdr *shdr; -@@ -68,6 +69,15 @@ int main(int argc, char **argv) - } - size = st.st_size; - -+ usize = xc_dom_check_gzip(image, st.st_size); -+ if (usize) -+ { -+ tmp = malloc(usize); -+ xc_dom_do_gunzip(image, st.st_size, tmp, usize); -+ image = tmp; -+ size = usize; -+ } -+ - if (0 != elf_init(&elf, image, size)) - { - fprintf(stderr, "File %s is not an ELF image\n", f); +Support transparant gunzipping in the readnotes utility. + +Signed-off-by: Gerd Hoffmann +--- + tools/xcutils/readnotes.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +Index: build-32-release304-13138/tools/xcutils/readnotes.c +=================================================================== +--- build-32-release304-13138.orig/tools/xcutils/readnotes.c ++++ build-32-release304-13138/tools/xcutils/readnotes.c +@@ -11,6 +11,7 @@ + #include + + #include ++#include /* gunzip bits */ + + #include + +@@ -33,8 +34,8 @@ static void print_numeric_note(const cha + int main(int argc, char **argv) + { + const char *f; +- int fd,h,size,count; +- void *image; ++ int fd,h,size,usize,count; ++ void *image,*tmp; + struct stat st; + struct elf_binary elf; + const elf_shdr *shdr; +@@ -68,6 +69,15 @@ int main(int argc, char **argv) + } + size = st.st_size; + ++ usize = xc_dom_check_gzip(image, st.st_size); ++ if (usize) ++ { ++ tmp = malloc(usize); ++ xc_dom_do_gunzip(image, st.st_size, tmp, usize); ++ image = tmp; ++ size = usize; ++ } ++ + if (0 != elf_init(&elf, image, size)) + { + fprintf(stderr, "File %s is not an ELF image\n", f); diff --git a/x86-nmi-inject.patch b/x86-nmi-inject.patch new file mode 100644 index 0000000..1f5f3b4 --- /dev/null +++ b/x86-nmi-inject.patch @@ -0,0 +1,359 @@ +Index: 2007-01-31/xen/arch/x86/physdev.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/physdev.c 2007-01-31 09:29:19.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/physdev.c 2007-02-14 18:22:18.000000000 +0100 +@@ -143,6 +143,57 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H + break; + } + ++ case PHYSDEVOP_send_nmi: { ++ struct physdev_send_nmi send_nmi; ++ struct domain *d; ++ ++ ret = -EFAULT; ++ if ( copy_from_guest(&send_nmi, arg, 1) != 0 ) ++ break; ++ ++ ret = -EPERM; ++ if ( send_nmi.domain == DOMID_SELF ) ++ d = current->domain; ++ else if ( !IS_PRIV(current->domain) ) ++ break; ++ else ++ d = find_domain_by_id(send_nmi.domain); ++ ret = -ESRCH; ++ if ( !d ) ++ break; ++ ++ switch ( send_nmi.vcpu ) ++ { ++ struct vcpu *v; ++ ++ case XEN_SEND_NMI_ALL: ++ case XEN_SEND_NMI_ALL_BUT_SELF: ++ for_each_vcpu(d, v) ++ { ++ if ( (send_nmi.vcpu == XEN_SEND_NMI_ALL || v != current) && ++ !test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) ) ++ vcpu_kick(v); ++ } ++ ret = 0; ++ break; ++ case 0 ... MAX_VIRT_CPUS - 1: ++ if ( (v = d->vcpu[send_nmi.vcpu]) != NULL ) ++ { ++ if ( !test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) ) ++ vcpu_kick(v); ++ ret = 0; ++ } ++ break; ++ default: ++ ret = EINVAL; ++ break; ++ } ++ ++ if ( send_nmi.domain != DOMID_SELF ) ++ put_domain(d); ++ break; ++ } ++ + default: + ret = -ENOSYS; + break; +Index: 2007-01-31/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-02-07 17:03:20.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/traps.c 2007-02-15 10:12:21.000000000 +0100 +@@ -2516,6 +2516,12 @@ long do_set_trap_table(XEN_GUEST_HANDLE( + if ( cur.address == 0 ) + break; + ++ if ( cur.vector == 2 && !TI_GET_IF(&cur) ) ++ { ++ rc = -EINVAL; ++ break; ++ } ++ + fixup_guest_code_selector(current->domain, cur.cs); + + memcpy(&dst[cur.vector], &cur, sizeof(cur)); +Index: 2007-01-31/xen/arch/x86/x86_32/asm-offsets.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_32/asm-offsets.c 2006-12-13 11:15:54.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_32/asm-offsets.c 2007-02-15 09:51:44.000000000 +0100 +@@ -68,6 +68,7 @@ void __dummy__(void) + OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); + OFFSET(VCPU_flags, struct vcpu, vcpu_flags); + OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr); ++ OFFSET(VCPU_nmi_cs, struct vcpu, arch.guest_context.trap_ctxt[2].cs); + DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending); + DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked); + DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events); +Index: 2007-01-31/xen/arch/x86/x86_32/entry.S +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_32/entry.S 2007-01-31 09:42:04.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_32/entry.S 2007-02-15 09:54:40.000000000 +0100 +@@ -232,7 +232,7 @@ test_all_events: + shl $IRQSTAT_shift,%eax + test %ecx,irq_stat(%eax,1) + jnz process_softirqs +- btr $_VCPUF_nmi_pending,VCPU_flags(%ebx) ++ lock btrl $_VCPUF_nmi_pending,VCPU_flags(%ebx) + jc process_nmi + test_guest_events: + movl VCPU_vcpu_info(%ebx),%eax +@@ -259,19 +259,20 @@ process_softirqs: + + ALIGN + process_nmi: +- movl VCPU_nmi_addr(%ebx),%eax ++ movzwl VCPU_nmi_cs(%ebx),%eax ++ movl VCPU_nmi_addr(%ebx),%ecx + test %eax,%eax + jz test_all_events +- bts $_VCPUF_nmi_masked,VCPU_flags(%ebx) ++ lock btsl $_VCPUF_nmi_masked,VCPU_flags(%ebx) + jc 1f + sti + leal VCPU_trap_bounce(%ebx),%edx +- movl %eax,TRAPBOUNCE_eip(%edx) +- movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx) ++ movl %ecx,TRAPBOUNCE_eip(%edx) ++ movw %ax,TRAPBOUNCE_cs(%edx) + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) + call create_bounce_frame + jmp test_all_events +-1: bts $_VCPUF_nmi_pending,VCPU_flags(%ebx) ++1: lock btsl $_VCPUF_nmi_pending,VCPU_flags(%ebx) + jmp test_guest_events + + bad_hypercall: +Index: 2007-01-31/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-01-31 09:29:21.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/asm-offsets.c 2007-02-15 10:03:33.000000000 +0100 +@@ -76,6 +76,7 @@ void __dummy__(void) + OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); + OFFSET(VCPU_flags, struct vcpu, vcpu_flags); + OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr); ++ OFFSET(VCPU_nmi_cs, struct vcpu, arch.guest_context.trap_ctxt[2].cs); + DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending); + DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked); + DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events); +Index: 2007-01-31/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-31 09:42:04.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/compat/entry.S 2007-02-15 10:22:57.000000000 +0100 +@@ -68,7 +68,7 @@ compat_test_all_events: + leaq irq_stat(%rip),%rcx + testl $~0,(%rcx,%rax,1) + jnz compat_process_softirqs +- btrq $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++ lock btrl $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jc compat_process_nmi + compat_test_guest_events: + movq VCPU_vcpu_info(%rbx),%rax +@@ -82,7 +82,7 @@ compat_test_guest_events: + movl VCPU_event_addr(%rbx),%eax + movl %eax,TRAPBOUNCE_eip(%rdx) + movl VCPU_event_sel(%rbx),%eax +- movl %eax,TRAPBOUNCE_cs(%rdx) ++ movw %ax,TRAPBOUNCE_cs(%rdx) + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + call compat_create_bounce_frame + jmp compat_test_all_events +@@ -97,20 +97,21 @@ compat_process_softirqs: + ALIGN + /* %rbx: struct vcpu */ + compat_process_nmi: +- movl VCPU_nmi_addr(%rbx),%eax ++ movzwl VCPU_nmi_cs(%rbx),%eax ++ movl VCPU_nmi_addr(%rbx),%ecx + testl %eax,%eax + jz compat_test_all_events +- btsq $_VCPUF_nmi_masked,VCPU_flags(%rbx) ++ lock btsl $_VCPUF_nmi_masked,VCPU_flags(%rbx) + jc 1f + sti + leaq VCPU_trap_bounce(%rbx),%rdx +- movl %eax,TRAPBOUNCE_eip(%rdx) +- movl $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) ++ movl %ecx,TRAPBOUNCE_eip(%rdx) ++ movw %ax,TRAPBOUNCE_cs(%rdx) + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + call compat_create_bounce_frame + jmp compat_test_all_events + 1: +- btsq $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++ lock btsl $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jmp compat_test_guest_events + + compat_bad_hypercall: +@@ -145,7 +146,7 @@ compat_failsafe_callback: + movl VCPU_failsafe_addr(%rbx),%eax + movl %eax,TRAPBOUNCE_eip(%rdx) + movl VCPU_failsafe_sel(%rbx),%eax +- movl %eax,TRAPBOUNCE_cs(%rdx) ++ movw %ax,TRAPBOUNCE_cs(%rdx) + movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) + btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) + jnc 1f +Index: 2007-01-31/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-31 09:29:26.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/compat/traps.c 2007-02-15 10:10:46.000000000 +0100 +@@ -287,6 +287,12 @@ int compat_set_trap_table(XEN_GUEST_HAND + if ( cur.address == 0 ) + break; + ++ if ( cur.vector == 2 && !TI_GET_IF(&cur) ) ++ { ++ rc = -EINVAL; ++ break; ++ } ++ + fixup_guest_code_selector(current->domain, cur.cs); + + XLAT_trap_info(dst + cur.vector, &cur); +Index: 2007-01-31/xen/arch/x86/x86_64/entry.S +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/entry.S 2007-01-31 09:42:04.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/entry.S 2007-02-14 17:15:25.000000000 +0100 +@@ -177,7 +177,7 @@ test_all_events: + leaq irq_stat(%rip),%rcx + testl $~0,(%rcx,%rax,1) + jnz process_softirqs +- btr $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++ lock btrl $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jc process_nmi + test_guest_events: + movq VCPU_vcpu_info(%rbx),%rax +@@ -207,7 +207,7 @@ process_nmi: + movq VCPU_nmi_addr(%rbx),%rax + test %rax,%rax + jz test_all_events +- bts $_VCPUF_nmi_masked,VCPU_flags(%rbx) ++ lock btsl $_VCPUF_nmi_masked,VCPU_flags(%rbx) + jc 1f + sti + leaq VCPU_trap_bounce(%rbx),%rdx +@@ -215,7 +215,7 @@ process_nmi: + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + call create_bounce_frame + jmp test_all_events +-1: bts $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++1: lock btsl $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jmp test_guest_events + + bad_hypercall: +Index: 2007-01-31/xen/arch/x86/x86_64/physdev.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/physdev.c 2007-01-31 09:29:19.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/physdev.c 2007-02-14 18:26:33.000000000 +0100 +@@ -30,6 +30,10 @@ + #define physdev_irq_status_query compat_physdev_irq_status_query + #define physdev_irq_status_query_t physdev_irq_status_query_compat_t + ++#define xen_physdev_send_nmi physdev_send_nmi ++CHECK_physdev_send_nmi; ++#undef xen_physdev_send_nmi ++ + #define COMPAT + #undef guest_handle_okay + #define guest_handle_okay compat_handle_okay +Index: 2007-01-31/xen/common/kernel.c +=================================================================== +--- 2007-01-31.orig/xen/common/kernel.c 2007-01-31 09:44:25.000000000 +0100 ++++ 2007-01-31/xen/common/kernel.c 2007-02-15 10:18:48.000000000 +0100 +@@ -252,16 +252,20 @@ long register_guest_nmi_callback(unsigne + struct vcpu *v = current; + struct domain *d = current->domain; + +- if ( (d->domain_id != 0) || (v->vcpu_id != 0) ) +- return -EINVAL; +- + v->nmi_addr = address; + #ifdef CONFIG_X86 ++ v->arch.guest_context.trap_ctxt[2].vector = 2; ++ v->arch.guest_context.trap_ctxt[2].flags = 0; ++ TI_SET_IF(v->arch.guest_context.trap_ctxt + 2, 1); ++ v->arch.guest_context.trap_ctxt[2].cs = ++ !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; ++ + /* + * If no handler was registered we can 'lose the NMI edge'. Re-assert it + * now. + */ +- if ( arch_get_nmi_reason(d) != 0 ) ++ if ( d->domain_id == 0 && v->vcpu_id == 0 && ++ arch_get_nmi_reason(d) != 0 ) + set_bit(_VCPUF_nmi_pending, &v->vcpu_flags); + #endif + +@@ -272,6 +276,11 @@ long unregister_guest_nmi_callback(void) + { + struct vcpu *v = current; + ++#ifdef CONFIG_X86 ++ v->arch.guest_context.trap_ctxt[2].cs = 0; ++ v->arch.guest_context.trap_ctxt[2].vector = 0; ++ v->arch.guest_context.trap_ctxt[2].flags = 0; ++#endif + v->nmi_addr = 0; + + return 0; +Index: 2007-01-31/xen/include/public/physdev.h +=================================================================== +--- 2007-01-31.orig/xen/include/public/physdev.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2007-01-31/xen/include/public/physdev.h 2007-02-14 18:21:35.000000000 +0100 +@@ -119,6 +119,22 @@ typedef struct physdev_irq physdev_irq_t + DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); + + /* ++ * Allocate or free a physical upcall vector for the specified IRQ line. ++ * @arg == pointer to physdev_irq structure. ++ */ ++#define PHYSDEVOP_send_nmi 13 ++struct physdev_send_nmi { ++ /* IN */ ++ domid_t domain; ++ uint32_t vcpu; ++}; ++typedef struct physdev_send_nmi physdev_send_nmi_t; ++DEFINE_XEN_GUEST_HANDLE(physdev_send_nmi_t); ++ ++#define XEN_SEND_NMI_ALL (~(uint32_t)0) ++#define XEN_SEND_NMI_ALL_BUT_SELF (~(uint32_t)1) ++ ++/* + * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() + * hypercall since 0x00030202. + */ +Index: 2007-01-31/xen/include/xen/sched.h +=================================================================== +--- 2007-01-31.orig/xen/include/xen/sched.h 2007-01-31 09:39:18.000000000 +0100 ++++ 2007-01-31/xen/include/xen/sched.h 2007-02-15 09:38:57.000000000 +0100 +@@ -108,7 +108,11 @@ struct vcpu + /* Bitmask of CPUs on which this VCPU may run. */ + cpumask_t cpu_affinity; + ++#ifndef CONFIG_X86 + unsigned long nmi_addr; /* NMI callback address. */ ++#else ++# define nmi_addr arch.guest_context.trap_ctxt[2].address ++#endif + + /* Bitmask of CPUs which are holding onto this VCPU's state. */ + cpumask_t vcpu_dirty_cpumask; +Index: 2007-01-31/xen/include/xlat.lst +=================================================================== +--- 2007-01-31.orig/xen/include/xlat.lst 2007-01-31 09:29:27.000000000 +0100 ++++ 2007-01-31/xen/include/xlat.lst 2007-02-14 17:58:42.000000000 +0100 +@@ -40,6 +40,7 @@ + ! memory_map memory.h + ! memory_reservation memory.h + ! translate_gpfn_list memory.h ++? physdev_send_nmi physdev.h + ! sched_poll sched.h + ? sched_remote_shutdown sched.h + ? sched_shutdown sched.h diff --git a/xen-vm-install.tar.bz2 b/xen-vm-install.tar.bz2 index 241bd71..f2764b6 100644 --- a/xen-vm-install.tar.bz2 +++ b/xen-vm-install.tar.bz2 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e21bb469ef2d4b66eb11a50b923a0ba23140a1b88ccd73041f408580f81819d1 -size 59577 +oid sha256:134bf952b2af34e4463047117344f82cfada3a791e61443c71b36f2be49ac4d9 +size 124324 diff --git a/xen.changes b/xen.changes index 2236911..bdb9d1c 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,54 @@ +------------------------------------------------------------------- +Fri Feb 16 18:07:09 MST 2007 - jfehlig@novell.com + +- Added changeset 13775 from xen-unstable. This patch fixes + the last known issue with the Xen API patchset backported + from xen-unstable. + +------------------------------------------------------------------- +Fri Feb 16 11:31:15 MST 2007 - jfehlig@novell.com + +- Added c/s 13226 from xen-unstable. It affects Xen API only. +- Added patch to remove ':disk' and 'tap:qcow' from stored domain + config. Fixes bug #237414 and helps with bug #242953. + +------------------------------------------------------------------- +Thu Feb 15 19:03:13 MST 2007 - jfehlig@novell.com + +- Backported Xen API functionality from xen-unstable to support + hosting CIM providers. This functionality is required for + FATE feature 110320. ECO has been approved. + + Includes 19 changesets from xen-unstable. Most are + specific to Xen API. + + Includes 1 patch that relaxes parsing of xml response + in Xen API c-bindings. + +------------------------------------------------------------------- +Thu Feb 15 12:52:24 MST 2007 - carnold@novell.com + +- Added x86-nmi-inject.patch for NW debuging. (#245942) + +------------------------------------------------------------------- +Thu Feb 15 10:09:41 MST 2007 - carnold@novell.com + +- kernel panic in DomU while installing 32bit DomU on 64bit + Dom0. (#244055) Patches 13630-domctl.patch, + 13903-domctl.patch and 13908-domctl.patch +- Updated patch pae-guest-linear-pgtable.patch + +------------------------------------------------------------------- +Mon Feb 12 17:00:58 MST 2007 - ccoffing@novell.com + +- Load xenblk at dom0 start to support bootstrapping from + non-loopback devices. (#242963, #186696) +- Update vm-install: + + Update translations + + Clean up exception error codes and sync man pages + + Honor ordering of arguments (as claimed in man page) + + #240984: properly detach vncviewer + + #240387: default to absolute coordinate mouse for Windows +- Drop logging patch. (#245150) + ------------------------------------------------------------------- Mon Feb 12 01:50:34 CET 2007 - ro@suse.de diff --git a/xen.spec b/xen.spec index 6818040..04b39bd 100644 --- a/xen.spec +++ b/xen.spec @@ -30,7 +30,7 @@ BuildRequires: glibc-32bit glibc-devel-32bit BuildRequires: kernel-source kernel-syms xorg-x11 %endif Version: 3.0.4_13138 -Release: 2 +Release: 4 License: GNU General Public License (GPL) Group: System/Kernel Autoreqprov: on @@ -84,7 +84,7 @@ Patch31: xen-hvm-default-bridge.diff Patch32: xen-hvm-netfront.diff Patch33: xend-xmlrpc-large-ints.diff Patch34: xen-hvm-default-pae.diff -Patch35: xend-config-devname.patch +#Patch35: xend-config-devname.patch Patch36: xend-config-ramdisk.patch Patch37: xm-test-cleanup.diff ## Jan's patches begin here @@ -144,22 +144,22 @@ Patch154: libelf-use-xen-dom0.diff Patch155: libelf-symlink-to-libxc.diff Patch156: libelf-use-hvm-build.diff Patch157: libelf-use-readnotes.diff +Patch158: libelf-dominfo.diff # domain builder rewrite -Patch158: tools-add-errors.diff -Patch159: tools-domain-builder-header-libxc.diff -Patch160: tools-domain-builder-core.diff -Patch161: tools-domain-builder-linux.diff -Patch162: tools-readnotes-gunzip.diff +Patch160: tools-add-errors.diff +Patch161: tools-domain-builder-header-libxc.diff +Patch162: tools-domain-builder-core.diff +Patch163: tools-domain-builder-linux.diff +Patch164: tools-readnotes-gunzip.diff # bimodal driver bits -Patch163: protocol-bimodal.diff -Patch164: fbback-bimodal.diff -Patch165: blktools-bimodal.diff +Patch165: protocol-bimodal.diff +Patch166: fbback-bimodal.diff +Patch167: blktools-bimodal.diff # libxc debugging bits -Patch166: tools-debug-oldbuilder.diff -Patch167: libxc-logging.diff +Patch168: tools-debug-oldbuilder.diff # guest kexec, kboot -Patch168: tools-xc_kexec.diff -Patch169: tools-kboot.diff +Patch170: tools-xc_kexec.diff +Patch171: tools-kboot.diff # AMD nested page table patches Patch200: npt_part1.patch Patch201: npt_part2.patch @@ -170,8 +170,36 @@ Patch210: microcode-xen-13079.diff Patch211: xen-localtime.patch Patch212: svm-update-v_tpr-on-mmio.patch Patch213: svm_cpuid_ffxsr_13743.patch +Patch214: 13630-domctl.patch +Patch215: 13903-domctl.patch +Patch216: 13908-domctl.patch +Patch217: x86-nmi-inject.patch # pv driver building Patch250: pv-driver-build.patch +# Jim' Xen API patches +Patch270: 13161_xenapi.patch +Patch271: 13201_xenapi.patch +Patch272: 13226_xenapi.patch +Patch273: 13235_xenapi.patch +Patch274: 13236_xenapi.patch +Patch275: 13577_xenapi.patch +Patch276: 13585_xenapi.patch +Patch277: 13615_xenapi.patch +Patch278: 13616_xenapi.patch +Patch279: 13628_xenapi.patch +Patch280: 13655_xenapi.patch +Patch281: 13689_xenapi.patch +Patch282: 13724_xenapi.patch +Patch283: 13745_xenapi.patch +Patch284: 13747_xenapi.patch +Patch285: 13753_xenapi.patch +Patch286: 13775_xenapi.patch +Patch287: 13777_xenapi.patch +Patch288: 13778_xenapi.patch +Patch289: 13784_xenapi.patch +Patch290: 13787_xenapi.patch +Patch291: libxen_permissive.patch +Patch292: xend_disk_decorate_rm.patch # Misc unused patches / need to be re-ported: Patch300: xen-enable-hvm-debug.diff Patch301: xen-removable.diff @@ -585,7 +613,7 @@ cd .. %patch32 -p1 %patch33 -p1 %patch34 -p1 -%patch35 -p1 +#%patch35 -p1 %patch36 -p1 %patch37 -p1 %patch100 -p1 @@ -638,7 +666,6 @@ cd .. %patch156 -p1 %patch157 -p1 %patch158 -p1 -%patch159 -p1 %patch160 -p1 %patch161 -p1 %patch162 -p1 @@ -648,7 +675,8 @@ cd .. %patch166 -p1 %patch167 -p1 %patch168 -p1 -%patch169 -p1 +%patch170 -p1 +%patch171 -p1 %patch200 -p1 %patch201 -p1 %patch202 -p1 @@ -657,7 +685,34 @@ cd .. %patch211 -p1 %patch212 -p1 %patch213 -p1 +%patch214 -p1 +%patch215 -p1 +%patch216 -p1 +%patch217 -p1 %patch250 -p1 +%patch270 -p1 +%patch271 -p1 +%patch272 -p1 +%patch273 -p1 +%patch274 -p1 +%patch275 -p1 +%patch276 -p1 +%patch277 -p1 +%patch278 -p1 +%patch279 -p1 +%patch280 -p1 +%patch281 -p1 +%patch282 -p1 +%patch283 -p1 +%patch284 -p1 +%patch285 -p1 +%patch286 -p1 +%patch287 -p1 +%patch288 -p1 +%patch289 -p1 +%patch290 -p1 +%patch291 -p1 +%patch292 -p1 XEN_EXTRAVERSION=%version-%release XEN_EXTRAVERSION=${XEN_EXTRAVERSION#%{xvers}} sed -i "s/XEN_EXTRAVERSION[ ]*.=.*\$/XEN_EXTRAVERSION = $XEN_EXTRAVERSION/" xen/Makefile @@ -730,6 +785,7 @@ make -C tools install \ DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %if %{?with_install}0 ln -s /usr/bin/vm-install $RPM_BUILD_ROOT/usr/sbin/xen-vm-install +%find_lang xen-vm-install %endif make -C tools/misc/serial-split install \ DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} @@ -836,8 +892,13 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %{_libdir}/fs/ %{_libdir}/libfsimage* %{_libdir}/libxen*.so.* +%if %{?with_install}0 -%files tools +%files tools -f ../xen-vm-install.lang +%else + +%files tools +%endif %defattr(-,root,root) /usr/bin/lomount /usr/bin/xencons @@ -968,7 +1029,40 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %{restart_on_update xend} %{insserv_cleanup} -%changelog -n xen +%changelog +* Fri Feb 16 2007 - jfehlig@novell.com +- Added changeset 13775 from xen-unstable. This patch fixes + the last known issue with the Xen API patchset backported + from xen-unstable. +* Fri Feb 16 2007 - jfehlig@novell.com +- Added c/s 13226 from xen-unstable. It affects Xen API only. +- Added patch to remove ':disk' and 'tap:qcow' from stored domain + config. Fixes bug #237414 and helps with bug #242953. +* Thu Feb 15 2007 - jfehlig@novell.com +- Backported Xen API functionality from xen-unstable to support + hosting CIM providers. This functionality is required for + FATE feature 110320. ECO has been approved. + + Includes 19 changesets from xen-unstable. Most are + specific to Xen API. + + Includes 1 patch that relaxes parsing of xml response + in Xen API c-bindings. +* Thu Feb 15 2007 - carnold@novell.com +- Added x86-nmi-inject.patch for NW debuging. (#245942) +* Thu Feb 15 2007 - carnold@novell.com +- kernel panic in DomU while installing 32bit DomU on 64bit + Dom0. (#244055) Patches 13630-domctl.patch, + 13903-domctl.patch and 13908-domctl.patch +- Updated patch pae-guest-linear-pgtable.patch +* Mon Feb 12 2007 - ccoffing@novell.com +- Load xenblk at dom0 start to support bootstrapping from + non-loopback devices. (#242963, #186696) +- Update vm-install: + + Update translations + + Clean up exception error codes and sync man pages + + Honor ordering of arguments (as claimed in man page) + + #240984: properly detach vncviewer + + #240387: default to absolute coordinate mouse for Windows +- Drop logging patch. (#245150) * Mon Feb 12 2007 - ro@suse.de - remove -fstack-protector from RPM_OPT_FLAGS for now * Thu Feb 08 2007 - ccoffing@novell.com diff --git a/xend-config-devname.patch b/xend-config-devname.patch deleted file mode 100644 index 2871e49..0000000 --- a/xend-config-devname.patch +++ /dev/null @@ -1,27 +0,0 @@ -# HG changeset patch -# User jfehlig@jfehlig2.provo.novell.com -# Date 1166568442 25200 -# Node ID 72a013bc923efa47b3262849cd5611a16353abc5 -# Parent 057f7c4dbed1c75a3fbe446d346cee04cff31497 -Remove ':disk' suffix from dev entry in dev_info dictionary in XendConfig.py. - -The suffix was added regardless of device type so it doesn't appear to add any semantics. Additionally, clients would be forced to strip this suffix from the device name since something like 'hda:disk" is not a device name. - -Signed-off-by: Jim Fehlig - -diff -r 057f7c4dbed1 -r 72a013bc923e tools/python/xen/xend/XendConfig.py ---- a/tools/python/xen/xend/XendConfig.py Tue Dec 19 12:00:11 2006 +0000 -+++ b/tools/python/xen/xend/XendConfig.py Tue Dec 19 15:47:22 2006 -0700 -@@ -970,10 +970,10 @@ class XendConfig(dict): - elif dev_type in ('vbd', 'tap'): - if dev_type == 'vbd': - dev_info['uname'] = cfg_xenapi.get('image', '') -- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') -+ dev_info['dev'] = cfg_xenapi.get('device') - elif dev_type == 'tap': - dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image') -- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') -+ dev_info['dev'] = cfg_xenapi.get('device') - - dev_info['driver'] = cfg_xenapi.get('driver') - dev_info['VDI'] = cfg_xenapi.get('VDI', '') diff --git a/xend_disk_decorate_rm.patch b/xend_disk_decorate_rm.patch new file mode 100644 index 0000000..04618e1 --- /dev/null +++ b/xend_disk_decorate_rm.patch @@ -0,0 +1,41 @@ +diff -ru xen-3.0.4-testing-orig/tools/python/xen/xend/server/blkif.py xen-3.0.4-testing/tools/python/xen/xend/server/blkif.py +--- xen-3.0.4-testing-orig/tools/python/xen/xend/server/blkif.py 2007-02-16 11:16:04.000000000 -0700 ++++ xen-3.0.4-testing/tools/python/xen/xend/server/blkif.py 2007-02-16 11:22:25.000000000 -0700 +@@ -120,10 +120,10 @@ + 'uuid') + dev, typ, params, mode, uuid = devinfo + ++ dev_type = self.readFrontend(devid, 'device-type') ++ if dev_type: ++ config['type'] = dev_type + if dev: +- dev_type = self.readFrontend(devid, 'device-type') +- if dev_type: +- dev += ':' + dev_type + config['dev'] = dev + if typ and params: + config['uname'] = typ +':' + params +diff -ru xen-3.0.4-testing-orig/tools/python/xen/xend/XendConfig.py xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py +--- xen-3.0.4-testing-orig/tools/python/xen/xend/XendConfig.py 2007-02-16 11:16:06.000000000 -0700 ++++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py 2007-02-16 11:25:03.000000000 -0700 +@@ -1036,12 +1036,14 @@ + target['vif_refs'].append(dev_uuid) + + elif dev_type in ('vbd', 'tap'): +- if dev_type == 'vbd': +- dev_info['uname'] = cfg_xenapi.get('image', '') +- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') +- elif dev_type == 'tap': +- dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image') +- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') ++ dev_info['type'] = cfg_xenapi.get('type', 'Disk') ++ if dev_info['type'] == 'CD': ++ dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'), ++ 'cdrom') ++ else: ++ dev_info['dev'] = cfg_xenapi.get('device') ++ ++ dev_info['uname'] = cfg_xenapi.get('image', '') + + dev_info['driver'] = cfg_xenapi.get('driver') + dev_info['VDI'] = cfg_xenapi.get('VDI', '')