def vm_cpu_affinity_check(config_file, id_cpus_per_vm_dic, item): """ Check cpu number of per vm :param item: vm pcpu_id item in xml :return: error informations """ err_dic = {} use_cpus = [] cpu_sharing_enabled = True cpu_sharing = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "SCHEDULER") if cpu_sharing == "SCHED_NOOP": cpu_sharing_enabled = False cpu_affinity = common.get_leaf_tag_map(config_file, "cpu_affinity", "pcpu_id") for vm_i in id_cpus_per_vm_dic.keys(): for cpu in id_cpus_per_vm_dic[vm_i]: if cpu in use_cpus and not cpu_sharing_enabled: key = "vm:id={},{}".format(vm_i, item) err_dic[ key] = "The same pcpu was configurated in <pcpu_id>/<cpu_affinity>, but CPU sharing is disabled by 'SCHED_NOOP'. Please re-configurate them!" return err_dic else: use_cpus.append(cpu) pre_launch_cpus = [] post_launch_cpus = [] for vm_i, vm_type in common.VM_TYPES.items(): if vm_i not in id_cpus_per_vm_dic.keys(): continue elif VM_DB[vm_type]['load_type'] == "PRE_LAUNCHED_VM": cpus = [x for x in id_cpus_per_vm_dic[vm_i] if not None] pre_launch_cpus.extend(cpus) elif VM_DB[vm_type]['load_type'] == "POST_LAUNCHED_VM": cpus = [x for x in id_cpus_per_vm_dic[vm_i] if not None] post_launch_cpus.extend(cpus) # duplicate cpus assign the same VM check cpus_vm_i = id_cpus_per_vm_dic[vm_i] for cpu_id in cpus_vm_i: if cpus_vm_i.count(cpu_id) >= 2: key = "vm:id={},{}".format(vm_i, item) err_dic[key] = "VM should not use the same pcpu id:{}".format( cpu_id) return err_dic if pre_launch_cpus: for pcpu in pre_launch_cpus: if pre_launch_cpus.count(pcpu) >= 2: key = "Pre launched VM cpu_affinity" err_dic[ key] = "Pre_launched_vm vm should not have the same cpus assignment" if pcpu in post_launch_cpus: key = "Pre launched vm and Post launchded VM cpu_affinity" err_dic[ key] = "Pre launched_vm and Post launched vm should not have the same cpus assignment" return err_dic
def get_pci_devs(self): """ Get pci devices items :return: None """ pci_items = common.get_leaf_tag_map(self.scenario_info, "pci_devs", "pci_dev") self.pci_devs = scenario_cfg_lib.get_pci_devs(pci_items)
def get_pci_dev_num(self): """ Get pci device number items :return: None """ self.pci_dev_num = common.get_leaf_tag_map(self.scenario_info, "pci_dev_num")
def set_shm_regions(launch_item_values, scenario_info): try: raw_shmem_regions = common.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_REGION") vm_types = common.get_leaf_tag_map(scenario_info, "vm_type") shm_enabled = common.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED") except: return sos_vm_id = 0 for vm_id, vm_type in vm_types.items(): if vm_type in ['SOS_VM']: sos_vm_id = vm_id elif vm_type in ['POST_STD_VM', 'POST_RT_VM', 'KATA_VM']: uos_id = vm_id - sos_vm_id shm_region_key = 'uos:id={},shm_regions,shm_region'.format(uos_id) launch_item_values[shm_region_key] = [''] if shm_enabled == 'y': for shmem_region in raw_shmem_regions: if shmem_region is None or shmem_region.strip() == '': continue try: shm_splited = shmem_region.split(',') name = shm_splited[0].strip() size = shm_splited[1].strip() vm_id_list = [ x.strip() for x in shm_splited[2].split(':') ] if str(vm_id) in vm_id_list: launch_item_values[shm_region_key].append(','.join( [name, size])) except Exception as e: print(e)
def get_info(self): """ Get all items which belong to this class :return: None """ pt_intx_map = common.get_leaf_tag_map(self.scenario_info, "pt_intx") # translation table to normalize the paired phys_gsi and virt_gsi string table = {ord('[') : ord('('), ord(']') : ord(')'), ord('{') : ord('('), ord('}') : ord(')'), ord(';') : ord(','), ord('\n') : None, ord('\r') : None, ord(' ') : None} for vm_i, s in pt_intx_map.items(): #normalize the phys_gsi and virt_gsi pair string s = s.translate(table) #extract the phys_gsi and virt_gsi pairs between parenthesis to a list s = re.findall(r'\(([^)]+)', s) self.phys_gsi[vm_i] = []; self.virt_gsi[vm_i] = []; for part in s: if not part: continue assert ',' in part, "you need to use ',' to separate phys_gsi and virt_gsi!" a, b = part.split(',') if not a and not b: continue assert a and b, "you need to specify both phys_gsi and virt_gsi!" a, b = common.str2int(a), common.str2int(b) self.phys_gsi[vm_i].append(a) self.virt_gsi[vm_i].append(b)
def mem_size_check(item): """ Check host physical size :param item: vm size item in xml :return: None """ prime_item = "memory" id_hpa_size_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key, hpa_size in id_hpa_size_dic.items(): hpa_sz_strip_ul = hpa_size.strip('UL') hpa_sz_strip_u = hpa_size.strip('U') if not hpa_size: key = "vm:id={},{}".format(id_key, item) ERR_LIST[ key] = "VM start host physical memory size should not empty" return if hpa_sz_strip_ul not in common.START_HPA_SIZE_LIST and hpa_sz_strip_u not in \ common.START_HPA_SIZE_LIST: key = "vm:id={},{},{}".format(id_key, prime_item, item) mem_max = 2 * 1024 * 1024 * 1024 if '0x' not in hpa_size and '0X' not in hpa_size: ERR_LIST[key] = "Mem size should be Hex format" elif int(hpa_sz_strip_ul, 16) > mem_max or int(hpa_sz_strip_u, 16) > mem_max: ERR_LIST[key] = "Mem size should less than 2GB"
def pci_dev_num_per_vm_gen(config): pci_items = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "pci_devs", "pci_dev") pci_devs = scenario_cfg_lib.get_pci_devs(pci_items) pci_dev_num = scenario_cfg_lib.get_pci_num(pci_devs) ivshmem_region = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_REGION") shmem_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED") shmem_regions = scenario_cfg_lib.get_shmem_regions(ivshmem_region) shmem_num = scenario_cfg_lib.get_shmem_num(shmem_regions) for vm_i,vm_type in common.VM_TYPES.items(): if "POST_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: if shmem_enabled == 'y' and vm_i in shmem_num.keys(): print("#define VM{}_CONFIG_PCI_DEV_NUM\t{}U".format(vm_i, shmem_num[vm_i]), file=config) elif "PRE_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: shmem_num_i = 0 if shmem_enabled == 'y' and vm_i in shmem_num.keys(): shmem_num_i = shmem_num[vm_i] print("#define VM{}_CONFIG_PCI_DEV_NUM\t{}U".format(vm_i, pci_dev_num[vm_i] + shmem_num_i), file=config) print("", file=config)
def set_pci_vuarts(launch_item_values, scenario_info): try: launch_item_values['user_vm,console_vuart'] = DM_VUART0 vm_types = common.get_leaf_tag_map(scenario_info, 'vm_type') sos_vm_id = 0 for vm_id, vm_type in vm_types.items(): if vm_type in ['SERVICE_VM']: sos_vm_id = vm_id for vm in list(common.get_config_root(scenario_info)): if vm.tag == 'vm' and scenario_cfg_lib.VM_DB[vm_types[int( vm.attrib['id'])]]['load_type'] == 'POST_LAUNCHED_VM': user_vmid = int(vm.attrib['id']) - sos_vm_id pci_vuart_key = 'user_vm:id={},communication_vuarts,communication_vuart'.format( user_vmid) for elem in list(vm): if elem.tag == 'communication_vuart': for sub_elem in list(elem): if sub_elem.tag == 'base' and sub_elem.text == 'PCI_VUART': if pci_vuart_key not in launch_item_values.keys( ): launch_item_values[pci_vuart_key] = [ '', elem.attrib['id'] ] else: launch_item_values[pci_vuart_key].append( elem.attrib['id']) except: return
def get_uos_type(): """ Get uos name from launch.xml at fist line """ uos_types = common.get_leaf_tag_map(common.LAUNCH_INFO_FILE, "uos_type") return uos_types
def get_user_vm_type(): """ Get User VM name from launch.xml at fist line """ user_vm_types = common.get_leaf_tag_map(common.LAUNCH_INFO_FILE, "user_vm_type") return user_vm_types
def clos_per_vm_gen(config): clos_per_vm = {} clos_per_vm = common.get_leaf_tag_map( common.SCENARIO_INFO_FILE, "clos", "vcpu_clos") for i,clos_list_i in clos_per_vm.items(): clos_config = scenario_cfg_lib.clos_assignment(clos_per_vm, i) print("#define VM{0}_VCPU_CLOS\t\t\t{1}".format(i, clos_config['clos_map']), file=config)
def get_leaf_tag_map(info_file, prime_item, item=''): """ :param info_file: some configurations in the info file :param prime_item: the prime item in xml file :param item: the item in xml file :return: dictionary which item value could be indexed by vmid """ vmid_item_dic = common.get_leaf_tag_map(info_file, prime_item, item) return vmid_item_dic
def check_items(self): ''' check the configurations for share memories. :return: ''' if self.shmem_enabled == 'y': vm_type_info = common.get_leaf_tag_map(self.scenario_info, "vm_type") scenario_cfg_lib.share_mem_check(self.shmem_regions, self.raw_shmem_regions, vm_type_info, "FEATURES", "IVSHMEM", "IVSHMEM_REGION")
def cpu_affinity_per_vm_gen(config): cpus_per_vm = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "cpu_affinity", "pcpu_id") for vm_i, _ in common.VM_TYPES.items(): cpu_bits = scenario_cfg_lib.cpus_assignment(cpus_per_vm, vm_i) cpu_affinity_output(cpu_bits, vm_i, config) print("", file=config)
def get_bdf_from_tag(config_file, branch_tag, tag_str): bdf_list = {} bdf_list = common.get_leaf_tag_map(config_file, branch_tag, tag_str) # split b:d:f from pci description for idx, bdf_v in bdf_list.items(): if bdf_v: bdf_list[idx] = bdf_v.split()[0] return bdf_list
def boot_args_per_vm_gen(config): kern_args = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "bootargs") for vm_i,vm_type in common.VM_TYPES.items(): if "PRE_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: if vm_i in kern_args.keys() and kern_args[vm_i]: print("#define VM{}_BOOT_ARGS\t".format(vm_i), end="", file=config) split_cmdline(kern_args[vm_i].strip(), config) print("", file=config) print("", file=config)
def get_sos_vmid(): load_dic = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "load_order") sos_id = '' for idx, load_order in load_dic.items(): if load_order == "SOS_VM": sos_id = idx break return sos_id
def get_info(self): """ Get all items which belong to this class :return: None """ self.name = common.get_leaf_tag_map(self.scenario_info, "name") self.load_vm = common.get_leaf_tag_map(self.scenario_info, "vm_type") self.guest_flags = common.get_leaf_tag_map(self.scenario_info, "guest_flags", "guest_flag") self.cpus_per_vm = common.get_leaf_tag_map(self.scenario_info, "cpu_affinity", "pcpu_id") self.clos_per_vm = common.get_leaf_tag_map(self.scenario_info, "clos", "vcpu_clos") self.epc_section.get_info() self.mem_info.get_info() self.os_cfg.get_info() self.vuart.get_info() self.cfg_pci.get_info() self.load_order_cnt.get_info(self.load_vm)
def is_tpm_passthru(): tpm_passthru = False (_, board) = common.get_board_name() tpm2_passthru_enabled = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "mmio_resources", "TPM2") if board in TPM_PASSTHRU_BOARD and tpm2_passthru_enabled and 'y' in tpm2_passthru_enabled.values( ): tpm_passthru = True return tpm_passthru
def get_args(self): self.args["uos_type"] = common.get_leaf_tag_map( self.launch_info, "uos_type") self.args["rtos_type"] = common.get_leaf_tag_map( self.launch_info, "rtos_type") self.args["mem_size"] = common.get_leaf_tag_map( self.launch_info, "mem_size") self.args["gvt_args"] = common.get_leaf_tag_map( self.launch_info, "gvt_args") self.args["vbootloader"] = common.get_leaf_tag_map( self.launch_info, "vbootloader") self.args["vuart0"] = common.get_leaf_tag_map(self.launch_info, "vuart0") self.args["cpu_sharing"] = common.get_leaf_tag_map( self.launch_info, "cpu_sharing") self.args["pm_channel"] = common.get_leaf_tag_map( self.launch_info, "poweroff_channel") self.args["off_pcpus"] = common.get_leaf_tag_map( self.scenario_info, "vcpu_affinity", "pcpu_id") self.args["xhci"] = common.get_leaf_tag_map(self.launch_info, "usb_xhci")
def off_line_cpus(args, vmid, user_vm_type, config): """ :param args: the dictionary of argument for acrn-dm :param vmid: ID of the vm :param user_vm_type: the type of User VM :param config: it is a file pointer to write offline cpu information """ pcpu_id_list = get_cpu_affinity_list(args["cpu_affinity"], vmid) if not pcpu_id_list: sos_vmid = launch_cfg_lib.get_sos_vmid() cpu_affinity = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "cpu_affinity", "pcpu_id") pcpu_id_list = get_cpu_affinity_list(cpu_affinity, sos_vmid + vmid) if not pcpu_id_list: key = "scenario config error" launch_cfg_lib.ERR_LIST[ key] = "No available cpu to offline and pass it to vm {}".format( vmid) print("# offline pinned vCPUs from Service VM before launch User VM", file=config) print('cpu_path="/sys/devices/system/cpu"', file=config) print("for i in `ls ${cpu_path}`; do", file=config) print(" for j in {}; do".format(' '.join([str(i) for i in pcpu_id_list])), file=config) print(' if [ "cpu"$j = $i ]; then', file=config) print(' online=`cat ${cpu_path}/$i/online`', file=config) print(' idx=`echo $i | tr -cd "[0-9]"`', file=config) print(' echo $i online=$online', file=config) print(' if [ "$online" = "1" ] && [ "$idx" != "0" ]; then', file=config) print(" echo 0 > ${cpu_path}/$i/online", file=config) print(" online=`cat ${cpu_path}/$i/online`", file=config) print( " # during boot time, cpu hotplug may be disabled by pci_device_probe during a pci module insmod", file=config) print(' while [ "$online" = "1" ]; do', file=config) print(" sleep 1", file=config) print(" echo 0 > ${cpu_path}/$i/online", file=config) print(" online=`cat ${cpu_path}/$i/online`", file=config) print(" done", file=config) print( " echo $idx > /sys/devices/virtual/misc/acrn_hsm/remove_cpu", file=config) print(" fi", file=config) print(" fi", file=config) print(" done", file=config) print("done", file=config) print("", file=config)
def off_line_cpus(args, vmid, uos_type, config): """ :param args: the dictionary of argument for acrn-dm :param vmid: ID of the vm :param uos_type: the type of UOS :param config: it is a file pointer to write offline cpu information """ pcpu_id_list = get_cpu_affinity_list(args["cpu_affinity"], vmid) if not pcpu_id_list: sos_vmid = launch_cfg_lib.get_sos_vmid() cpu_affinity = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "cpu_affinity", "pcpu_id") pcpu_id_list = get_cpu_affinity_list(cpu_affinity, sos_vmid + vmid) if not pcpu_id_list: key = "scenario config error" launch_cfg_lib.ERR_LIST[ key] = "No available cpu to offline and pass it to vm {}".format( vmid) print('offline_path="/sys/class/vhm/acrn_vhm"', file=config) print("", file=config) print( "# Check the device file of /dev/acrn_hsm to determine the offline_path", file=config) print('if [ -e "/dev/acrn_hsm" ]; then', file=config) print('offline_path="/sys/class/acrn/acrn_hsm"', file=config) print('fi', file=config) print("", file=config) print("# offline pinned vCPUs from SOS before launch UOS", file=config) print("for i in `ls -d /sys/devices/system/cpu/cpu[{}]`; do".format( '..'.join(pcpu_id_list)), file=config) print(" online=`cat $i/online`", file=config) print(' idx=`echo $i | tr -cd "[1-99]"`', file=config) print(" echo cpu$idx online=$online", file=config) print(' if [ "$online" = "1" ]; then', file=config) print(" echo 0 > $i/online", file=config) print(" online=`cat $i/online`", file=config) print( " # during boot time, cpu hotplug may be disabled by pci_device_probe during a pci module insmod", file=config) print(' while [ "$online" = "1" ]; do', file=config) print(" sleep 1", file=config) print(" echo 0 > $i/online", file=config) print(" online=`cat $i/online`", file=config) print(" done", file=config) print(" echo $idx > ${offline_path}/offline_cpu", file=config) print(" fi", file=config) print("done", file=config) print("", file=config)
def check_board_private_info(): if 'SOS_VM' not in common.VM_TYPES.values(): return branch_tag = "board_private" private_info = {} dev_private_tags = ['rootfs'] for tag_str in dev_private_tags: dev_setting = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, branch_tag, tag_str) private_info[tag_str] = dev_setting if not private_info['rootfs'] and err_dic: ERR_LIST['vm:id=0,boot_private,rootfs'] = "The board have to chose one rootfs partition" ERR_LIST.update(err_dic)
def parse_boot_info(): err_dic = {} if 'SOS_VM' in common.VM_TYPES.values(): sos_cmdlines = list( common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "bootargs").values()) sos_rootfs = list( common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "rootfs").values()) (err_dic, vuart0_dic, vuart1_dic) = get_vuart_settings() else: sos_cmdlines = list( common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "bootargs").values()) sos_rootfs = list( common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "rootfs").values()) (err_dic, vuart0_dic, vuart1_dic) = get_vuart_settings() return (err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic)
def os_kern_root_dev_check(item): """ Check os kernel rootfs partitions :param item: vm os config rootdev item in xml :return: None """ prime_item = "os_config" id_kern_rootdev_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key, kern_rootdev in id_kern_rootdev_dic.items(): if not kern_rootdev: key = "vm:id={},{},{}".format(id_key, prime_item, item) ERR_LIST[key] = "VM os config kernel root device should not empty"
def os_kern_console_check(item): """ Check os kernel console :param item: vm os config console item in xml :return: None """ prime_item = "os_config" id_kern_console_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key, kern_console in id_kern_console_dic.items(): if kern_console and "ttyS" not in kern_console: key = "vm:id={},{},{}".format(id_key, prime_item, item) ERR_LIST[key] = "VM os config kernel console should be ttyS[0..3]"
def os_kern_mod_check(item): """ Check os kernel mod :param item: vm os config mod item in xml :return: None """ prime_item = "os_config" id_kern_mod_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key, kern_mod in id_kern_mod_dic.items(): if len(kern_mod) > 32 or len(kern_mod) == 0: key = "vm:id={},{},{}".format(id_key, prime_item, item) ERR_LIST[ key] = "VM os config kernel mod tag should be in range [1,32] bytes"
def cpus_per_vm_check(item): """ Check cpu of per vm :param item: vm pcpu_id item in xml :return: None """ prime_item = "pcpu_ids" id_cpus_per_vm_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key in id_cpus_per_vm_dic.keys(): vm_type = get_order_type_by_vmid(id_key) cpus_vm_i = id_cpus_per_vm_dic[id_key] if not cpus_vm_i and vm_type == "PRE_LAUNCHED_VM": key = "vm:id={},{}".format(id_key, item) ERR_LIST[key] = "VM have no assignment cpus"
def os_kern_args_check(item): """ Check os kernel args :param item: vm os config args item in xml :return: None """ prime_item = "os_config" id_kern_args_dic = common.get_leaf_tag_map(SCENARIO_INFO_FILE, prime_item, item) for id_key, kern_args in id_kern_args_dic.items(): vm_type = get_order_type_by_vmid(id_key) if vm_type == "SOS_VM" and kern_args != "SOS_VM_BOOTARGS": key = "vm:id={},{},{}".format(id_key, prime_item, item) ERR_LIST[ key] = "VM os config kernel service os should be SOS_VM_BOOTARGS"
def pci_dev_num_per_vm_gen(config): pci_items = common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "pci_devs", "pci_dev") pci_devs = scenario_cfg_lib.get_pt_pci_devs(pci_items) pt_pci_num = scenario_cfg_lib.get_pt_pci_num(pci_devs) ivshmem_region = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_REGION") shmem_enabled = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED") shmem_regions = scenario_cfg_lib.get_shmem_regions(ivshmem_region) shmem_num = scenario_cfg_lib.get_shmem_num(shmem_regions) vuarts = common.get_vuart_info(common.SCENARIO_INFO_FILE) pci_vuarts_num = scenario_cfg_lib.get_pci_vuart_num(vuarts) for vm_i, vm_type in common.VM_TYPES.items(): num = 0 if "POST_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: shmem_num_i = 0 pci_vuart_num = pci_vuarts_num[vm_i] if shmem_enabled == 'y' and vm_i in shmem_num.keys(): shmem_num_i = shmem_num[vm_i] num = shmem_num_i + pci_vuart_num elif "PRE_LAUNCHED_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: shmem_num_i = 0 if shmem_enabled == 'y' and vm_i in shmem_num.keys(): shmem_num_i = shmem_num[vm_i] num = pt_pci_num[vm_i] + shmem_num_i + pci_vuarts_num[vm_i] if pt_pci_num[vm_i] > 0 or shmem_num_i > 0 or pci_vuarts_num[ vm_i] > 0: # if there is passthrough device or ivshmem, vhostbridge is needed num += 1 elif "SOS_VM" == scenario_cfg_lib.VM_DB[vm_type]['load_type']: continue if num > 0: print("#define VM{}_CONFIG_PCI_DEV_NUM\t{}U".format(vm_i, num), file=config) print("", file=config)