From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by dpdk.org (Postfix) with ESMTP id F25E61B014 for ; Wed, 3 Jan 2018 05:40:14 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3665E1529; Tue, 2 Jan 2018 20:40:13 -0800 (PST) Received: from lenovo-a010984.shanghai.arm.com (lenovo-a010984.shanghai.arm.com [10.169.40.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3A15A3F24A; Tue, 2 Jan 2018 20:40:12 -0800 (PST) From: Herbert Guan To: dts@dpdk.org Cc: yong.liu@intel.com, phil.yang@arm.com, jianbo.liu@arm.com, Herbert Guan Date: Wed, 3 Jan 2018 12:40:04 +0800 Message-Id: <1514954404-26103-1-git-send-email-herbert.guan@arm.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1512452777-3982-1-git-send-email-herbert.guan@arm.com> References: <1512452777-3982-1-git-send-email-herbert.guan@arm.com> Subject: [dts] [PATCH v2] framework: enable AArch64 and add more options for libvirt X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jan 2018 04:40:15 -0000 1) Add the libvirt support on AArch64 platforms 2) Add 'loader' and 'nvram' option support in 'os' section 3) Add 'opt_bus', 'opt_dev' and 'opt_controller' option support in 'disk' section. Change 'type' to 'opt_format' to get aligined with option naming in qemu_kvm. 4) Add serial 'serial_option' option support for serial console 5) Add domain parsing in __parse_pci() 6) Function add_vm_device() uses 'opt_host' to specify PCI address Signed-off-by: Herbert Guan --- conf/vm_power_manager.cfg | 11 +++- framework/qemu_libvirt.py | 144 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 125 insertions(+), 30 deletions(-) diff --git a/conf/vm_power_manager.cfg b/conf/vm_power_manager.cfg index 9c8f87a..e2c8fc7 100644 --- a/conf/vm_power_manager.cfg +++ b/conf/vm_power_manager.cfg @@ -1,5 +1,8 @@ # libvirtd options: # [VM name] section value is the name for VM +# os +# loader: /path/to/loader/file.fd +# nvram: /path/to/nvram/file.fd # cpu # hard code type to host-passthrough # number: number of vcpus # cpupin: host cpu list @@ -7,7 +10,7 @@ # size: 4096 # disk # file: absolute path to disk image -# type: disk image format +# opt_format: [ raw | qcow2 | ... ] #disk image format # login # user: user name to login into VM # password: passwork to login into VM @@ -20,18 +23,20 @@ # vm configuration for vm power management case [vm0] +#os = +# loader=/usr/share/AAVMF/AAVMF_CODE.fd,nvram=/var/lib/libvirt/qemu/nvram/vm0_VARS.fd; cpu = number=4,cpupin=5 6 7 8; mem = size=4096; disk = - file=/storage/vm-image/vm0.img,type=raw; + file=/storage/vm-image/vm0.img,opt_format=raw; login = user=root,password=tester; [vm1] mem = size=4096; disk = - file=/storage/vm-image/vm1.img,type=raw; + file=/storage/vm-image/vm1.img,opt_format=raw; login = user=root,password=tester; diff --git a/framework/qemu_libvirt.py b/framework/qemu_libvirt.py index ed8e0e6..59a0c9e 100644 --- a/framework/qemu_libvirt.py +++ b/framework/qemu_libvirt.py @@ -57,6 +57,7 @@ class LibvirtKvm(VirtBase): # disk and pci device default index self.diskindex = 'a' + self.controllerindex = 0 self.pciindex = 10 # configure root element @@ -79,6 +80,7 @@ class LibvirtKvm(VirtBase): # internal variable to track whether default nic has been added self.__default_nic = False + self.__default_nic_pci = '' # set some default values for vm, # if there is not the values of the specified options @@ -98,6 +100,13 @@ class LibvirtKvm(VirtBase): """ check and setup host virtual ability """ + arch = self.host_session.send_expect('uname -m', '# ') + if arch == 'aarch64': + out = self.host_session.send_expect('service libvirtd status', "# ") + if 'active (running)' not in out: + return False + return True + out = self.host_session.send_expect('cat /proc/cpuinfo | grep flags', '# ') rgx = re.search(' vmx ', out) @@ -201,7 +210,31 @@ class LibvirtKvm(VirtBase): ',name=org.qemu.guest_agent.0'}) self.qga_sock_path = '/tmp/%s_qga0.sock' % self.vm_name - def set_vm_default(self): + def add_vm_os(self, **options): + os = self.domain.find('os') + if 'loader' in options.keys(): + loader = ET.SubElement( + os, 'loader', {'readonly': 'yes', 'type': 'pflash'}) + loader.text = options['loader'] + if 'nvram' in options.keys(): + nvram = ET.SubElement(os, 'nvram') + nvram.text = options['nvram'] + + + def set_vm_default_aarch64(self): + os = ET.SubElement(self.domain, 'os') + type = ET.SubElement( + os, 'type', {'arch': 'aarch64', 'machine': 'virt'}) + type.text = 'hvm' + ET.SubElement(os, 'boot', {'dev': 'hd'}) + features = ET.SubElement(self.domain, 'features') + ET.SubElement(features, 'acpi') + ET.SubElement(features, 'gic', {'version': '3'}) + + ET.SubElement(self.domain, 'cpu', + {'mode': 'host-passthrough', 'check': 'none'}) + + def set_vm_default_x86_64(self): os = ET.SubElement(self.domain, 'os') type = ET.SubElement( os, 'type', {'arch': 'x86_64', 'machine': 'pc-i440fx-1.6'}) @@ -213,6 +246,14 @@ class LibvirtKvm(VirtBase): ET.SubElement(features, 'pae') ET.SubElement(self.domain, 'cpu', {'mode': 'host-passthrough'}) + self.__default_nic_pci = '00:1f.0' + + def set_vm_default(self): + arch = self.host_session.send_expect('uname -m', '# ') + set_default_func = getattr(self, 'set_vm_default_' + arch) + if callable(set_default_func): + set_default_func() + # qemu-kvm for emulator device = ET.SubElement(self.domain, 'devices') @@ -226,7 +267,11 @@ class LibvirtKvm(VirtBase): # add default control interface if not self.__default_nic: - def_nic = {'type': 'nic', 'opt_hostfwd': '', 'opt_addr': '00:1f.0'} + if len(self.__default_nic_pci) > 0: + def_nic = {'type': 'nic', 'opt_hostfwd': '', + 'opt_addr': self.__default_nic_pci} + else: + def_nic = {'type': 'nic', 'opt_hostfwd': ''} self.add_vm_net(**def_nic) self.__default_nic = True @@ -273,17 +318,57 @@ class LibvirtKvm(VirtBase): return False ET.SubElement(disk, 'source', {'file': options['file']}) - if 'type' not in options: + if 'opt_format' not in options: disk_type = 'raw' else: - disk_type = options['type'] + disk_type = options['opt_format'] ET.SubElement(disk, 'driver', {'name': 'qemu', 'type': disk_type}) + if 'opt_bus' not in options: + bus = 'virtio' + else: + bus = options['opt_bus'] + if 'opt_dev' not in options: + dev = 'vd%c' % self.diskindex + self.diskindex = chr(ord(self.diskindex) + 1) + else: + dev = options['opt_dev'] ET.SubElement( - disk, 'target', {'dev': 'vd%c' % self.diskindex, 'bus': 'virtio'}) + disk, 'target', {'dev': dev, 'bus': bus}) + + if 'opt_controller' in options: + controller = ET.SubElement(devices, 'controller', + {'type': bus, + 'index': hex(self.controllerindex)[2:], + 'model': options['opt_controller']}) + self.controllerindex += 1 + ET.SubElement(controller, 'address', + {'type': 'pci', 'domain': '0x0000', 'bus': hex(self.pciindex), + 'slot': '0x00', 'function': '0x00'}) + self.pciindex += 1 - self.diskindex = chr(ord(self.diskindex) + 1) + def add_vm_serial_port(self, **options): + if 'enable' in options.keys(): + if options['enable'].lower() == 'yes': + devices = self.domain.find('devices') + if 'opt_type' in options.keys(): + serial_type = options['opt_type'] + else: + serial_type = 'unix' + if serial_type == 'pty': + serial = ET.SubElement(devices, 'serial', {'type': serial_type}) + ET.SubElement(serial, 'target', {'port': '0'}) + elif serial_type == 'unix': + serial = ET.SubElement(devices, 'serial', {'type': serial_type}) + self.serial_path = "/tmp/%s_serial.sock" % self.vm_name + ET.SubElement(serial, 'source', {'mode': 'bind', 'path': self.serial_path}) + ET.SubElement(serial, 'target', {'port': '0'}) + else: + print utils.RED("Serial type %s is not supported!" % serial_type) + return False + console = ET.SubElement(devices, 'console', {'type': serial_type}) + ET.SubElement(console, 'target', {'type': 'serial', 'port': '0'}) def add_vm_login(self, **options): """ @@ -305,14 +390,23 @@ class LibvirtKvm(VirtBase): def __parse_pci(self, pci_address): pci_regex = r"([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2})" + \ ".([0-9a-fA-F]{1,2})" + pci_regex_domain = r"([0-9a-fA-F]{1,4}):([0-9a-fA-F]{1,2}):" + \ + "([0-9a-fA-F]{1,2}).([0-9a-fA-F]{1,2})" m = re.match(pci_regex, pci_address) - if m is None: - return None - bus = m.group(1) - slot = m.group(2) - func = m.group(3) - - return (bus, slot, func) + if m is not None: + bus = m.group(1) + slot = m.group(2) + func = m.group(3) + dom = '0' + return (bus, slot, func, dom) + m = re.match(pci_regex_domain, pci_address) + if m is not None: + bus = m.group(2) + slot = m.group(3) + func = m.group(4) + dom = m.group(1) + return (bus, slot, func, dom) + return None def add_vm_device(self, **options): """ @@ -325,35 +419,31 @@ class LibvirtKvm(VirtBase): 'mode': 'subsystem', 'type': 'pci', 'managed': 'yes'}) - if 'pf_idx' not in options.keys(): - print utils.RED("Missing device index for device option!!!") - return False - - pf = int(options['pf_idx']) - if pf > len(self.host_dut.ports_info): - print utils.RED("PF device index over size!!!") + if 'opt_host' in options.keys(): + pci_addr = options['opt_host'] + else: + print utils.RED("Missing opt_host for device option!!!") return False - pci_addr = self.host_dut.ports_info[pf]['pci'] pci = self.__parse_pci(pci_addr) if pci is None: return False - bus, slot, func = pci + bus, slot, func, dom = pci source = ET.SubElement(hostdevice, 'source') ET.SubElement(source, 'address', { - 'domain': '0x0', 'bus': '0x%s' % bus, + 'domain': '0x%s' % dom, 'bus': '0x%s' % bus, 'slot': '0x%s' % slot, 'function': '0x%s' % func}) if 'guestpci' in options.keys(): pci = self.__parse_pci(options['guestpci']) if pci is None: return False - bus, slot, func = pci + bus, slot, func, dom = pci ET.SubElement(hostdevice, 'address', { - 'type': 'pci', 'domain': '0x0', 'bus': '0x%s' % bus, - 'slot': '0x%s' % slot, 'function': '0x%s' % func}) + 'type': 'pci', 'domain': '0x%s' % dom, 'bus': '0x%s' % bus, + 'slot': '0x%s' % slot, 'function': '0x%s' % func}) # save host and guest pci address mapping pci_map = {} pci_map['hostpci'] = pci_addr @@ -397,7 +487,7 @@ class LibvirtKvm(VirtBase): pci = self.__parse_pci(options['opt_addr']) if pci is None: return False - bus, slot, func = pci + bus, slot, func, dom = pci ET.SubElement(qemu, 'qemu:arg', {'value': 'nic,model=e1000,addr=0x%s' % slot}) else: -- 1.8.3.1