From nobody Tue Feb 10 04:23:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1680694309; cv=none; d=zohomail.com; s=zohoarc; b=FeiwSGxMa8QJUUDL6gX6aoEvF5tiK0e+kcepZ1NmCHJNAVJ8pliw3igLlW+5uObT/gTeQhEsrJDYHNn77FRYe+ja5EbAmqo0V4smzJSHg0rv8DJP0cO50/DVQ6mI9CTkbY84L8RAI1INy9K3+Qk3Sd8I+61G2njGUYGnYHBqpnw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1680694309; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9lBsrGb4mFnyekCTEjx1ysqM93R7KJ72xryAJB7TnWA=; b=mzSP0lyXnU0OetLEnB3XCzVBOV9/71YtjC9l9r8wmn2c/zbwsGlLvEmcODtFDVwzg8JZT3H6sNiipbMUyfNKVLE9Dy+2xuTjRW08WMreqIU+xVuw+f2zV8jtMNqOZEwlPyNean64UnJA9wuXjzEpNkgG3e6CmJLeQZ+4NiXzt8E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1680694309274301.5318039053402; Wed, 5 Apr 2023 04:31:49 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-300-5TZ8QPO6OMeRzm5y8XMhJA-1; Wed, 05 Apr 2023 07:31:44 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 11DEF101163D; Wed, 5 Apr 2023 11:31:42 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id EF6ED440D6; Wed, 5 Apr 2023 11:31:41 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id A443C19465B2; Wed, 5 Apr 2023 11:31:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 8338D1946587 for ; Wed, 5 Apr 2023 11:30:21 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 71F1A4020C80; Wed, 5 Apr 2023 11:30:21 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id 18DF040C6EC4 for ; Wed, 5 Apr 2023 11:30:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680694308; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=9lBsrGb4mFnyekCTEjx1ysqM93R7KJ72xryAJB7TnWA=; b=FKcPeNXxOZ95ze4aYqbK/maQch7q24ksYwH3DGvqiOiuv4/+rLOzv8QcifSbAt/gkkI9xn OqBJcvOhEOZq10O0eqGdpXjuU5lg0fe9nJIb69rcDjfFc/PretJJ5z5pq+hoQvhwJoyQrb gv79APylq0Ng3UwDrkvaVqa+jv30FhE= X-MC-Unique: 5TZ8QPO6OMeRzm5y8XMhJA-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 1/3] util: Introduce virAcpi module Date: Wed, 5 Apr 2023 13:30:17 +0200 Message-Id: <53f81bc1ffb7382ef317e3d3db34cbb4b7e57666.1680694162.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1680694311093100001 Content-Type: text/plain; charset="utf-8"; x-default="true" The aim of this new module is to contain code that's parsing ACPI tables. For now, only parsing of IORT table is implemented (it's ARM specific table). And since we only need to check whether the table contains SMMU record, the code is very simplified. I've followed the specification published here: https://developer.arm.com/documentation/den0049/latest/ Signed-off-by: Michal Privoznik --- po/POTFILES | 1 + src/libvirt_private.syms | 7 ++ src/util/meson.build | 1 + src/util/viracpi.c | 225 +++++++++++++++++++++++++++++++++++++++ src/util/viracpi.h | 23 ++++ src/util/viracpipriv.h | 59 ++++++++++ 6 files changed, 316 insertions(+) create mode 100644 src/util/viracpi.c create mode 100644 src/util/viracpi.h create mode 100644 src/util/viracpipriv.h diff --git a/po/POTFILES b/po/POTFILES index fa769a8a95..b122f02818 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -244,6 +244,7 @@ src/storage_file/storage_source.c src/storage_file/storage_source_backingstore.c src/test/test_driver.c src/util/iohelper.c +src/util/viracpi.c src/util/viralloc.c src/util/virarptable.c src/util/viraudit.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e37373c3c9..1247b67a39 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1829,6 +1829,13 @@ vir_g_strdup_printf; vir_g_strdup_vprintf; =20 =20 +# util/viracpi.c +virAcpiHasSMMU; +virAcpiParseIORT; +virIORTNodeTypeTypeFromString; +virIORTNodeTypeTypeToString; + + # util/viralloc.h virAppendElement; virDeleteElementsN; diff --git a/src/util/meson.build b/src/util/meson.build index c81500ea04..2fe6f7699e 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -1,5 +1,6 @@ util_sources =3D [ 'glibcompat.c', + 'viracpi.c', 'viralloc.c', 'virarch.c', 'virarptable.c', diff --git a/src/util/viracpi.c b/src/util/viracpi.c new file mode 100644 index 0000000000..e7d3ce2356 --- /dev/null +++ b/src/util/viracpi.c @@ -0,0 +1,225 @@ +/* + * viracpi.c: ACPI table(s) parser + * + * Copyright (C) 2023 Red Hat, 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, see + * . + */ + +#include + +#include +#include + +#define LIBVIRT_VIRACPIPRIV_H_ALLOW +#include "internal.h" +#include "viracpi.h" +#include "viracpipriv.h" +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("util.acpi"); + +typedef struct virIORTHeader virIORTHeader; +struct virIORTHeader { + uint32_t signature; + uint32_t length; + uint8_t revision; + uint8_t checksum; + char oem_id[6]; + char oem_table_id[8]; + char oem_revision[4]; + char creator_id[4]; + char creator_revision[4]; + /* Technically, the following are not part of header, but + * they immediately follow the header and are in the table + * exactly once. */ + uint32_t nnodes; + uint32_t nodes_offset; + /* Here follows reserved and padding fields. Ain't nobody's + * interested in that. */ +} ATTRIBUTE_PACKED; + +VIR_ENUM_IMPL(virIORTNodeType, + VIR_IORT_NODE_TYPE_LAST, + "ITS Group", + "Named Component", + "Root Complex", + "SMMU v1/v2", + "SMMU v3", + "PMCG", + "Memory range"); + + +static int +virAcpiParseIORTNodeHeader(int fd, + const char *filename, + virIORTNodeHeader *nodeHeader) +{ + g_autofree char *nodeHeaderBuf =3D NULL; + const char *typeStr =3D NULL; + int nodeHeaderLen; + + nodeHeaderLen =3D virFileReadHeaderFD(fd, sizeof(*nodeHeader), &nodeHe= aderBuf); + if (nodeHeaderLen < 0) { + virReportSystemError(errno, + _("cannot read node header '%1$s'"), + filename); + return -1; + } + + if (nodeHeaderLen !=3D sizeof(*nodeHeader)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("IORT table node header ended early")); + return -1; + } + + memcpy(nodeHeader, nodeHeaderBuf, nodeHeaderLen); + + typeStr =3D virIORTNodeTypeTypeToString(nodeHeader->type); + + VIR_DEBUG("IORT node header: type =3D %" PRIu8 " (%s) len =3D %" PRIu1= 6, + nodeHeader->type, typeStr, nodeHeader->len); + + /* Basic sanity check. While there's a type specific data + * that follows the node header, the node length should be at + * least size of header itself. */ + if (nodeHeader->len < sizeof(*nodeHeader)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("IORT table node type %1$s has invalid length: %2= $" PRIu16), + NULLSTR(typeStr), nodeHeader->len); + return -1; + } + + return 0; +} + + +static ssize_t +virAcpiParseIORTNodes(int fd, + const char *filename, + const virIORTHeader *header, + virIORTNodeHeader **nodesRet) +{ + g_autofree virIORTNodeHeader *nodes =3D NULL; + size_t nnodes =3D 0; + off_t pos; + + /* Firstly, reset position to the start of nodes. */ + if ((pos =3D lseek(fd, header->nodes_offset, SEEK_SET)) < 0) { + virReportSystemError(errno, + _("cannot seek in '%1$s'"), + filename); + return -1; + } + + for (; pos < header->length;) { + virIORTNodeHeader node; + + if (virAcpiParseIORTNodeHeader(fd, filename, &node) < 0) + return -1; + + if ((pos =3D lseek(fd, pos + node.len, SEEK_SET)) < 0) { + virReportSystemError(errno, + _("cannot seek in '%1$s'"), + filename); + return -1; + } + + VIR_APPEND_ELEMENT(nodes, nnodes, node); + } + + *nodesRet =3D g_steal_pointer(&nodes); + return nnodes; +} + + +ssize_t +virAcpiParseIORT(virIORTNodeHeader **nodesRet, + const char *filename) +{ + VIR_AUTOCLOSE fd =3D -1; + g_autofree char *headerBuf =3D NULL; + int headerLen; + virIORTHeader header; + + if ((fd =3D open(filename, O_RDONLY)) < 0) { + virReportSystemError(errno, + _("cannot open '%1$s'"), + filename); + return -1; + } + + headerLen =3D virFileReadHeaderFD(fd, sizeof(header), &headerBuf); + if (headerLen < 0) { + virReportSystemError(errno, + _("cannot read header '%1$s'"), + filename); + return -1; + } + + if (headerLen !=3D sizeof(header)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("IORT table header ended early")); + return -1; + } + + memcpy(&header, headerBuf, headerLen); + + VIR_DEBUG("IORT header: len =3D %" PRIu32 " revision =3D %" PRIu8 + " nnodes =3D %" PRIu32 " OEM =3D %s", + header.length, header.revision, + header.nnodes, header.oem_id); + + return virAcpiParseIORTNodes(fd, filename, &header, nodesRet); +} + + +#define IORT_PATH "/sys/firmware/acpi/tables/IORT" + +/** + * virAcpiHasSMMU: + * + * Parse IORT table trying to find SMMU node entry. + * Since IORT is ARM specific ACPI table, it doesn't make much + * sense to call this function on other platforms and expect + * sensible result. + * + * Returns: 0 if no SMMU node was found, + * 1 if a SMMU node was found (i.e. host supports SMMU), + * -1 otherwise (with error reported). + */ +int +virAcpiHasSMMU(void) +{ + g_autofree virIORTNodeHeader *nodes =3D NULL; + ssize_t nnodes =3D -1; + size_t i; + + if ((nnodes =3D virAcpiParseIORT(&nodes, IORT_PATH)) < 0) + return -1; + + for (i =3D 0; i < nnodes; i++) { + if (nodes[i].type =3D=3D VIR_IORT_NODE_TYPE_SMMU_V1_2 || + nodes[i].type =3D=3D VIR_IORT_NODE_TYPE_SMMU_V3) + return 1; + } + + return 0; +} diff --git a/src/util/viracpi.h b/src/util/viracpi.h new file mode 100644 index 0000000000..5a433b893a --- /dev/null +++ b/src/util/viracpi.h @@ -0,0 +1,23 @@ +/* + * viracpi.h: ACPI table(s) parser + * + * Copyright (C) 2023 Red Hat, 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, see + * . + */ + +#pragma once + +int virAcpiHasSMMU(void); diff --git a/src/util/viracpipriv.h b/src/util/viracpipriv.h new file mode 100644 index 0000000000..f98296632c --- /dev/null +++ b/src/util/viracpipriv.h @@ -0,0 +1,59 @@ +/* + * viracpipriv.h: Functions for testing virAcpi APIs + * + * Copyright (C) 2023 Red Hat, 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, see + * . + * + */ + +#ifndef LIBVIRT_VIRACPIPRIV_H_ALLOW +# error "viracpipriv.h may only be included by viracpi.c or test suites" +#endif /* LIBVIRT_VIRACPIPRIV_H_ALLOW */ + +#pragma once + +#include + +#include "internal.h" +#include "virenum.h" + +typedef enum { + VIR_IORT_NODE_TYPE_UNKNOWN =3D -1, + VIR_IORT_NODE_TYPE_ITS_GROUP =3D 0, + VIR_IORT_NODE_TYPE_NAMED_COMPONENT, + VIR_IORT_NODE_TYPE_ROOT_COMPLEX, + VIR_IORT_NODE_TYPE_SMMU_V1_2, + VIR_IORT_NODE_TYPE_SMMU_V3, + VIR_IORT_NODE_TYPE_PMCG, + VIR_IORT_NODE_TYPE_MEMORY_RANGE, + VIR_IORT_NODE_TYPE_LAST, +} virIORTNodeType; + +VIR_ENUM_DECL(virIORTNodeType); + +typedef struct virIORTNodeHeader virIORTNodeHeader; +struct virIORTNodeHeader { + uint8_t type; /* One of virIORTNodeType */ + uint16_t len; + uint8_t revision; + uint32_t identifier; + uint32_t nmappings; + uint32_t reference_id; +} ATTRIBUTE_PACKED; + +ssize_t +virAcpiParseIORT(virIORTNodeHeader **nodesRet, + const char *filename); --=20 2.39.2 From nobody Tue Feb 10 04:23:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1680694285; cv=none; d=zohomail.com; s=zohoarc; b=kG8EL+23iMf6BozNUf2NATbonNjyO0MhYM0SVIojtCKLfK+iM+4lnDi94HSRqrIoDqx7gv6XIqlPruJuz3zlJphsIiGBlFDS41HMZlJk6QLBt40hcTu7mu6c8Zgvqis9uJOtutz8cVX3NnUeI2sqLgjjvawGZV3ypn/aPRIRVlw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1680694285; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=MIJbG3yUGfpFriElwINxnwqKZhFGqfVaLMvAYncWWEw=; b=AuHXsinHzMr0jmc4fWmQRSC87XM/HVkTVpISn/ie080ISonwTp8BrInQKGpsrC2QZ87lVaZVWERqkoL9OFIDBVvgqYMqKoXbWQslteWrbMV6eKcf+VSvQIpleYUDXfxaU+gs2me7lRVRN8yZZZUPVBtCVk58uxXHB8XXiyNOmvE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1680694285145587.938090179439; Wed, 5 Apr 2023 04:31:25 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-108-OasSQOnQPl-CwQskd8qjfg-1; Wed, 05 Apr 2023 07:31:20 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7CBE53C0ED63; Wed, 5 Apr 2023 11:31:17 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 69A431121315; Wed, 5 Apr 2023 11:31:17 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 1E022194658F; Wed, 5 Apr 2023 11:31:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 2829F19465BB for ; Wed, 5 Apr 2023 11:30:22 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 0DA244020C82; Wed, 5 Apr 2023 11:30:22 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id A944A40C6EC4 for ; Wed, 5 Apr 2023 11:30:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680694284; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=MIJbG3yUGfpFriElwINxnwqKZhFGqfVaLMvAYncWWEw=; b=GOpH9SiWWSGe391MjIkmjisxmWB95hn6GcujqygcDQt+tDRDXFlOWE1IONAhLg467EpYhR ehwao0Kvq0au1pNB9PtpmbruDjfX98+/hesWJDyqXIIW8xxmfDnr1/EgWHgz/iWpacJ8tp tHOX/mRh4fcuvMT/xodLh1wsOz0OBjA= X-MC-Unique: OasSQOnQPl-CwQskd8qjfg-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 2/3] tests: Introduce viracpitest Date: Wed, 5 Apr 2023 13:30:18 +0200 Message-Id: <15ac02742776fc499d35a2533ee70a3d0d31e2da.1680694162.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1680694286733100001 Content-Type: text/plain; charset="utf-8"; x-default="true" Introduce a test that checks newly introduced virArch module. There are three IORT tables from a real HW (IORT_ampere, IORT_gigabyte and IORT_qualcom), then there's one from a VM (IORT_virt_aarch64) and one that I handcrafted to be empty (IORT_empty). Signed-off-by: Michal Privoznik --- build-aux/syntax-check.mk | 2 +- tests/meson.build | 1 + tests/viracpidata/IORT_ampere | Bin 0 -> 2304 bytes tests/viracpidata/IORT_empty | Bin 0 -> 65 bytes tests/viracpidata/IORT_gigabyte | Bin 0 -> 10100 bytes tests/viracpidata/IORT_qualcom | Bin 0 -> 3560 bytes tests/viracpidata/IORT_virt_aarch64 | Bin 0 -> 128 bytes tests/viracpitest.c | 135 ++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 tests/viracpidata/IORT_ampere create mode 100644 tests/viracpidata/IORT_empty create mode 100644 tests/viracpidata/IORT_gigabyte create mode 100644 tests/viracpidata/IORT_qualcom create mode 100644 tests/viracpidata/IORT_virt_aarch64 create mode 100644 tests/viracpitest.c diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk index 5829dc9011..64c1e2773e 100644 --- a/build-aux/syntax-check.mk +++ b/build-aux/syntax-check.mk @@ -1370,7 +1370,7 @@ exclude_file_name_regexp--sc_prohibit_close =3D \ (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/vir(file|event)\.c|src/libvirt= -stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c)|tools/= nss/libvirt_nss_(leases|macs)\.c)|tools/virt-qemu-qmp-proxy$$) =20 exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF =3D \ - (^tests/(nodedevmdevctl|virhostcpu|virpcitest|virstoragetest)data/|docs/= js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$) + (^tests/(nodedevmdevctl|viracpi|virhostcpu|virpcitest|virstoragetest)dat= a/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.= conf$$) =20 exclude_file_name_regexp--sc_prohibit_fork_wrappers =3D \ (^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)= \.c$$) diff --git a/tests/meson.build b/tests/meson.build index 24d08e4f97..35adbc2d56 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -269,6 +269,7 @@ tests +=3D [ { 'name': 'storagevolxml2xmltest' }, { 'name': 'sysinfotest' }, { 'name': 'utiltest' }, + { 'name': 'viracpitest' }, { 'name': 'viralloctest' }, { 'name': 'virauthconfigtest' }, { 'name': 'virbitmaptest' }, diff --git a/tests/viracpidata/IORT_ampere b/tests/viracpidata/IORT_ampere new file mode 100644 index 0000000000000000000000000000000000000000..02e7fd98499729025346c6ac3ae= 5cf10b0f1074d GIT binary patch literal 2304 zcmbW1y-EW?6opUzV}1)8%LN4mK`kr-7P4TWg&4%rLXlu$Lg$lfAhAGcZwV=3D;3b8Z6<$$zRpB*-Hx%AfcuV1Jg?AL*&3Um09*JpqZe{?O zqhNo2j#YGkfFbw)ib1ii+>)bWKJ0S3tjuMt`ZLaZB1OlRM%>(tBecBB}{d#$GR#QJ1$|W zYctkW#f#$-rnUxTGHSy)RgsHBpSXT>E n$0ba4UB|lGsLR0_qjZI-uA5j_2Z`enrn>H8U0w7XmoVaAS)q0T literal 0 HcmV?d00001 diff --git a/tests/viracpidata/IORT_empty b/tests/viracpidata/IORT_empty new file mode 100644 index 0000000000000000000000000000000000000000..58b696fe935b432020377aabc76= fe2b95376b48f GIT binary patch literal 65 ucmebD4+?Q$U|?Y6a`g=3DeiDdBcbPDqf3SnRbih&p)8U!4`B$SXqaJT?S&j#KA literal 0 HcmV?d00001 diff --git a/tests/viracpidata/IORT_gigabyte b/tests/viracpidata/IORT_gigab= yte new file mode 100644 index 0000000000000000000000000000000000000000..b18b445b5de0911ba7190dfe396= a72fec3fe6cf5 GIT binary patch literal 10100 zcmeI1OHRWu5Qg2REq(9^AS76TA~tNhV95qiBr266RV`x4f;U?ZP>CaO1rESrH~oNhgq5>JSK2mi4?O{V>;(fI91sY?6o^twN}9A8X^z4OscMJd%Ejt6^< zo$Nrz$NF$>*F_2;#-b&+H51}AsNpZVy_<6t=3Deh}%I??@99|OL|*gKAGch71O=3Dh`F3(vuP5gZKakV%Y~+ zD>13!@}VLoSw2~g{cuiHq~RfsV@ z(9PynpX+p8l*6sikW!lF5}Hcb3_`W*WeOMOMwNiSS{Sk4Ei zh>1=3D0y-jlzF_BX_$HZUO_?VOiGD+%l0c?$20f;fCe6|Kc$o$AQtESLYAp2^S*N^jIFPpwaF5v64&vo11iD#Xe(lq> zk4fD?CP{scJdCCOBI}g*4F~e}0qzlBIzdcYgFrXSq~0N27v*r9G^CVfYY7d1;x0Vr E57fpI9{>OV literal 0 HcmV?d00001 diff --git a/tests/viracpidata/IORT_qualcom b/tests/viracpidata/IORT_qualcom new file mode 100644 index 0000000000000000000000000000000000000000..5364a9968fa024f34b5e911513a= 08e8a7f88cf91 GIT binary patch literal 3560 zcmb7_yK7WI6vk)w?gfdc+XO5}jbI^i_hDy|WN$P9V~9y%A;c$GhzN?HK?NJFM9@YX zTmKYG!TbS&7AXbo*Yn+ZoZX!D-Z=3Dxi^Z3p;bLMyV++Eway1jqI7;|ZJw6SjOW_htc zEDGDArL`;Dm*?|&yF%lFK2~PpYhnO$Ma|k4ZC3tC?blad8 z)4JsI;{czZk6z#9bS9q`KM%?s_r`81d;+7u=3Dbm2>_cy;HAH)c~+o0P9y_nV| zpWg@g{E2*C5tCid<@HQHZNUe-rSS3FnZW0bUl8{A zSHEb~7tPV$Qa;ap-tT=3Ds{oFIb2fL;4$=3Dnf<&lkTS?r-+0eBROdh!HyKi}L-ij{2(8 zQC}0fv9_<$8e|24;sU28c=3DX_M*3CwBCO7w$aiFLPc} zdztgH+RL0rYAa?~@eq_}=3D!+#oS-SQ~fN<#%m$R3ygL--Gw7zX!(+%s=3D~I BN)P}5 literal 0 HcmV?d00001 diff --git a/tests/viracpidata/IORT_virt_aarch64 b/tests/viracpidata/IORT_v= irt_aarch64 new file mode 100644 index 0000000000000000000000000000000000000000..7efd0ce8a6b3928efa7e1373f68= 8ab4c5f50543b GIT binary patch literal 128 zcmebD4+?2uU|?Y0?Bwt45v<@85#X!<1dKp25F11@0kHuPgMkDCNC*yK93~3}W)K^M VRiHGGVg_O`aDdYP|3ers^8jQz3IPBB literal 0 HcmV?d00001 diff --git a/tests/viracpitest.c b/tests/viracpitest.c new file mode 100644 index 0000000000..c34abec47b --- /dev/null +++ b/tests/viracpitest.c @@ -0,0 +1,135 @@ +/* + * viracpitest.c: Test ACPI table parsing + * + * Copyright (C) 2023 Red Hat, 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, see + * . + * + */ + +#include + +#define LIBVIRT_VIRACPIPRIV_H_ALLOW +#include "testutils.h" +#include "viracpi.h" +#include "viracpipriv.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +typedef struct testAarch64SMMUData testAarch64SMMUData; +struct testAarch64SMMUData { + const char *filename; + ssize_t nnodes; + const virIORTNodeType *node_types; +}; + +static void +printBitmap(virBitmap *types) +{ + size_t i; + + for (i =3D 0; i < VIR_IORT_NODE_TYPE_LAST; i++) { + if (virBitmapIsBitSet(types, i)) { + fprintf(stderr, "%s\n", virIORTNodeTypeTypeToString(i)); + } + } +} + +static int +testAarch64SMMU(const void *opaque) +{ + const testAarch64SMMUData *data =3D opaque; + g_autofree char *path =3D NULL; + g_autofree virIORTNodeHeader *nodes =3D NULL; + ssize_t nnodes =3D 0; + + path =3D g_strdup_printf("%s/viracpidata/%s", + abs_srcdir, data->filename); + + nnodes =3D virAcpiParseIORT(&nodes, path); + + if (nnodes !=3D data->nnodes) { + fprintf(stderr, + "virAcpiParseIORT() returned wrong number of nodes: %zd, e= xpected %zd\n", + nnodes, data->nnodes); + return -1; + } + + if (nnodes > 0) { + g_autoptr(virBitmap) typesSeen =3D virBitmapNew(VIR_IORT_NODE_TYPE= _LAST); + g_autoptr(virBitmap) typesExp =3D virBitmapNew(VIR_IORT_NODE_TYPE_= LAST); + size_t i =3D 0; + + for (i =3D 0; data->node_types[i] !=3D VIR_IORT_NODE_TYPE_LAST; i+= +) { + size_t type =3D data->node_types[i]; + + ignore_value(virBitmapSetBit(typesExp, type)); + } + + for (i =3D 0; i < nnodes; i++) { + virIORTNodeHeader *h =3D &nodes[i]; + + ignore_value(virBitmapSetBit(typesSeen, h->type)); + } + + if (!virBitmapEqual(typesSeen, typesExp)) { + fprintf(stderr, "node types mismatch.\n\nExpected:\n"); + printBitmap(typesExp); + fprintf(stderr, "\nActual:\n"); + printBitmap(typesSeen); + return -1; + } + } + + return 0; +} + + +static int +mymain(void) +{ + int ret =3D 0; + +#define DO_TEST(filename, nnodes, ...) \ + do { \ + const virIORTNodeType node_types[] =3D { __VA_ARGS__, VIR_IORT_NOD= E_TYPE_LAST }; \ + const testAarch64SMMUData data =3D {filename, nnodes, node_types }= ; \ + if (virTestRun("aarch64 SMMU " filename, testAarch64SMMU, &data) <= 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST("IORT_empty", 0, VIR_IORT_NODE_TYPE_LAST); + DO_TEST("IORT_virt_aarch64", 2, + VIR_IORT_NODE_TYPE_ITS_GROUP, + VIR_IORT_NODE_TYPE_ROOT_COMPLEX); + DO_TEST("IORT_ampere", 36, + VIR_IORT_NODE_TYPE_ITS_GROUP, + VIR_IORT_NODE_TYPE_ROOT_COMPLEX, + VIR_IORT_NODE_TYPE_SMMU_V3); + DO_TEST("IORT_gigabyte", 30, + VIR_IORT_NODE_TYPE_ITS_GROUP, + VIR_IORT_NODE_TYPE_ROOT_COMPLEX, + VIR_IORT_NODE_TYPE_SMMU_V1_2); + DO_TEST("IORT_qualcom", 69, + VIR_IORT_NODE_TYPE_ITS_GROUP, + VIR_IORT_NODE_TYPE_NAMED_COMPONENT, + VIR_IORT_NODE_TYPE_ROOT_COMPLEX, + VIR_IORT_NODE_TYPE_SMMU_V3, + VIR_IORT_NODE_TYPE_PMCG); + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN(mymain) --=20 2.39.2 From nobody Tue Feb 10 04:23:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1680694231; cv=none; d=zohomail.com; s=zohoarc; b=b4kSmn4kTS2jkACGAZNQo4DImwxCu/YmfzMFMZihFTdOmsiSZCQMWq8u9bnVKBbDULJvF53kGn18N/HZ3KYXOKOEid2ST5yqDDPgb8ErukV5iPU3VCBqQ2C+PsvlEGXMOk10l+zenB5e9OLDDRqiXG8dPxYPYbjhBKe+0q4gmd4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1680694231; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=qmqeQgZVSGCeoCF9D47z51O2e3vsptM4qytS/9oRPxE=; b=SjIA7bsHuswSJ8osf8PPJDKo4WKVQWvWiuOcBs0uGCDC9lmR/c6KwgebVfyjdclOA0KbkbSsO5b+W2SNmabSH0vlwy5qp9WguU6nhiUFnMJxPyFM684PXkIb6MdwyM2K68Im94vCG9UJyb+9OJQZnGMoUGFCnplEoCTmmiwLVDw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1680694231323604.3895418327947; Wed, 5 Apr 2023 04:30:31 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-615-zEN6CsFsOeSXW9dZSRCwaw-1; Wed, 05 Apr 2023 07:30:27 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2B331101A531; Wed, 5 Apr 2023 11:30:25 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7B77440C6EC4; Wed, 5 Apr 2023 11:30:23 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 383C01946595; Wed, 5 Apr 2023 11:30:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id AB3F41946587 for ; Wed, 5 Apr 2023 11:30:22 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 9D77F4020C82; Wed, 5 Apr 2023 11:30:22 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id 44D6F40C6EC4 for ; Wed, 5 Apr 2023 11:30:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680694230; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=qmqeQgZVSGCeoCF9D47z51O2e3vsptM4qytS/9oRPxE=; b=OJIYAgRwj61TitpF2tJq5RHaAxaZvY4qCigHQ7+gHuxZaQgUtKU/Idn6ln19FfIM9OalVN NA+tjWh/3zT5WabbzcVYtSkSvxHtIF74X+WAcpKVXoETsJZvbKI/nDpB4CDp2qM6UHfrp4 CPTsG87i2hSQbr46Yb8sPLSO17bW1Tw= X-MC-Unique: zEN6CsFsOeSXW9dZSRCwaw-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 3/3] virt-host-validate: Detect SMMU presence on ARMs by parsing IORT table Date: Wed, 5 Apr 2023 13:30:19 +0200 Message-Id: <061a2ecf513a25e4e264c89424775ef75255c976.1680694162.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1680694231824100001 Content-Type: text/plain; charset="utf-8"; x-default="true" In my previous commit v9.2.0-rc1~3 I've made virt-host-validate to report host IOMMU check pass if IORT table is present. This is not sufficient though, because IORT describes much more than just IOMMU (well, it's called SMMU in ARM world). In fact, this can be seen in previous commit which adds test cases: there are tables (IORT_virt_aarch64) which does not contain any SMMU records. But after previous commits, we can parse the table so switch to that. Fixes: 2c13a2a7c9c368ea81eccd4ba12d9cf34bdd331b Signed-off-by: Michal Privoznik --- tools/virt-host-validate-common.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-c= ommon.c index e96986bb48..c8a23e2e99 100644 --- a/tools/virt-host-validate-common.c +++ b/tools/virt-host-validate-common.c @@ -26,6 +26,7 @@ #include #include =20 +#include "viracpi.h" #include "viralloc.h" #include "vircgroup.h" #include "virfile.h" @@ -389,13 +390,24 @@ int virHostValidateIOMMU(const char *hvname, } virHostMsgPass(); } else if (ARCH_IS_ARM(arch)) { - if (access("/sys/firmware/acpi/tables/IORT", F_OK) =3D=3D 0) { - virHostMsgPass(); - } else { + if (access("/sys/firmware/acpi/tables/IORT", F_OK) !=3D 0) { virHostMsgFail(level, "No ACPI IORT table found, IOMMU not " "supported by this hardware platform"); return VIR_HOST_VALIDATE_FAILURE(level); + } else { + rc =3D virAcpiHasSMMU(); + if (rc < 0) { + virHostMsgFail(level, + "Failed to parse ACPI IORT table"); + return VIR_HOST_VALIDATE_FAILURE(level); + } else if (rc =3D=3D 0) { + virHostMsgFail(level, + "No SMMU found"); + return VIR_HOST_VALIDATE_FAILURE(level); + } else { + virHostMsgPass(); + } } } else { virHostMsgFail(level, --=20 2.39.2