1# Copyright (C) 2019-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6import os 7import getopt 8import re 9 10import acrn_config_utilities 11import board_cfg_lib 12import scenario_cfg_lib 13import lxml 14from defusedxml.lxml import parse 15 16ERR_LIST = {} 17BOOT_TYPE = ['no', 'ovmf'] 18RTOS_TYPE = ['no', 'Soft RT', 'Hard RT'] 19DM_VUART0 = ['Disable', 'Enable'] 20y_n = ['y', 'n'] 21USER_VM_TYPES = ['CLEARLINUX', 'ANDROID', 'ALIOS', 'PREEMPT-RT LINUX', 'VXWORKS', 'WINDOWS', 'ZEPHYR', 'YOCTO', 'UBUNTU', 'GENERIC LINUX'] 22LINUX_LIKE_OS = ['CLEARLINUX', 'PREEMPT-RT LINUX', 'YOCTO', 'UBUNTU', 'GENERIC LINUX'] 23 24PT_SUB_PCI = {} 25PT_SUB_PCI['usb_xdci'] = ['USB controller'] 26PT_SUB_PCI['gpu'] = ['VGA compatible controller'] 27PT_SUB_PCI['ipu'] = ['Multimedia controller'] 28PT_SUB_PCI['ipu_i2c'] = ['Signal processing controller'] 29PT_SUB_PCI['cse'] = ['Communication controller'] 30PT_SUB_PCI['audio'] = ['Audio device', 'Multimedia audio controller'] 31PT_SUB_PCI['audio_codec'] = ['Signal processing controller'] 32PT_SUB_PCI['sd_card'] = ['SD Host controller'] 33PT_SUB_PCI['wifi'] = ['Ethernet controller', 'Network controller', '802.1a controller', 34 '802.1b controller', 'Wireless controller'] 35PT_SUB_PCI['bluetooth'] = ['Signal processing controller'] 36PT_SUB_PCI['ethernet'] = ['Ethernet controller', 'Network controller'] 37PT_SUB_PCI['sata'] = ['SATA controller'] 38PT_SUB_PCI['nvme'] = ['Non-Volatile memory controller'] 39 40# passthrough devices for board 41PASSTHRU_DEVS = ['usb_xdci', 'gpu', 'ipu', 'ipu_i2c', 'cse', 'audio', 'sata', 42 'nvme', 'audio_codec', 'sd_card', 'ethernet', 'wifi', 'bluetooth'] 43 44PT_SLOT = { 45 "hostbridge":0, 46 "lpc":1, 47 "pci-gvt":2, 48 "virtio-blk":3, 49 "igd-lpc":31, 50 } 51 52 53MOUNT_FLAG_DIC = {} 54 55 56def usage(file_name): 57 """ This is usage for how to use this tool """ 58 print("usage= {} [h]".format(file_name), end="") 59 print("--board <board_info_file> --scenario <scenario_info_file> --launch <launch_info_file> --user_vmid <user_vmid id> --out [output folder]") 60 print('board_info_file : file name of the board info') 61 print('scenario_info_file : file name of the scenario info') 62 print('launch_info_file : file name of the launch info') 63 print('user_vmid : this is the relative id for post launch vm in scenario info XML:[1..max post launch vm]') 64 print('output folder : path to acrn-hypervisor_folder') 65 66 67def get_param(args): 68 """ 69 Get the script parameters from command line 70 :param args: this the command line of string for the script without script name 71 """ 72 vm_th = '0' 73 err_dic = {} 74 board_info_file = False 75 scenario_info_file = False 76 launch_info_file = False 77 output_folder = False 78 param_list = ['--board', '--scenario', '--launch', '--user_vmid'] 79 80 for arg_str in param_list: 81 82 if arg_str not in args: 83 usage(args[0]) 84 err_dic['acrn_config_utilities error: wrong parameter'] = "wrong usage" 85 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 86 87 args_list = args[1:] 88 (optlist, args_list) = getopt.getopt(args_list, '', ['board=', 'scenario=', 'launch=', 'user_vmid=', 'out=']) 89 for arg_k, arg_v in optlist: 90 if arg_k == '--board': 91 board_info_file = arg_v 92 if arg_k == '--scenario': 93 scenario_info_file = arg_v 94 if arg_k == '--launch': 95 launch_info_file = arg_v 96 if arg_k == '--out': 97 output_folder = arg_v 98 if '--user_vmid' in args: 99 if arg_k == '--user_vmid': 100 vm_th = arg_v 101 if not vm_th.isnumeric(): 102 err_dic['common error: wrong parameter'] = "--user_vmid should be a number" 103 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 104 105 if not board_info_file or not scenario_info_file or not launch_info_file: 106 usage(args[0]) 107 err_dic['common error: wrong parameter'] = "wrong usage" 108 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 109 110 if not os.path.exists(board_info_file): 111 err_dic['common error: wrong parameter'] = "{} does not exist!".format(board_info_file) 112 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 113 114 if not os.path.exists(scenario_info_file): 115 err_dic['common error: wrong parameter'] = "{} does not exist!".format(scenario_info_file) 116 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 117 118 if not os.path.exists(launch_info_file): 119 err_dic['common error: wrong parameter'] = "{} does not exist!".format(launch_info_file) 120 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 121 122 return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th), output_folder) 123 124 125def launch_vm_cnt(config_file): 126 """ 127 Get post vm number 128 :param config_file: it is a file what contains information for script to read from 129 :return: total post vm number in launch file 130 """ 131 post_vm_count = 0 132 133 # get post vm number 134 root = acrn_config_utilities.get_config_root(config_file) 135 for item in root: 136 if item.tag == "user_vm": 137 post_vm_count += 1 138 139 return post_vm_count 140 141 142def get_post_num_list(): 143 """ 144 Get post vm number list 145 :return: total post dic: {launch_id:scenario_id} in launch file 146 """ 147 post_vm_list = [] 148 149 # get post vm number 150 root = acrn_config_utilities.get_config_root(acrn_config_utilities.LAUNCH_INFO_FILE) 151 for item in root: 152 if item.tag == "user_vm": 153 post_vm_list.append(int(item.attrib['id'])) 154 155 return post_vm_list 156 157 158def post_vm_cnt(config_file): 159 """ 160 Calculate the pre launched vm number 161 :param config_file: it is a file what contains information for script to read from 162 :return: number of post launched vm 163 """ 164 post_launch_cnt = 0 165 166 for load_order in acrn_config_utilities.LOAD_ORDER.values(): 167 if load_order == "POST_LAUNCHED_VM": 168 post_launch_cnt += 1 169 170 return post_launch_cnt 171 172 173def get_post_vm_cnt(): 174 """ 175 Get board name from launch.xml at fist line 176 :param scenario_file: it is a file what contains scenario information for script to read from 177 """ 178 launch_vm_count = launch_vm_cnt(acrn_config_utilities.LAUNCH_INFO_FILE) 179 post_vm_count = post_vm_cnt(acrn_config_utilities.SCENARIO_INFO_FILE) 180 return (launch_vm_count, post_vm_count) 181 182 183def get_sos_vmid(): 184 185 sos_id = '' 186 for vm_i,load_order in acrn_config_utilities.LOAD_ORDER.items(): 187 if load_order == "SERVICE_VM": 188 sos_id = vm_i 189 break 190 191 return sos_id 192 193 194def get_bdf_from_tag(config_file, branch_tag, tag_str): 195 bdf_list = {} 196 bdf_list = acrn_config_utilities.get_leaf_tag_map(config_file, branch_tag, tag_str) 197 198 # split b:d:f from pci description 199 for idx, bdf_v in bdf_list.items(): 200 if bdf_v: 201 bdf_list[idx] = bdf_v.split()[0] 202 203 return bdf_list 204 205 206def get_vpid_from_bdf(bdf_vpid_map, bdf_list): 207 vpid_list = {} 208 post_vm_list = get_post_num_list() 209 for p_id in post_vm_list: 210 for bdf_k, vpid_v in bdf_vpid_map.items(): 211 if bdf_k == bdf_list[p_id]: 212 # print("k:{}, v{}".format(bdf_k, bdf_list[p_id])) 213 # convert "808x:0xxx" to "808x 0xxx" 214 tmp_vpid = " ".join(vpid_v.split(':')) 215 vpid_list[p_id] = tmp_vpid 216 elif not bdf_list[p_id]: 217 vpid_list[p_id] = '' 218 219 return vpid_list 220 221 222def get_user_vm_type(): 223 """ 224 Get User VM name from launch.xml at fist line 225 """ 226 user_vm_types = acrn_config_utilities.get_leaf_tag_map(acrn_config_utilities.LAUNCH_INFO_FILE, "user_vm_type") 227 228 return user_vm_types 229 230 231def get_user_vm_names(): 232 user_vm_names = acrn_config_utilities.get_leaf_tag_map(acrn_config_utilities.LAUNCH_INFO_FILE, "vm_name") 233 return user_vm_names 234 235 236def is_bdf_format(bdf_str): 237 bdf_len = 7 238 status = True 239 if not bdf_str: 240 return status 241 242 bdf_str_len = len(bdf_str) 243 if ':' in bdf_str and '.' in bdf_str and bdf_len == bdf_str_len: 244 status = True 245 else: 246 status = False 247 248 return status 249 250 251def is_vpid_format(vpid_str): 252 status = True 253 if not vpid_str: 254 return status 255 256 vpid_len = 9 257 vpid_str_len = len(vpid_str) 258 259 if ' ' in vpid_str and vpid_len == vpid_str_len: 260 status = True 261 else: 262 status = False 263 264 return status 265 266 267def pt_devs_check(bdf_list, vpid_list, item): 268 i_cnt = 1 269 270 # check bdf 271 for bdf_str in bdf_list.values(): 272 if is_bdf_format(bdf_str): 273 continue 274 else: 275 key = "user_vm:id={},passthrough_devices,{}".format(i_cnt, item) 276 ERR_LIST[key] = "Unkonw the BDF format of {} device".format(item) 277 i_cnt += 1 278 279 # check vpid 280 i_cnt = 1 281 for vpid_str in vpid_list.values(): 282 if is_vpid_format(vpid_str): 283 continue 284 else: 285 key = "user_vm:id={},passthrough_devices,{}".format(i_cnt, item) 286 ERR_LIST[key] = "Unkonw the Vendor:Product ID format of {} device".format(item) 287 288 i_cnt += 1 289 290 291def empty_err(i_cnt, item): 292 """ 293 add empty error message into ERR_LIST 294 :param i_cnt: the launch vm index from config xml 295 :param item: the item of tag from config xml 296 :return: None 297 """ 298 key = "user_vm:id={},{}".format(i_cnt, item) 299 ERR_LIST[key] = "The parameter should not be empty" 300 301 302def args_aval_check(arg_list, item, avl_list): 303 """ 304 check arguments from config xml are available and validate 305 :param arg_list: the list of arguments from config xml 306 :param item: the item of tag from config xml 307 :param avl_list: available argument which are allowed to chose 308 :return: None 309 """ 310 # args should be set into launch xml from webUI 311 i_cnt = 1 312 skip_check_list = [''] 313 if item in skip_check_list: 314 return 315 316 for arg_str in arg_list.values(): 317 if arg_str == None or not arg_str.strip(): 318 empty_err(i_cnt, item) 319 i_cnt += 1 320 continue 321 322 if arg_str not in avl_list: 323 key = "user_vm:id={},{}".format(i_cnt, item) 324 ERR_LIST[key] = "The {} is invalidate".format(item) 325 i_cnt += 1 326 327 328def mem_size_check(arg_list, item): 329 """ 330 check memory size list which are set from webUI 331 :param arg_list: the list of arguments from config xml 332 :param item: the item of tag from config xml 333 :return: None 334 """ 335 # get total memory information 336 total_mem_mb = board_cfg_lib.get_total_mem() 337 338 # available check 339 i_cnt = 1 340 for arg_str in arg_list.values(): 341 if arg_str == None or not arg_str.strip(): 342 empty_err(i_cnt, item) 343 i_cnt += 1 344 continue 345 346 mem_size_set = int(arg_str.strip()) 347 if mem_size_set > total_mem_mb: 348 key = "user_vm:id={},{}".format(i_cnt, item) 349 ERR_LIST[key] = "{}MB should be less than total memory {}MB".format(item) 350 i_cnt += 1 351 352 353def virtual_dev_slot(dev): 354 max_slot = 31 355 base_slot = 3 356 357 # get devices slot which already stored 358 if dev in list(PT_SLOT.keys()): 359 return PT_SLOT[dev] 360 361 # alloc a new slot for device 362 for slot_num in range(base_slot, max_slot): 363 if slot_num not in list(PT_SLOT.values()): 364 365 if (slot_num == 6 and 14 in list(PT_SLOT.values())) or (slot_num == 14 and 6 in list(PT_SLOT.values())): 366 continue 367 if (slot_num == 7 and 15 in list(PT_SLOT.values())) or (slot_num == 15 and 7 in list(PT_SLOT.values())): 368 continue 369 370 PT_SLOT[dev] = slot_num 371 break 372 373 return slot_num 374 375 376def get_slot(bdf_list, dev): 377 378 slot_list = {} 379 post_vm_list = get_post_num_list() 380 for p_id in post_vm_list: 381 if not bdf_list[p_id]: 382 slot_list[p_id] = '' 383 else: 384 slot_fun = virtual_dev_slot(dev) 385 PT_SLOT[dev] = slot_fun 386 slot_list[p_id] = slot_fun 387 388 return slot_list 389 390 391def reset_pt_slot(): 392 393 global PT_SLOT 394 395 PT_SLOT = { 396 "hostbridge":0, 397 "lpc":1, 398 "pci-gvt":2, 399 "virtio-blk":3, 400 "igd-lpc":31, 401 } 402 403 404def get_pt_dev(): 405 """ Get passthrough device list """ 406 cap_pt = PASSTHRU_DEVS 407 408 return cap_pt 409 410 411def get_vuart1_from_scenario(vmid): 412 """Get the vmid's vuart1 base""" 413 vuart1 = acrn_config_utilities.get_vuart_info_id(acrn_config_utilities.SCENARIO_INFO_FILE, 1) 414 return vuart1[vmid]['base'] 415 416 417def pt_devs_check_audio(audio_map, audio_codec_map): 418 """ 419 Check the connections about audio/audio_codec pass-through devices 420 If audio_codec is selected as pass-through device, the audio device 421 must to be chosen as pass-through device either. 422 :param audio_map: the dictionary contains vmid and bdf of audio device 423 :param audio_codec_map: the dictionary contains vmid and bdf of audio_codec device 424 """ 425 for vmid in list(audio_map.keys()): 426 bdf_audio = audio_map[vmid] 427 bdf_codec = audio_codec_map[vmid] 428 if not bdf_audio and bdf_codec: 429 key = "user_vm:id={},passthrough_devices,{}".format(vmid, 'audio_codec') 430 ERR_LIST[key] = "Audio codec device should be pass through together with Audio devcie!" 431 432 433def check_block_mount(virtio_blk_dic): 434 (blk_dev_list, num) = board_cfg_lib.get_rootfs(acrn_config_utilities.BOARD_INFO_FILE) 435 for vmid in list(virtio_blk_dic.keys()): 436 mount_flags = [] 437 for blk in virtio_blk_dic[vmid]: 438 rootfs_img = '' 439 if not blk: 440 mount_flags.append(False) 441 continue 442 443 if ':' in blk: 444 blk_dev = blk.split(':')[0] 445 rootfs_img = blk.split(':')[1] 446 else: 447 blk_dev = blk 448 449 if blk_dev in blk_dev_list and rootfs_img: 450 mount_flags.append(True) 451 else: 452 mount_flags.append(False) 453 454 MOUNT_FLAG_DIC[vmid] = mount_flags 455 456 457def check_sriov_param(sriov_dev, pt_sel): 458 for dev_type in ['gpu', 'network']: 459 for vm_id, dev_bdf in sriov_dev[dev_type].items(): 460 if not dev_bdf: 461 continue 462 pt_devname = dev_type 463 if pt_devname == 'network': 464 pt_devname = 'ethernet' 465 if pt_sel.bdf[pt_devname][vm_id]: 466 ERR_LIST[ 467 'vmid:{} sriov {}'.format(vm_id, dev_type) 468 ] = 'this vm has {} passthrough and sriov {} at same time!'.format(pt_devname, dev_type) 469 if not re.match(r'^[\da-fA-F]{2}:[0-3][\da-fA-F]\.[0-7]$', dev_bdf): 470 ERR_LIST['vmid:{} sriov {}'.format(vm_id, dev_type)] = 'sriov {} bdf error'.format(dev_type) 471 472 473def bdf_duplicate_check(bdf_dic): 474 """ 475 Check if exist duplicate slot 476 :param bdf_dic: contains all selected pass-through devices 477 :return: None 478 """ 479 bdf_used = [] 480 for dev in bdf_dic.keys(): 481 dev_bdf_dic = bdf_dic[dev] 482 for vm_i in dev_bdf_dic.keys(): 483 dev_bdf = dev_bdf_dic[vm_i] 484 if not dev_bdf: 485 continue 486 487 if dev_bdf in bdf_used: 488 key = "user_vm:id={},{},{}".format(vm_i, 'passthrough_devices', dev) 489 ERR_LIST[key] = "You select the same device for {} pass-through !".format(dev) 490 return 491 else: 492 bdf_used.append(dev_bdf) 493 494 495def get_gpu_bdf(): 496 497 pci_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PCI_DEVICE>", "</PCI_DEVICE>") 498 499 for line in pci_lines: 500 if "VGA compatible controller" in line: 501 global gpu_bdf 502 gpu_bdf = line.split('\t')[1] 503 gpu_bdf = gpu_bdf[0:7] 504 return gpu_bdf 505 506 507def get_vpid_by_bdf(bdf): 508 vpid = '' 509 vpid_lines = board_cfg_lib.get_info(acrn_config_utilities.BOARD_INFO_FILE, "<PCI_VID_PID>", "</PCI_VID_PID>") 510 511 for vpid_line in vpid_lines: 512 if bdf in vpid_line: 513 vpid = " ".join(vpid_line.split()[2].split(':')) 514 return vpid 515 516 517def get_gpu_vpid(): 518 gpu_bdf = get_gpu_bdf() 519 return get_vpid_by_bdf(gpu_bdf) 520 521 522def user_vm_cpu_affinity(user_vmid_cpu_affinity): 523 524 cpu_affinity = {} 525 sos_vm_id = get_sos_vmid() 526 for user_vmid,cpu_affinity_list in user_vmid_cpu_affinity.items(): 527 cpu_affinity[int(user_vmid) + int(sos_vm_id)] = cpu_affinity_list 528 return cpu_affinity 529 530 531def check_slot(slot_db): 532 533 slot_values = {} 534 # init list of slot values for Post VM 535 for dev in slot_db.keys(): 536 for user_vmid in slot_db[dev].keys(): 537 slot_values[user_vmid] = [] 538 break 539 540 # get slot values for Passthrough devices 541 for dev in PASSTHRU_DEVS: 542 if dev == 'gpu': 543 continue 544 for user_vmid,slot_str in slot_db[dev].items(): 545 if not slot_str: 546 continue 547 slot_values[user_vmid].append(slot_str) 548 549 # update slot values and replace the fun=0 if there is no fun 0 in bdf list 550 for dev in PASSTHRU_DEVS: 551 if dev == 'gpu': 552 continue 553 for user_vmid,slot_str in slot_db[dev].items(): 554 if not slot_str or ':' not in str(slot_str): 555 continue 556 bus_slot = slot_str[0:-1] 557 bus_slot_fun0 = bus_slot + "0" 558 if bus_slot_fun0 not in slot_values[user_vmid]: 559 slot_db[dev][user_vmid] = bus_slot_fun0 560 slot_values[user_vmid].append(bus_slot_fun0) 561 562 563def is_linux_like(user_vm_type): 564 565 is_linux = False 566 if user_vm_type in LINUX_LIKE_OS: 567 is_linux = True 568 569 return is_linux 570 571 572def set_shm_regions(launch_item_values, scenario_info): 573 574 try: 575 raw_shmem_regions = acrn_config_utilities.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_REGION") 576 load_orders = acrn_config_utilities.get_leaf_tag_map(scenario_info, "load_order") 577 shm_enabled = acrn_config_utilities.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED") 578 except: 579 return 580 581 sos_vm_id = 0 582 for vm_id,load_order in load_orders.items(): 583 if load_order in ['SERVICE_VM']: 584 sos_vm_id = vm_id 585 elif load_order in ['POST_LAUNCHED_VM']: 586 user_vmid = vm_id - sos_vm_id 587 shm_region_key = 'user_vm:id={},shm_regions,shm_region'.format(user_vmid) 588 launch_item_values[shm_region_key] = [''] 589 if shm_enabled == 'y': 590 for shmem_region in raw_shmem_regions: 591 if shmem_region is None or shmem_region.strip() == '': 592 continue 593 try: 594 shm_splited = shmem_region.split(',') 595 name = shm_splited[0].strip() 596 size = shm_splited[1].strip() 597 vm_id_list = [x.strip() for x in shm_splited[2].split(':')] 598 if str(vm_id) in vm_id_list: 599 launch_item_values[shm_region_key].append(','.join([name, size])) 600 except Exception as e: 601 print(e) 602 603 604def set_pci_vuarts(launch_item_values, scenario_info): 605 try: 606 launch_item_values['user_vm,console_vuart'] = DM_VUART0 607 load_orders = acrn_config_utilities.get_leaf_tag_map(scenario_info, 'load_order') 608 sos_vm_id = 0 609 for vm_id,load_order in load_orders.items(): 610 if load_order in ['SERVICE_VM']: 611 sos_vm_id = vm_id 612 for vm in list(acrn_config_utilities.get_config_root(scenario_info)): 613 if vm.tag == 'vm' and load_orders[int(vm.attrib['id'])] == 'POST_LAUNCHED_VM': 614 user_vmid = int(vm.attrib['id']) - sos_vm_id 615 pci_vuart_key = 'user_vm:id={},communication_vuarts,communication_vuart'.format(user_vmid) 616 for elem in list(vm): 617 if elem.tag == 'communication_vuart': 618 for sub_elem in list(elem): 619 if sub_elem.tag == 'base' and sub_elem.text == 'PCI_VUART': 620 if pci_vuart_key not in launch_item_values.keys(): 621 launch_item_values[pci_vuart_key] = ['', elem.attrib['id']] 622 else: 623 launch_item_values[pci_vuart_key].append(elem.attrib['id']) 624 except: 625 return 626 627 628def check_shm_regions(launch_shm_regions, scenario_info): 629 launch_item_values = {} 630 set_shm_regions(launch_item_values, scenario_info) 631 632 for user_vmid, shm_regions in launch_shm_regions.items(): 633 shm_region_key = 'user_vm:id={},shm_regions,shm_region'.format(user_vmid) 634 for shm_region in shm_regions: 635 if shm_region_key not in launch_item_values.keys() or shm_region not in launch_item_values[shm_region_key]: 636 ERR_LIST[shm_region_key] = "shm {} should be configured in scenario setting and the size should be decimal" \ 637 "in MB and spaces should not exist.".format(shm_region) 638 return 639 640 641def check_console_vuart(launch_console_vuart, vuart0, scenario_info): 642 vuarts = acrn_config_utilities.get_vuart_info(scenario_info) 643 644 for user_vmid, console_vuart_enable in launch_console_vuart.items(): 645 key = 'user_vm:id={},console_vuart'.format(user_vmid) 646 if console_vuart_enable == "Enable" and vuart0[user_vmid] == "Enable": 647 ERR_LIST[key] = "vuart0 and console_vuart of user_vm {} should not be enabled " \ 648 "at the same time".format(user_vmid) 649 return 650 if console_vuart_enable == "Enable" and int(user_vmid) in vuarts.keys() \ 651 and 0 in vuarts[user_vmid] and vuarts[user_vmid][0]['base'] == "INVALID_PCI_BASE": 652 ERR_LIST[key] = "console_vuart of user_vm {} should be enabled in scenario setting".format(user_vmid) 653 return 654 655 656def check_communication_vuart(launch_communication_vuarts, scenario_info): 657 vuarts = acrn_config_utilities.get_vuart_info(scenario_info) 658 vuart1_setting = acrn_config_utilities.get_vuart_info_id(acrn_config_utilities.SCENARIO_INFO_FILE, 1) 659 660 for user_vmid, vuart_list in launch_communication_vuarts.items(): 661 vuart_key = 'user_vm:id={},communication_vuarts,communication_vuart'.format(user_vmid) 662 for vuart_id in vuart_list: 663 if not vuart_id: 664 return 665 if int(vuart_id) not in vuarts[user_vmid].keys(): 666 ERR_LIST[vuart_key] = "communication_vuart {} of user_vm {} should be configured" \ 667 "in scenario setting.".format(vuart_id, user_vmid) 668 return 669 if int(vuart_id) == 1 and vuarts[user_vmid][1]['base'] != "INVALID_PCI_BASE": 670 if user_vmid in vuart1_setting.keys() and vuart1_setting[user_vmid]['base'] != "INVALID_COM_BASE": 671 ERR_LIST[vuart_key] = "user_vm {}'s communication_vuart 1 and legacy_vuart 1 should " \ 672 "not be configured at the same time.".format(user_vmid) 673 return 674 675def check_enable_ptm(launch_enable_ptm, scenario_info): 676 scenario_etree = parse(scenario_info) 677 enable_ptm_vm_list = scenario_etree.xpath("//vm[PTM = 'y']/@id") 678 for user_vmid, enable_ptm in launch_enable_ptm.items(): 679 key = 'user_vm:id={},enable_ptm'.format(user_vmid) 680 if enable_ptm == 'y' and str(user_vmid) not in enable_ptm_vm_list: 681 ERR_LIST[key] = "PTM of user_vm:{} set to 'n' in scenario xml".format(user_vmid) 682