From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71C91C433F5 for ; Wed, 13 Apr 2022 17:59:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232386AbiDMSCQ (ORCPT ); Wed, 13 Apr 2022 14:02:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237547AbiDMSCM (ORCPT ); Wed, 13 Apr 2022 14:02:12 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 046123CFD1 for ; Wed, 13 Apr 2022 10:59:50 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id x7-20020a056902050700b00641671dc5d0so2266544ybs.18 for ; Wed, 13 Apr 2022 10:59:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kJgMoCAjhZF08CgV3+jJ2ov9zdWBjUSyLPZfA15qjOk=; b=KggzFVdxeoQg0dg+xCFerVmln70DhOirzJQH9b1+gcRB0aoPmOowDWXYaW4JNLhTAf fEzzgwRI27LnMa+AC7ayiTD9id5tigrXxr8Hn95S734FE6qQgRsnvRGxl06Y1SKvGncV 8SYJtPiHQLszFDpR1lAz0yvFHC21ZIJl/5yYG7LpGaiRRX4AIpqc7iXqFEfgG2qSxXAV jFiIJxPadIAvzVoXx7tfMP/flZYRkKUVmklo0N/Vr8VnWNR2sh8eYcDtD2cogmaDs5eG z2qPB7Als5U9dO8oF7RYzYfNde+sgAs6n6dzYGqwXLvNmlThh7/daEbwBRzzVugoPWIF 70FA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kJgMoCAjhZF08CgV3+jJ2ov9zdWBjUSyLPZfA15qjOk=; b=7c8jchpgKHIjbE3OorujB6hMVY47N4qH0BRIO+FkWr1ppzcFqHh9UzIKCN6JVNMY6l V2cqn7ZeolZLYd1gnzi/A+HaeY2wMbvpXvpbmppIbiVN0aNUgEU2TkB4dajelaRPa4F7 sDlvlxMq8R5Ex5TBJyY/5XnBXmMOyhxJYmQWlcEIHy8dGgkdcqeTg80iDwhN+YP36YoR H7OlOtseAwJNmt3fc3bo4d7SE+P+C3SQVabA2dSgs7cvGzf4PLtH1J5cMCzV/RBoIemy sA73Fuu9AL02mvl9zkkmN7+kU9BtpaKhkEPyFdX4hkqeitHkDSQ+v3rT4Wvr680cEO9r /Ylw== X-Gm-Message-State: AOAM531fl4zvd2+4UYPWWMJ+DjBS0yjkXrI/urvUm3o8cZgqHYj9ulYs 6uFNw83a2f+NBpqVXCawjiT6yP3zJSQ8AFl9HxMcw36ulT4XBN5E6d3ebGA0FVGsWGKrtaclIan ELV7AlDaGUr5fF3WCwRhIxMNun6MtQeGpV7x+9ayZX0INEH39RTdvxyRSzv6ogr9Uxpxzr/E6 X-Google-Smtp-Source: ABdhPJxN2eJeLSvaFNqx2VGfAZIffbfLWeE5kC9d2iePwu7oo1zNXRPm5PthuTpaymrUQi70C7kyooloY6IU X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a25:84c3:0:b0:641:63ae:8688 with SMTP id x3-20020a2584c3000000b0064163ae8688mr96300ybm.148.1649872789160; Wed, 13 Apr 2022 10:59:49 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:35 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-2-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 01/10] KVM: selftests: Remove dynamic memory allocation for stats header From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There's no need to allocate dynamic memory for the stats header since its size is known at compile time. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/kvm_binary_stats_test.c | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index 17f65d514915..dad34d8a41fe 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -26,56 +26,53 @@ static void stats_test(int stats_fd) int i; size_t size_desc; size_t size_data =3D 0; - struct kvm_stats_header *header; + struct kvm_stats_header header; char *id; struct kvm_stats_desc *stats_desc; u64 *stats_data; struct kvm_stats_desc *pdesc; =20 /* Read kvm stats header */ - header =3D malloc(sizeof(*header)); - TEST_ASSERT(header, "Allocate memory for stats header"); - - ret =3D read(stats_fd, header, sizeof(*header)); - TEST_ASSERT(ret =3D=3D sizeof(*header), "Read stats header"); - size_desc =3D sizeof(*stats_desc) + header->name_size; + ret =3D read(stats_fd, &header, sizeof(header)); + TEST_ASSERT(ret =3D=3D sizeof(header), "Read stats header"); + size_desc =3D sizeof(*stats_desc) + header.name_size; =20 /* Read kvm stats id string */ - id =3D malloc(header->name_size); + id =3D malloc(header.name_size); TEST_ASSERT(id, "Allocate memory for id string"); - ret =3D read(stats_fd, id, header->name_size); - TEST_ASSERT(ret =3D=3D header->name_size, "Read id string"); + ret =3D read(stats_fd, id, header.name_size); + TEST_ASSERT(ret =3D=3D header.name_size, "Read id string"); =20 /* Check id string, that should start with "kvm" */ - TEST_ASSERT(!strncmp(id, "kvm", 3) && strlen(id) < header->name_size, + TEST_ASSERT(!strncmp(id, "kvm", 3) && strlen(id) < header.name_size, "Invalid KVM stats type, id: %s", id); =20 /* Sanity check for other fields in header */ - if (header->num_desc =3D=3D 0) { + if (header.num_desc =3D=3D 0) { printf("No KVM stats defined!"); return; } /* Check overlap */ - TEST_ASSERT(header->desc_offset > 0 && header->data_offset > 0 - && header->desc_offset >=3D sizeof(*header) - && header->data_offset >=3D sizeof(*header), + TEST_ASSERT(header.desc_offset > 0 && header.data_offset > 0 + && header.desc_offset >=3D sizeof(header) + && header.data_offset >=3D sizeof(header), "Invalid offset fields in header"); - TEST_ASSERT(header->desc_offset > header->data_offset || - (header->desc_offset + size_desc * header->num_desc <=3D - header->data_offset), + TEST_ASSERT(header.desc_offset > header.data_offset || + (header.desc_offset + size_desc * header.num_desc <=3D + header.data_offset), "Descriptor block is overlapped with data block"); =20 /* Allocate memory for stats descriptors */ - stats_desc =3D calloc(header->num_desc, size_desc); + stats_desc =3D calloc(header.num_desc, size_desc); TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); /* Read kvm stats descriptors */ ret =3D pread(stats_fd, stats_desc, - size_desc * header->num_desc, header->desc_offset); - TEST_ASSERT(ret =3D=3D size_desc * header->num_desc, + size_desc * header.num_desc, header.desc_offset); + TEST_ASSERT(ret =3D=3D size_desc * header.num_desc, "Read KVM stats descriptors"); =20 /* Sanity check for fields in descriptors */ - for (i =3D 0; i < header->num_desc; ++i) { + for (i =3D 0; i < header.num_desc; ++i) { pdesc =3D (void *)stats_desc + i * size_desc; /* Check type,unit,base boundaries */ TEST_ASSERT((pdesc->flags & KVM_STATS_TYPE_MASK) @@ -104,7 +101,7 @@ static void stats_test(int stats_fd) break; } /* Check name string */ - TEST_ASSERT(strlen(pdesc->name) < header->name_size, + TEST_ASSERT(strlen(pdesc->name) < header.name_size, "KVM stats name(%s) too long", pdesc->name); /* Check size field, which should not be zero */ TEST_ASSERT(pdesc->size, "KVM descriptor(%s) with size of 0", @@ -124,14 +121,14 @@ static void stats_test(int stats_fd) size_data +=3D pdesc->size * sizeof(*stats_data); } /* Check overlap */ - TEST_ASSERT(header->data_offset >=3D header->desc_offset - || header->data_offset + size_data <=3D header->desc_offset, + TEST_ASSERT(header.data_offset >=3D header.desc_offset + || header.data_offset + size_data <=3D header.desc_offset, "Data block is overlapped with Descriptor block"); /* Check validity of all stats data size */ - TEST_ASSERT(size_data >=3D header->num_desc * sizeof(*stats_data), + TEST_ASSERT(size_data >=3D header.num_desc * sizeof(*stats_data), "Data size is not correct"); /* Check stats offset */ - for (i =3D 0; i < header->num_desc; ++i) { + for (i =3D 0; i < header.num_desc; ++i) { pdesc =3D (void *)stats_desc + i * size_desc; TEST_ASSERT(pdesc->offset < size_data, "Invalid offset (%u) for stats: %s", @@ -142,15 +139,15 @@ static void stats_test(int stats_fd) stats_data =3D malloc(size_data); TEST_ASSERT(stats_data, "Allocate memory for stats data"); /* Read kvm stats data as a bulk */ - ret =3D pread(stats_fd, stats_data, size_data, header->data_offset); + ret =3D pread(stats_fd, stats_data, size_data, header.data_offset); TEST_ASSERT(ret =3D=3D size_data, "Read KVM stats data"); /* Read kvm stats data one by one */ size_data =3D 0; - for (i =3D 0; i < header->num_desc; ++i) { + for (i =3D 0; i < header.num_desc; ++i) { pdesc =3D (void *)stats_desc + i * size_desc; ret =3D pread(stats_fd, stats_data, pdesc->size * sizeof(*stats_data), - header->data_offset + size_data); + header.data_offset + size_data); TEST_ASSERT(ret =3D=3D pdesc->size * sizeof(*stats_data), "Read data of KVM stats: %s", pdesc->name); size_data +=3D pdesc->size * sizeof(*stats_data); @@ -159,7 +156,6 @@ static void stats_test(int stats_fd) free(stats_data); free(stats_desc); free(id); - free(header); } =20 =20 --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94EE0C433EF for ; Wed, 13 Apr 2022 18:00:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237577AbiDMSCU (ORCPT ); Wed, 13 Apr 2022 14:02:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237557AbiDMSCN (ORCPT ); Wed, 13 Apr 2022 14:02:13 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67D7935DE1 for ; Wed, 13 Apr 2022 10:59:51 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id q1-20020a17090a2dc100b001cba43e127dso1669423pjm.9 for ; Wed, 13 Apr 2022 10:59:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Qmx8EsRrZbSQNFkjDz/mX7u6vKF72QcXgkibsLvEgdA=; b=nmgQIt8HDpFZHnZ2oPMbra7J/K4/W71WPYEYyeS9mh5TjtHyShK2YeCBkC6W1Otzxr Ctw+/9VvksAVw8ge5jYnkdStPnpK0MrCb1XqqPJO8Ytv23VUAclvZVCW0bYNgsaVZgMA JGyLExmZ+P40TRdtd3HNQNGM/ZeKFjwHbgZBTYItKOJlE7vdLmknJKf+x/sIjpFKxpil mjkcwycQj5zTRjLi0oCWpwvunMjgjzxPh3xPu1Wraby0ZiS5Oh5KWZlIzcgBXUqHft3x pyYSyvO9HVwOG1zOIMWkBLG5wz2vmavUaxp7FYbtSThCvtuMviX32nXluiS24yDwu4ss adug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Qmx8EsRrZbSQNFkjDz/mX7u6vKF72QcXgkibsLvEgdA=; b=jrzugrhKcY1xTzz8TeTUgDsh52QnjYWIyFT0jrcSjPDYqQrOuBHdgheePZCeTzW2LH kusR+qrri6Ka8Zk9zhd7QXgOhBQHnX3qsGoNe8rt8/BIgllFSSN59stueNc0nDatm3Zp WIOp3ISJfXOdeumLsyipDyI8ipYqK3rjLm8zaoRXzHyDc6oCtuvLAie+tiGBAT4fYZVm JLhiTnF1hhcKdjVPY3zmuR9II1H9ubmWCXvo+9jHf72lgWftLX+BUV28Sw5NHEkyHn0s AjhkFyWL8h1vGgeMXoGq5XZq9cJdfBDdohiPIgtOC9uBwvwRM5xj1AYqABCWsGB4+qoE P0Ow== X-Gm-Message-State: AOAM531b2Dy8TtXSPFTh9u5sif424vNAjOS38BDCiW0QUM4wFCwREK+t 3umg6THR+dJi0+te+rKINoSszRfM/BMzEw8e+LBznC276oRKsyl938a/eElX5/AWWOakV7YCNmI ZwjW8cKPo/rcWSgTflex1iQP++iqcmw8wgJVfcsnJ9C6NmaKyzYG9Vq0WMfeYQCX15n9qadmJ X-Google-Smtp-Source: ABdhPJxW4HDO9a7kQpk2ZBV4ljZgFCpWEuHwGotU1wRE4n+U4XpQJIlPZgmdYCir/GPQLu47qXd2QJLyb087 X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a05:6a00:1a06:b0:4fc:d6c5:f3d7 with SMTP id g6-20020a056a001a0600b004fcd6c5f3d7mr44462916pfv.53.1649872790687; Wed, 13 Apr 2022 10:59:50 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:36 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-3-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 02/10] KVM: selftests: Read binary stats header in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the code to read the binary stats header to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/include/kvm_util_base.h | 1 + .../selftests/kvm/kvm_binary_stats_test.c | 4 ++-- tools/testing/selftests/kvm/lib/kvm_util.c | 21 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 92cef0ffb19e..749cded9b157 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -400,6 +400,7 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, u= int32_t vcpuid); =20 int vm_get_stats_fd(struct kvm_vm *vm); int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid); +void read_stats_header(int stats_fd, struct kvm_stats_header *header); =20 uint32_t guest_get_vcpuid(void); =20 diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index dad34d8a41fe..fb511b42a03e 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -33,8 +33,8 @@ static void stats_test(int stats_fd) struct kvm_stats_desc *pdesc; =20 /* Read kvm stats header */ - ret =3D read(stats_fd, &header, sizeof(header)); - TEST_ASSERT(ret =3D=3D sizeof(header), "Read stats header"); + read_stats_header(stats_fd, &header); + size_desc =3D sizeof(*stats_desc) + header.name_size; =20 /* Read kvm stats id string */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 1665a220abcb..1d75d41f92dc 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2556,3 +2556,24 @@ int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vc= puid) =20 return ioctl(vcpu->fd, KVM_GET_STATS_FD, NULL); } + +/* + * Read binary stats header + * + * Input Args: + * stats_fd - the file descriptor for the binary stats file from which t= o read + * + * Output Args: + * header - a binary stats metadata header to be filled with data + * + * Return: void + * + * Read a header for the binary stats interface. + */ +void read_stats_header(int stats_fd, struct kvm_stats_header *header) +{ + ssize_t ret; + + ret =3D read(stats_fd, header, sizeof(*header)); + TEST_ASSERT(ret =3D=3D sizeof(*header), "Read stats header"); +} --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43557C433FE for ; Wed, 13 Apr 2022 18:00:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237590AbiDMSCX (ORCPT ); Wed, 13 Apr 2022 14:02:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237562AbiDMSCR (ORCPT ); Wed, 13 Apr 2022 14:02:17 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A6BB3EF3D for ; Wed, 13 Apr 2022 10:59:53 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id h14-20020a63530e000000b0039daafb0a84so1474037pgb.7 for ; Wed, 13 Apr 2022 10:59:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=jzWTSrObuuzchukDU3ZKJCOBHTggGHOLs/QEIhTLeaQ=; b=T7ff8Gw7EbvMO/RhGeZnSOV5XVRiNFOL3VC6qOIFpQq4ZrTBsrg5GpBZuyOEGQ1RIy Uf4/3LXk/fi/yAaRAsABMNt0a+oizpcd31KwOjIZgXlX1Lsu8/tY15pVm9A3N27cftnM jMWtJDOw8BlP4/xrMRmWpzd9rF+C3Ll3SFgjNOUPSYLr4jT9dcwhvf6oXLcrsSas2kHl cnp17MBxNHyYYjVh3lzPPPvsZGbKtqqxT1kG7AIsEfTXxyJcPRCCbrHlFn/SvuXGzT8U iNPaf8Mzqei2a63o4/Gw7/RrSCGv1sBd0VbpvFvwodDJdCxgdG5mfJAdILRPmRGdFPY2 4CGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=jzWTSrObuuzchukDU3ZKJCOBHTggGHOLs/QEIhTLeaQ=; b=iNXbGfNvsk1RoEUtsE83U90Id3N4AV6SwOSEFIH9qQA9fiiO5mTkkI+f5eCfEUeWwV QF80gIXb+YuDfHTSNJnfhU3CCJZ5tLmeB7CVW9SlTRAZl14WJkSE5aS1rbEQMpGmryyT 1uEUTubKdGjbxdXsH1NVuopJuYmLfi77FbkbLEGSqCr9ogUVo/JmOa/hyCWoIUvClP+j ujL1i35Q0IcH+ObV4MGwafoXHwF80clJCxMs6mL+b3OvIJZzv7fG+gG4kfy6F9EIs5sV PhEM7D33a03cHrrwiImTjwJpjZYow6KJ3xcw2jNJqjoxSaEr/07kHkp/9VfNBGk/xtbj nwMg== X-Gm-Message-State: AOAM533OIt/qG5RGsX6eJCT0hM9LBBGu3uer0xF5KCMsRT5VZFXcCPgm JRn9fMQgw6+nehPrXUcoExxNwAlVYg0a5CYzz23QUkJl/yFbkJheBtK6hmmcooJOf7NKQj2y64n yF/dB4T1ppUUwA5feZn2fVpar9bJWQZWJB1X/ni6J/IgFBoTxhB8wWYrQDMzxTTBFyk2cgdGm X-Google-Smtp-Source: ABdhPJw+1qz0wZbwekQ/1LYTZd61Pfe06F/KlYdFMslqEcJtAZD5QtALlGE+CSoEfB149VvN++QbigBl0GD2 X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a05:6a00:3309:b0:505:ffd5:f146 with SMTP id cq9-20020a056a00330900b00505ffd5f146mr11833pfb.60.1649872792570; Wed, 13 Apr 2022 10:59:52 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:37 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-4-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 03/10] KVM: selftests: Read binary stats desc in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the code to read the binary stats descriptors to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/include/kvm_util_base.h | 2 + .../selftests/kvm/kvm_binary_stats_test.c | 8 +--- tools/testing/selftests/kvm/lib/kvm_util.c | 38 +++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 749cded9b157..fabe46ddc1b2 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -401,6 +401,8 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, u= int32_t vcpuid); int vm_get_stats_fd(struct kvm_vm *vm); int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid); void read_stats_header(int stats_fd, struct kvm_stats_header *header); +struct kvm_stats_desc *read_stats_desc(int stats_fd, + struct kvm_stats_header *header); =20 uint32_t guest_get_vcpuid(void); =20 diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index fb511b42a03e..b49fae45db1e 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -62,14 +62,8 @@ static void stats_test(int stats_fd) header.data_offset), "Descriptor block is overlapped with data block"); =20 - /* Allocate memory for stats descriptors */ - stats_desc =3D calloc(header.num_desc, size_desc); - TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); /* Read kvm stats descriptors */ - ret =3D pread(stats_fd, stats_desc, - size_desc * header.num_desc, header.desc_offset); - TEST_ASSERT(ret =3D=3D size_desc * header.num_desc, - "Read KVM stats descriptors"); + stats_desc =3D read_stats_desc(stats_fd, &header); =20 /* Sanity check for fields in descriptors */ for (i =3D 0; i < header.num_desc; ++i) { diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 1d75d41f92dc..12fa8cc88043 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2577,3 +2577,41 @@ void read_stats_header(int stats_fd, struct kvm_stat= s_header *header) ret =3D read(stats_fd, header, sizeof(*header)); TEST_ASSERT(ret =3D=3D sizeof(*header), "Read stats header"); } + +static ssize_t stats_descs_size(struct kvm_stats_header *header) +{ + return header->num_desc * + (sizeof(struct kvm_stats_desc) + header->name_size); +} + +/* + * Read binary stats descriptors + * + * Input Args: + * stats_fd - the file descriptor for the binary stats file from which t= o read + * header - the binary stats metadata header corresponding to the given = FD + * + * Output Args: None + * + * Return: + * A pointer to a newly allocated series of stat descriptors. + * Caller is responsible for freeing the returned kvm_stats_desc. + * + * Read the stats descriptors from the binary stats interface. + */ +struct kvm_stats_desc *read_stats_desc(int stats_fd, + struct kvm_stats_header *header) +{ + struct kvm_stats_desc *stats_desc; + ssize_t ret; + + stats_desc =3D malloc(stats_descs_size(header)); + TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); + + ret =3D pread(stats_fd, stats_desc, stats_descs_size(header), + header->desc_offset); + TEST_ASSERT(ret =3D=3D stats_descs_size(header), + "Read KVM stats descriptors"); + + return stats_desc; +} --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE88EC433EF for ; Wed, 13 Apr 2022 18:00:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237597AbiDMSC1 (ORCPT ); Wed, 13 Apr 2022 14:02:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237567AbiDMSCS (ORCPT ); Wed, 13 Apr 2022 14:02:18 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18CAF3FBD2 for ; Wed, 13 Apr 2022 10:59:55 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id oo16-20020a17090b1c9000b001c6d21e8c04so4097064pjb.4 for ; Wed, 13 Apr 2022 10:59:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dGdHT2bPLXOJ2n8aFuh4xhdm9dOQMBhMBknnyhFlP5I=; b=jBAwjxink+IFXlbU98ZjIOs4uulu5gO8kRsE7u4MXqpB8RzpFew92LEOwx4Xu9X8k6 xgoBr1hxRAUDGQ4kJ/MnRo04q0jTuZTTcosAtfJhwItYkFSokhBaSr58g6X42k1DPPVa 2Kqr6dmOtE+hUey8r9q5rFiUOv0nlW8R2sdtAD64IdlTe4So1NjCYEQwjwFN4tochF9P AWaA1CH7FDYgCSDTspVLWbL7yqNDxiXZ3xu3IsNz+qR+Nk0/qqtJYnCAfmOnkRgATAg3 v8L9TysbeR0jl5BKqY5Znlh64uGAV+JGCdG6puNyFcHiVje3A5beJKeI4YFR1g7st/Nz qZng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dGdHT2bPLXOJ2n8aFuh4xhdm9dOQMBhMBknnyhFlP5I=; b=3Jqh0iKSMOeERPexQ3vYI2vca2R9DNCrIw0d4h9d7mLj3lMtC3W0l/ErZGSfmmwSKJ 29k8OubIoVL40MqVL+JGpP0Bt0LzTJUKBxQsbsz8ow5scLKgh5LFdx0L9SUtWJkyxvpD eIBlXWg8rIRdzmcCY/XjoFeFAcQtrzzll55gbRT7ATiJW4tNIs3xCDTbFgmti61F0U91 XTBtuUSt5DuBtplaI3B8uVyjZXcT04qz3mU8rs1huV/6vCyFs89bEJlagcIFrbImHSpP zhYa3rpXPYme7OZfI/m+r7rwPIJqRgI3mw81r7yCCCVjofLjkSl7/dflGq+l2S3j1jof RmmA== X-Gm-Message-State: AOAM531DrZH1pOaEIMDPQuMdZyvUNOBA8NbrHj4dEIyyxFd5kaBV94wP 3YLUekkLAbGGyQX3GeRGgfh9ESUZ5G6OgFfknT6Puq0qMgkW6S6PVE5dlrqBwsxGaM4MqvlR0V5 8b0eOL3CSFPl6hrYQ2+HKfj112ifEhZUSw7yEgVJifR7THQDJr/A3WTeDIzOyrn8tay201Gnu X-Google-Smtp-Source: ABdhPJxg3bnsHDqR36HhTPliOgczpjBpwZNk93DfkQ5KZoOER3XSqIWUzuxf7JvzKrhCcxw9cok/KWCo4t8q X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a65:6753:0:b0:385:fa8a:188f with SMTP id c19-20020a656753000000b00385fa8a188fmr36502519pgu.499.1649872794452; Wed, 13 Apr 2022 10:59:54 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:38 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-5-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 04/10] KVM: selftests: Clean up coding style in binary stats test From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Sean Christopherson Fix a variety of code style violations and/or inconsistencies in the binary stats test. The 80 char limit is a soft limit and can and should be ignored/violated if doing so improves the overall code readability. Specifically, provide consistent indentation and don't split expressions at arbitrary points just to honor the 80 char limit. Opportunistically expand/add comments to call out the more subtle aspects of the code. Signed-off-by: Sean Christopherson Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/kvm_binary_stats_test.c | 91 ++++++++++++------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index b49fae45db1e..8b31f8fc7e08 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -35,47 +35,64 @@ static void stats_test(int stats_fd) /* Read kvm stats header */ read_stats_header(stats_fd, &header); =20 + /* + * The base size of the descriptor is defined by KVM's ABI, but the + * size of the name field is variable as far as KVM's ABI is concerned. + * But, the size of name is constant for a given instance of KVM and + * is provided by KVM in the overall stats header. + */ size_desc =3D sizeof(*stats_desc) + header.name_size; =20 /* Read kvm stats id string */ id =3D malloc(header.name_size); TEST_ASSERT(id, "Allocate memory for id string"); + ret =3D read(stats_fd, id, header.name_size); TEST_ASSERT(ret =3D=3D header.name_size, "Read id string"); =20 /* Check id string, that should start with "kvm" */ TEST_ASSERT(!strncmp(id, "kvm", 3) && strlen(id) < header.name_size, - "Invalid KVM stats type, id: %s", id); + "Invalid KVM stats type, id: %s", id); =20 /* Sanity check for other fields in header */ if (header.num_desc =3D=3D 0) { printf("No KVM stats defined!"); return; } - /* Check overlap */ - TEST_ASSERT(header.desc_offset > 0 && header.data_offset > 0 - && header.desc_offset >=3D sizeof(header) - && header.data_offset >=3D sizeof(header), - "Invalid offset fields in header"); + /* + * The descriptor and data offsets must be valid, they must not overlap + * the header, and the descriptor and data blocks must not overlap each + * other. Note, the data block is rechecked after its size is known. + */ + TEST_ASSERT(header.desc_offset && header.desc_offset >=3D sizeof(header) = && + header.data_offset && header.data_offset >=3D sizeof(header), + "Invalid offset fields in header"); + TEST_ASSERT(header.desc_offset > header.data_offset || - (header.desc_offset + size_desc * header.num_desc <=3D - header.data_offset), - "Descriptor block is overlapped with data block"); + (header.desc_offset + size_desc * header.num_desc <=3D header.data_o= ffset), + "Descriptor block is overlapped with data block"); =20 /* Read kvm stats descriptors */ stats_desc =3D read_stats_desc(stats_fd, &header); =20 /* Sanity check for fields in descriptors */ for (i =3D 0; i < header.num_desc; ++i) { + /* + * Note, size_desc includes the of the name field, which is + * variable, i.e. this is NOT equivalent to &stats_desc[i]. + */ pdesc =3D (void *)stats_desc + i * size_desc; - /* Check type,unit,base boundaries */ - TEST_ASSERT((pdesc->flags & KVM_STATS_TYPE_MASK) - <=3D KVM_STATS_TYPE_MAX, "Unknown KVM stats type"); - TEST_ASSERT((pdesc->flags & KVM_STATS_UNIT_MASK) - <=3D KVM_STATS_UNIT_MAX, "Unknown KVM stats unit"); - TEST_ASSERT((pdesc->flags & KVM_STATS_BASE_MASK) - <=3D KVM_STATS_BASE_MAX, "Unknown KVM stats base"); - /* Check exponent for stats unit + + /* Check type, unit, and base boundaries */ + TEST_ASSERT((pdesc->flags & KVM_STATS_TYPE_MASK) <=3D KVM_STATS_TYPE_MAX, + "Unknown KVM stats type"); + TEST_ASSERT((pdesc->flags & KVM_STATS_UNIT_MASK) <=3D KVM_STATS_UNIT_MAX, + "Unknown KVM stats unit"); + TEST_ASSERT((pdesc->flags & KVM_STATS_BASE_MASK) <=3D KVM_STATS_BASE_MAX, + "Unknown KVM stats base"); + + /* + * Check exponent for stats unit * Exponent for counter should be greater than or equal to 0 * Exponent for unit bytes should be greater than or equal to 0 * Exponent for unit seconds should be less than or equal to 0 @@ -86,47 +103,51 @@ static void stats_test(int stats_fd) case KVM_STATS_UNIT_NONE: case KVM_STATS_UNIT_BYTES: case KVM_STATS_UNIT_CYCLES: - TEST_ASSERT(pdesc->exponent >=3D 0, - "Unsupported KVM stats unit"); + TEST_ASSERT(pdesc->exponent >=3D 0, "Unsupported KVM stats unit"); break; case KVM_STATS_UNIT_SECONDS: - TEST_ASSERT(pdesc->exponent <=3D 0, - "Unsupported KVM stats unit"); + TEST_ASSERT(pdesc->exponent <=3D 0, "Unsupported KVM stats unit"); break; } /* Check name string */ TEST_ASSERT(strlen(pdesc->name) < header.name_size, - "KVM stats name(%s) too long", pdesc->name); + "KVM stats name(%s) too long", pdesc->name); /* Check size field, which should not be zero */ - TEST_ASSERT(pdesc->size, "KVM descriptor(%s) with size of 0", - pdesc->name); + TEST_ASSERT(pdesc->size, + "KVM descriptor(%s) with size of 0", pdesc->name); /* Check bucket_size field */ switch (pdesc->flags & KVM_STATS_TYPE_MASK) { case KVM_STATS_TYPE_LINEAR_HIST: TEST_ASSERT(pdesc->bucket_size, - "Bucket size of Linear Histogram stats (%s) is zero", - pdesc->name); + "Bucket size of Linear Histogram stats (%s) is zero", + pdesc->name); break; default: TEST_ASSERT(!pdesc->bucket_size, - "Bucket size of stats (%s) is not zero", - pdesc->name); + "Bucket size of stats (%s) is not zero", + pdesc->name); } size_data +=3D pdesc->size * sizeof(*stats_data); } - /* Check overlap */ - TEST_ASSERT(header.data_offset >=3D header.desc_offset - || header.data_offset + size_data <=3D header.desc_offset, - "Data block is overlapped with Descriptor block"); + + /* + * Now that the size of the data block is known, verify the data block + * doesn't overlap the descriptor block. + */ + TEST_ASSERT(header.data_offset >=3D header.desc_offset || + header.data_offset + size_data <=3D header.desc_offset, + "Data block is overlapped with Descriptor block"); + /* Check validity of all stats data size */ TEST_ASSERT(size_data >=3D header.num_desc * sizeof(*stats_data), - "Data size is not correct"); + "Data size is not correct"); + /* Check stats offset */ for (i =3D 0; i < header.num_desc; ++i) { pdesc =3D (void *)stats_desc + i * size_desc; TEST_ASSERT(pdesc->offset < size_data, - "Invalid offset (%u) for stats: %s", - pdesc->offset, pdesc->name); + "Invalid offset (%u) for stats: %s", + pdesc->offset, pdesc->name); } =20 /* Allocate memory for stats data */ --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09335C433FE for ; Wed, 13 Apr 2022 18:00:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237621AbiDMSDI (ORCPT ); Wed, 13 Apr 2022 14:03:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237579AbiDMSCU (ORCPT ); Wed, 13 Apr 2022 14:02:20 -0400 Received: from mail-ot1-x349.google.com (mail-ot1-x349.google.com [IPv6:2607:f8b0:4864:20::349]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F2A93FDB0 for ; Wed, 13 Apr 2022 10:59:57 -0700 (PDT) Received: by mail-ot1-x349.google.com with SMTP id f8-20020a9d5f08000000b005cb3a6c4c1cso1319572oti.21 for ; Wed, 13 Apr 2022 10:59:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=nE0p9VkAEZPrbUZLBLHj/EA6GeKDyutWcWOyx+QH1CQ=; b=CGNbDpPje6DWNjSf8HxzYlFoeW1No4i38r6wXXxwwBripH9w+hcowUZjbCXeEk7ebm JxfkF/a2MAsta6GRKlumZE6cFaOm/Yli8aCQmtf0wxrUnAcQlyyzk/cU8XGWus381SF/ JJMqKOUXYgEuvwwpU3m8+ZCRalGNv0LEk6CSfdh9BSWnas3iuooeZM7XMsT8H5BrlMnh RGhfZnBAP6eymm5zbSoH03p791b2+LMIiH3gDKpQfotTNSudybPXIx3ElmeOLTSdcP6Z a2wkvjqmqlx90KsFRn1CWqeB5Gjecuhtn5LxmvywsA0apGF8kDHFZe/PSmzbdFhrC2DV /7nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=nE0p9VkAEZPrbUZLBLHj/EA6GeKDyutWcWOyx+QH1CQ=; b=oF3+WFB7R/wDM+4LNKZ9V+ri4/ByXB72LWLRTk9EK+0GPSBcUDRigMUMdSJQgYEO4P xL9j+VClBlicqoozFly9HcYQ+gXxE1d4R+bvk96wraPVTXKtBMEny+3EnPNyRaOg5Kq9 DIEe1+rihruMJ/ndbb/iQyExlYsBhdD58sKmYG0LYCGmRmqw4Q0K6F+fsu8bHcduv8L9 0z0T0eegIHLa2L9JzcIsSXfa9Z6Kz4abBFv4u9dftv2JR2AD6nUuv9vh8KPZ+0DHFVXU kIBCmTxOLfnjomurB3utNUAMf/CwqYm+twUTVbYbTH4L5qZQgeSXB5RDA46t/JHSB76V v4Sw== X-Gm-Message-State: AOAM533jl+YeMOBOKeTCsaY7PKmUx+3BkP8JrPLYiUGWT75NyY9o67tS xldw9AClZDASj7IrK2OmFkAoDijOpVlb4mG0OKkLwUQmz0IUM5mkvUC9dKMr0nUJbUrPL+Y13sJ cnWdpX/rjlFG+wXgXtk7c75jMrymn/9BjXcKHP7DkVO4gs1kgUvbaq6FmgH0Qd7l5C6b5YSAR X-Google-Smtp-Source: ABdhPJxIEOLgikotz+8frIC7nYGrz+JkYc/+D4E6cRrh+T9b8zgx11iYyDt9qlI4bTND46iVkwTs5LlwOE4V X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a05:6870:a789:b0:de:a48c:c953 with SMTP id x9-20020a056870a78900b000dea48cc953mr9066oao.298.1649872796515; Wed, 13 Apr 2022 10:59:56 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:39 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-6-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 05/10] KVM: selftests: Read binary stat data in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the code to read the binary stats data to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/include/kvm_util_base.h | 3 ++ .../selftests/kvm/kvm_binary_stats_test.c | 7 ++-- tools/testing/selftests/kvm/lib/kvm_util.c | 36 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index fabe46ddc1b2..2a3a4d9ed8e3 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -403,6 +403,9 @@ int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpui= d); void read_stats_header(int stats_fd, struct kvm_stats_header *header); struct kvm_stats_desc *read_stats_desc(int stats_fd, struct kvm_stats_header *header); +int read_stat_data(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc, uint64_t *data, + ssize_t max_elements); =20 uint32_t guest_get_vcpuid(void); =20 diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index 8b31f8fc7e08..59677fae26e5 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -160,11 +160,8 @@ static void stats_test(int stats_fd) size_data =3D 0; for (i =3D 0; i < header.num_desc; ++i) { pdesc =3D (void *)stats_desc + i * size_desc; - ret =3D pread(stats_fd, stats_data, - pdesc->size * sizeof(*stats_data), - header.data_offset + size_data); - TEST_ASSERT(ret =3D=3D pdesc->size * sizeof(*stats_data), - "Read data of KVM stats: %s", pdesc->name); + read_stat_data(stats_fd, &header, pdesc, stats_data, + pdesc->size); size_data +=3D pdesc->size * sizeof(*stats_data); } =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 12fa8cc88043..fc2321055a69 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2615,3 +2615,39 @@ struct kvm_stats_desc *read_stats_desc(int stats_fd, =20 return stats_desc; } + +/* + * Read stat data for a particular stat + * + * Input Args: + * stats_fd - the file descriptor for the binary stats file from which t= o read + * header - the binary stats metadata header corresponding to the given = FD + * desc - the binary stat metadata for the particular stat to be read + * max_elements - the maximum number of 8-byte values to read into data + * + * Output Args: + * data - the buffer into which stat data should be read + * + * Return: + * The number of data elements read into data or -ERRNO on error. + * + * Read the data values of a specified stat from the binary stats interfac= e. + */ +int read_stat_data(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc, uint64_t *data, + ssize_t max_elements) +{ + ssize_t size =3D min((ssize_t)desc->size, max_elements); + ssize_t ret; + + ret =3D pread(stats_fd, data, size * sizeof(*data), + header->data_offset + desc->offset); + + /* ret from pread is in bytes. */ + ret =3D ret / sizeof(*data); + + TEST_ASSERT(ret =3D=3D size, + "Read data of KVM stats: %s", desc->name); + + return ret; +} --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73237C433EF for ; Wed, 13 Apr 2022 18:01:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231976AbiDMSDW (ORCPT ); Wed, 13 Apr 2022 14:03:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58608 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237572AbiDMSCV (ORCPT ); Wed, 13 Apr 2022 14:02:21 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D7FD3ED2A for ; Wed, 13 Apr 2022 10:59:59 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id f6-20020a170902ab8600b0015895212d23so1544834plr.6 for ; Wed, 13 Apr 2022 10:59:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=oDKaF227nBT2MqbB1fwM7dDzetRoxMTdlPAeTV2ta2k=; b=oed96hXLbqf3H5+veEWpI7BPo6+Tj6+HENlIbuTZ3V0cxFInrOUq+bfBBhnWnpwOil hzsTBRaUaiDOz3t8DWOqtHxLfumGuusIqO3GZfnEXToYerUVRodtarOg5Fh3VPykFwjq rMvVPu87J42w4tUsHsgoliRq9MSCQdrTontaV7hQ9tuRwp48RrDHwZ9Jt/OdPzcgL0af GqUHzNwxjAjyIqtWcATGP+rtDha/KvmktceaOiLEN2mRZGK7Z7jP1iyoWomYLkk9iQbl 5ScbyfCtJ17qjWizLWP1G8TPBT7+gIvXigqc8ZlHZfiZFjV6jk9SbToLkRRWmVAPyBWn tZKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=oDKaF227nBT2MqbB1fwM7dDzetRoxMTdlPAeTV2ta2k=; b=jF9sB5dMHEpKBKfnhhKr2qcANMpZujG11QPjmEi6NLsGa3rkUtLeq0tRJdy5yP0x7l 0a7Kihexdgmh4hWvhaln/Ajvgh4kGDYcctHelAkPPuVjVyzthlL4LepuR6ugLoXC5pzl wr4/3kQOYxMFsr1dtAtfY085mI7Lw9e4emWSknNsLQjBe382jt4GQiXmOFrxV5lScehg 5EgEybo4UQdM/9YiSP4zQdpMcs3pZWazfLMZ+5uacXyzKLru1G0G1/RDtkgwRbXOEQsc 3+vnb+PlVc22nUuTpC6YbT0tGbjQw7iW84ZTALu7Mwj/jGfmUxJ9k+h7McS1VEd8rY6m 6XoQ== X-Gm-Message-State: AOAM533drKLWW8F/NXWLT7x1xWI2ZKIQDlEMeY2x3F1m99wr21vl5OnR cruMpNY5FFYM2It7pztRqExk5XnEqZr6Ei/3w/kgDF072VstwqFDwshzrvNiqEKcQBiFrDksceX 6b1Ci8j/kO8dyQJAuFYq7bpThzwafPOoQsJJb/LtlhLPYaR8pLVmZMx3jnn9uSUmDKwh6uNiR X-Google-Smtp-Source: ABdhPJwNN7Emm7zUNN0AwUlDvrPtO3WG1fzXyrP8M5uUg+90Kryz0WiDW7yuJUfiR0Q/JhBSKRDdfp1XM6BQ X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a17:90b:2384:b0:1cb:5223:9dc4 with SMTP id mr4-20020a17090b238400b001cb52239dc4mr25759pjb.1.1649872798287; Wed, 13 Apr 2022 10:59:58 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:40 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-7-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 06/10] KVM: selftests: Add NX huge pages test From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There's currently no test coverage of NX hugepages in KVM selftests, so add a basic test to ensure that the feature works as intended. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- tools/testing/selftests/kvm/Makefile | 10 ++ .../selftests/kvm/include/kvm_util_base.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 62 +++++++ .../selftests/kvm/x86_64/nx_huge_pages_test.c | 166 ++++++++++++++++++ .../kvm/x86_64/nx_huge_pages_test.sh | 25 +++ 5 files changed, 264 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c create mode 100755 tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index af582d168621..9bb9bce4df37 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -43,6 +43,10 @@ LIBKVM_aarch64 =3D lib/aarch64/processor.c lib/aarch64/u= call.c lib/aarch64/handler LIBKVM_s390x =3D lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318= _test_handler.c LIBKVM_riscv =3D lib/riscv/processor.c lib/riscv/ucall.c =20 +# Non-compiled test targets +TEST_PROGS_x86_64 +=3D x86_64/nx_huge_pages_test.sh + +# Compiled test targets TEST_GEN_PROGS_x86_64 =3D x86_64/cpuid_test TEST_GEN_PROGS_x86_64 +=3D x86_64/cr4_cpuid_sync_test TEST_GEN_PROGS_x86_64 +=3D x86_64/get_msr_index_features @@ -104,6 +108,9 @@ TEST_GEN_PROGS_x86_64 +=3D steal_time TEST_GEN_PROGS_x86_64 +=3D kvm_binary_stats_test TEST_GEN_PROGS_x86_64 +=3D system_counter_offset_test =20 +# Compiled outputs used by test targets +TEST_GEN_PROGS_EXTENDED_x86_64 +=3D x86_64/nx_huge_pages_test + TEST_GEN_PROGS_aarch64 +=3D aarch64/arch_timer TEST_GEN_PROGS_aarch64 +=3D aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 +=3D aarch64/get-reg-list @@ -142,7 +149,9 @@ TEST_GEN_PROGS_riscv +=3D kvm_page_table_test TEST_GEN_PROGS_riscv +=3D set_memory_region_test TEST_GEN_PROGS_riscv +=3D kvm_binary_stats_test =20 +TEST_PROGS +=3D $(TEST_PROGS_$(UNAME_M)) TEST_GEN_PROGS +=3D $(TEST_GEN_PROGS_$(UNAME_M)) +TEST_GEN_PROGS_EXTENDED +=3D $(TEST_GEN_PROGS_EXTENDED_$(UNAME_M)) LIBKVM +=3D $(LIBKVM_$(UNAME_M)) =20 INSTALL_HDR_PATH =3D $(top_srcdir)/usr @@ -193,6 +202,7 @@ $(OUTPUT)/libkvm.a: $(LIBKVM_OBJS) x :=3D $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))) all: $(STATIC_LIBS) $(TEST_GEN_PROGS): $(STATIC_LIBS) +$(TEST_GEN_PROGS_EXTENDED): $(STATIC_LIBS) =20 cscope: include_paths =3D $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include = lib .. cscope: diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 2a3a4d9ed8e3..001b55ae25f8 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -406,6 +406,7 @@ struct kvm_stats_desc *read_stats_desc(int stats_fd, int read_stat_data(int stats_fd, struct kvm_stats_header *header, struct kvm_stats_desc *desc, uint64_t *data, ssize_t max_elements); +uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name); =20 uint32_t guest_get_vcpuid(void); =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index fc2321055a69..d332f02370d1 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2651,3 +2651,65 @@ int read_stat_data(int stats_fd, struct kvm_stats_he= ader *header, =20 return ret; } + +static int __vm_get_stat(struct kvm_vm *vm, const char *stat_name, + uint64_t *data, ssize_t max_elements) +{ + struct kvm_stats_desc *stats_desc; + struct kvm_stats_header header; + struct kvm_stats_desc *desc; + size_t size_desc; + int stats_fd; + int ret =3D -EINVAL; + int i; + + stats_fd =3D vm_get_stats_fd(vm); + + read_stats_header(stats_fd, &header); + + stats_desc =3D read_stats_desc(stats_fd, &header); + + size_desc =3D sizeof(struct kvm_stats_desc) + header.name_size; + + /* Read kvm stats data one by one */ + for (i =3D 0; i < header.num_desc; ++i) { + desc =3D (void *)stats_desc + (i * size_desc); + + if (strcmp(desc->name, stat_name)) + continue; + + ret =3D read_stat_data(stats_fd, &header, desc, data, + max_elements); + } + + free(stats_desc); + close(stats_fd); + return ret; +} + +/* + * Read the value of the named stat + * + * Input Args: + * vm - the VM for which the stat should be read + * stat_name - the name of the stat to read + * + * Output Args: None + * + * Return: + * The value of the stat + * + * Reads the value of the named stat through the binary stat interface. If + * the named stat has multiple data elements, only the first will be retur= ned. + */ +uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) +{ + uint64_t data; + int ret; + + ret =3D __vm_get_stat(vm, stat_name, &data, 1); + TEST_ASSERT(ret =3D=3D 1, + "Stat %s expected to have 1 element, but %d returned", + stat_name, ret); + return data; +} diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tool= s/testing/selftests/kvm/x86_64/nx_huge_pages_test.c new file mode 100644 index 000000000000..7f80e48781fd --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * tools/testing/selftests/kvm/nx_huge_page_test.c + * + * Usage: to be run via nx_huge_page_test.sh, which does the necessary + * environment setup and teardown + * + * Copyright (C) 2022, Google LLC. + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include +#include "kvm_util.h" + +#define HPAGE_SLOT 10 +#define HPAGE_GVA (23*1024*1024) +#define HPAGE_GPA (10*1024*1024) +#define HPAGE_SLOT_NPAGES (512 * 3) +#define PAGE_SIZE 4096 + +/* + * x86 opcode for the return instruction. Used to call into, and then + * immediately return from, memory backed with hugepages. + */ +#define RETURN_OPCODE 0xC3 + +/* + * Exit the VM after each memory access so that the userspace component of= the + * test can make assertions about the pages backing the VM. + */ +void guest_code(void) +{ + uint64_t hpage_1 =3D HPAGE_GVA; + uint64_t hpage_2 =3D hpage_1 + (PAGE_SIZE * 512); + uint64_t hpage_3 =3D hpage_2 + (PAGE_SIZE * 512); + + READ_ONCE(*(uint64_t *)hpage_1); + GUEST_SYNC(1); + + READ_ONCE(*(uint64_t *)hpage_2); + GUEST_SYNC(2); + + ((void (*)(void)) hpage_1)(); + GUEST_SYNC(3); + + ((void (*)(void)) hpage_3)(); + GUEST_SYNC(4); + + READ_ONCE(*(uint64_t *)hpage_1); + GUEST_SYNC(5); + + READ_ONCE(*(uint64_t *)hpage_3); + GUEST_SYNC(6); +} + +static void check_2m_page_count(struct kvm_vm *vm, int expected_pages_2m) +{ + int actual_pages_2m; + + actual_pages_2m =3D vm_get_stat(vm, "pages_2m"); + + TEST_ASSERT(actual_pages_2m =3D=3D expected_pages_2m, + "Unexpected 2m page count. Expected %d, got %d", + expected_pages_2m, actual_pages_2m); +} + +static void check_split_count(struct kvm_vm *vm, int expected_splits) +{ + int actual_splits; + + actual_splits =3D vm_get_stat(vm, "nx_lpage_splits"); + + TEST_ASSERT(actual_splits =3D=3D expected_splits, + "Unexpected nx lpage split count. Expected %d, got %d", + expected_splits, actual_splits); +} + +int main(int argc, char **argv) +{ + struct kvm_vm *vm; + struct timespec ts; + void *hva; + + vm =3D vm_create_default(0, 0, guest_code); + + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, + HPAGE_GPA, HPAGE_SLOT, + HPAGE_SLOT_NPAGES, 0); + + virt_map(vm, HPAGE_GVA, HPAGE_GPA, HPAGE_SLOT_NPAGES); + + hva =3D addr_gpa2hva(vm, HPAGE_GPA); + memset(hva, RETURN_OPCODE, HPAGE_SLOT_NPAGES * PAGE_SIZE); + + check_2m_page_count(vm, 0); + check_split_count(vm, 0); + + /* + * The guest code will first read from the first hugepage, resulting + * in a huge page mapping being created. + */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 1); + check_split_count(vm, 0); + + /* + * Then the guest code will read from the second hugepage, resulting + * in another huge page mapping being created. + */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 2); + check_split_count(vm, 0); + + /* + * Next, the guest will execute from the first huge page, causing it + * to be remapped at 4k. + */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 1); + check_split_count(vm, 1); + + /* + * Executing from the third huge page (previously unaccessed) will + * cause part to be mapped at 4k. + */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 1); + check_split_count(vm, 2); + + /* Reading from the first huge page again should have no effect. */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 1); + check_split_count(vm, 2); + + /* + * Give recovery thread time to run. The wrapper script sets + * recovery_period_ms to 100, so wait 5x that. + */ + ts.tv_sec =3D 0; + ts.tv_nsec =3D 500000000; + nanosleep(&ts, NULL); + + /* + * Now that the reclaimer has run, all the split pages should be gone. + */ + check_2m_page_count(vm, 1); + check_split_count(vm, 0); + + /* + * The 4k mapping on hpage 3 should have been removed, so check that + * reading from it causes a huge page mapping to be installed. + */ + vcpu_run(vm, 0); + check_2m_page_count(vm, 2); + check_split_count(vm, 0); + + kvm_vm_free(vm); + + return 0; +} + diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh b/too= ls/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh new file mode 100755 index 000000000000..19fc95723fcb --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only */ + +# tools/testing/selftests/kvm/nx_huge_page_test.sh +# Copyright (C) 2022, Google LLC. + +NX_HUGE_PAGES=3D$(cat /sys/module/kvm/parameters/nx_huge_pages) +NX_HUGE_PAGES_RECOVERY_RATIO=3D$(cat /sys/module/kvm/parameters/nx_huge_pa= ges_recovery_ratio) +NX_HUGE_PAGES_RECOVERY_PERIOD=3D$(cat /sys/module/kvm/parameters/nx_huge_p= ages_recovery_period_ms) +HUGE_PAGES=3D$(cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages) + +echo 1 > /sys/module/kvm/parameters/nx_huge_pages +echo 1 > /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio +echo 100 > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms +echo 200 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +./nx_huge_pages_test +RET=3D$? + +echo $NX_HUGE_PAGES > /sys/module/kvm/parameters/nx_huge_pages +echo $NX_HUGE_PAGES_RECOVERY_RATIO > /sys/module/kvm/parameters/nx_huge_pa= ges_recovery_ratio +echo $NX_HUGE_PAGES_RECOVERY_PERIOD > /sys/module/kvm/parameters/nx_huge_p= ages_recovery_period_ms +echo $HUGE_PAGES > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +exit $RET --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38C02C433EF for ; Wed, 13 Apr 2022 18:01:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237809AbiDMSDn (ORCPT ); Wed, 13 Apr 2022 14:03:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237568AbiDMSCW (ORCPT ); Wed, 13 Apr 2022 14:02:22 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1F5F40918 for ; Wed, 13 Apr 2022 11:00:00 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id bf10-20020a656d0a000000b0039d4f854e22so1475356pgb.5 for ; Wed, 13 Apr 2022 11:00:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=S9c5hfgea9nF2vcGLAzTx3MCtPKtuM/ZU/yidQX2w98=; b=fysxMTw5FfeK2kfCYyldf+U2U6tRB7zRsq9JmBoQbVpkoKWgjcJFFsaxGEaogeuHP2 0tkRlXfnlvVimHa9GCR61mV1Cwo8kJeXLMx8NY3eLl+pNzl0E70NCHbzTodLmT3FCJ+S ulQ+1RrkXHdi6NuH3A9ke1uwAs40IuhESL/zkPW3jhBOq9XChi9ndNgfZiQJzkwp/nwp W+Ro7evQEnJDKZObBIaEEZmKBimsckWmr+UseTNZ7Juk5JyA3mf8sE2krn3iCSJ8ryMR ZBE3RYt7ww+T8Q5A3WHEOuUDMYzIvb+hjkWJnMHRgNGpKV6cx8n55PYy8Ox07OAqcVTf yMcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=S9c5hfgea9nF2vcGLAzTx3MCtPKtuM/ZU/yidQX2w98=; b=esZiQpwFIXG25FZLY4hWHrMXQPSF0W2nWdXBySR52jGUk1QaO1EC6pklBY4dipdDWj dPf/yrnIVaEY4/q1y1aFmAid03cGwbVooat9K30DOApYqh5NO/fPTQ5yBd+bRxeD1y/s G6Daf2G4w+HWpmpNE6kCixXy+C2Y3slvzUh4JoZateEPsm8l+F3+kje8x0NQoW1efaoE yoEzaPzvWq8N7n1kpQLhQlG+9G6wraPjEccXSMMMHpzBY1kB5H0JCB+QyS+xF58dF1Ne KukITuNP+k9C2465b2c8Aj9EdKX8S38YXDS+wRzGjouMZSI5mawAbggwc1GGpJUz6LER yK8Q== X-Gm-Message-State: AOAM531hbjfKAcvu7dngc02fWWphDe9aQoHmuIw/KVbPYvzFhrO43YAh qI5zesXwqzeMkpqLfxZzd+EtMsOJyjWAPOsfx/q2Xl/Dzeypc8HcfDE70Rz0lIbSFHuwPQNI8hp WHcwU5CsHBExMND4i+ieZTk02t40rE84JQ+aGleSO+4EFUhlD6+uinkR/VpHyq67MDtfr3fk8 X-Google-Smtp-Source: ABdhPJwz1kE+LgFkjp6n93PoL8eszyj+sUtefQWtn3Wy529KwG2yZvBjUXDzUykj7XYTEdt1lSJb6vGRqYH9 X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a17:902:d2d0:b0:158:761e:c165 with SMTP id n16-20020a170902d2d000b00158761ec165mr13217509plc.59.1649872800278; Wed, 13 Apr 2022 11:00:00 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:41 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-8-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 07/10] KVM: x86: Fix errant brace in KVM capability handling From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The braces around the KVM_CAP_XSAVE2 block also surround the KVM_CAP_PMU_CAPABILITY block, likely the result of a merge issue. Simply move the curly brace back to where it belongs. Fixes: ba7bb663f5547 ("KVM: x86: Provide per VM capability for disabling PM= U virtualization") Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ab336f7c82e4..665c1fa8bb57 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4382,10 +4382,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, l= ong ext) if (r < sizeof(struct kvm_xsave)) r =3D sizeof(struct kvm_xsave); break; + } case KVM_CAP_PMU_CAPABILITY: r =3D enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0; break; - } case KVM_CAP_DISABLE_QUIRKS2: r =3D KVM_X86_VALID_QUIRKS; break; --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 492A9C433EF for ; Wed, 13 Apr 2022 18:01:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230400AbiDMSDv (ORCPT ); Wed, 13 Apr 2022 14:03:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237600AbiDMSC2 (ORCPT ); Wed, 13 Apr 2022 14:02:28 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6A7840E7B for ; Wed, 13 Apr 2022 11:00:03 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id n5-20020a1709026a8500b00158a0312fe9so1554572plk.2 for ; Wed, 13 Apr 2022 11:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=LID3cRTY2ArhbHgRrWrGB0hR8ooJJqddVWRsh1uyvfY=; b=Vsq8aDzKSI7Ijbv4BOenD46C1cvo38NZrSaRPHBdHVKdS8JscFvlFxTcg8+0TJ9Koa HvJKtZtq6lOjrI35RVfttdhmvUt23cUpe2QE9WKbmARZHHsuDhKis5opyRJKqgzPQmnG btgqiY8AQDwfsg3W8WKmz+pOnMAO+XlNo5rdqU7aCE/o0z+bm2w5PGDqTrWtbpzKdowB UWycdBXsxFBL1hELUsWx0DGIIe3WkRF+4L1BfOOiwWNCMBrI2nsqf+x1feEaN7Qzb+tI 1NJwTAGGfBCgoQ4u7tlup6DfUk47fc4jqBxrfgas9cGK0SpKnWQwUZVq/52tr9S1JjVj A6sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LID3cRTY2ArhbHgRrWrGB0hR8ooJJqddVWRsh1uyvfY=; b=4uTq+CzoRX4X9DcifUXylv38EwcZ3XqyXiQ3w50QivKc4sG1kJ4v6wq3JRXb7olH3t fr92XdsZFwrqMEtro7QHAIaWmPp3gR5L7HTpJ/N3sgmXSXcDuhzth6fxTLr4PbjTchw0 7jqSLOD1xZpCof+Ky25PNno3usPRXyleNHK4izn8Li3Xpk+kSfF6jCXHPK0r1ilT/baP cZdh0aw3+d7wlNmFYgq0HvGbxTo5Vh2/jkK2g7XV/UHTF90jPeFioLy8qXS/7MI0GG8u IDRkwcGvwt/4GbBJ0wv0oTcV4A9HbnaTvA2SJ1q8gemdzK66fji9p1EKK78oh61vDZgr YgOA== X-Gm-Message-State: AOAM530mLvCanR5ETNYukw1P8fPdzvZZcp9Xi7Zg0vh1+lDg/gcPDYxv xShEfQrFj2Pa2o/jmY7fy9+403LEXnCkp0Z9pliFgzz/d351gFJbiQdT0F9LVdn1HbQVCkJYmiI +qqDJTbj2XyO2Bmy+yMJZuGwEJi6HlzgxZWaiZSzFaO+5DidVPE/qLCP4U3GUTiJeptnuvsZK X-Google-Smtp-Source: ABdhPJxLG/CRYgnCQcwMFMmg+KPQ8RP4j8UzyPwwqr3SsMN0pYZaOvxOFED/VCjyHutG8DlmxcaJ6i1Fg95w X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a17:90a:c70f:b0:1bf:3e2d:6cfa with SMTP id o15-20020a17090ac70f00b001bf3e2d6cfamr47514pjt.70.1649872802308; Wed, 13 Apr 2022 11:00:02 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:42 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-9-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 08/10] KVM: x86/MMU: Allow NX huge pages to be disabled on a per-vm basis From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In some cases, the NX hugepage mitigation for iTLB multihit is not needed for all guests on a host. Allow disabling the mitigation on a per-VM basis to avoid the performance hit of NX hugepages on trusted workloads. In order to disable NX hugepages on a VM, ensure that the userspace actor has permission to reboot the system. Since disabling NX hugepages would allow a guest to crash the system, it is similar to reboot permissions. Ideally, KVM would require userspace to prove it has access to KVM's nx_huge_pages module param, e.g. so that userspace can opt out without needing full reboot permissions. But getting access to the module param file info is difficult because it is buried in layers of sysfs and module glue. Requiring CAP_SYS_BOOT is sufficient for all known use cases. Suggested-by: Jim Mattson Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- Documentation/virt/kvm/api.rst | 13 +++++++++++++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/mmu.h | 9 +++++---- arch/x86/kvm/mmu/spte.c | 7 ++++--- arch/x86/kvm/mmu/spte.h | 3 ++- arch/x86/kvm/mmu/tdp_mmu.c | 3 ++- arch/x86/kvm/x86.c | 23 +++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + 8 files changed, 52 insertions(+), 9 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 72183ae628f7..021452a9fa91 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7855,6 +7855,19 @@ At this time, KVM_PMU_CAP_DISABLE is the only capabi= lity. Setting this capability will disable PMU virtualization for that VM. Usermode should adjust CPUID leaf 0xA to reflect that the PMU is disabled. =20 +8.36 KVM_CAP_VM_DISABLE_NX_HUGE_PAGES +--------------------------- + +:Capability KVM_CAP_PMU_CAPABILITY +:Architectures: x86 +:Type: vm +:Returns 0 on success, -EPERM if the userspace process does not + have CAP_SYS_BOOT + +This capability disables the NX huge pages mitigation for iTLB MULTIHIT. + +The capability has no effect if the nx_huge_pages module parameter is not = set. + 9. Known KVM API problems =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D =20 diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 2c20f715f009..b8ab4fa7d4b2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1240,6 +1240,8 @@ struct kvm_arch { hpa_t hv_root_tdp; spinlock_t hv_root_tdp_lock; #endif + + bool disable_nx_huge_pages; }; =20 struct kvm_vm_stat { diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 671cfeccf04e..148f630af78a 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -173,9 +173,10 @@ struct kvm_page_fault { int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault= ); =20 extern int nx_huge_pages; -static inline bool is_nx_huge_page_enabled(void) +static inline bool is_nx_huge_page_enabled(struct kvm *kvm) { - return READ_ONCE(nx_huge_pages); + return READ_ONCE(nx_huge_pages) && + !kvm->arch.disable_nx_huge_pages; } =20 static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_o= r_gpa, @@ -191,8 +192,8 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu= *vcpu, gpa_t cr2_or_gpa, .user =3D err & PFERR_USER_MASK, .prefetch =3D prefetch, .is_tdp =3D likely(vcpu->arch.mmu->page_fault =3D=3D kvm_tdp_page_fault), - .nx_huge_page_workaround_enabled =3D is_nx_huge_page_enabled(), - + .nx_huge_page_workaround_enabled =3D + is_nx_huge_page_enabled(vcpu->kvm), .max_level =3D KVM_MAX_HUGEPAGE_LEVEL, .req_level =3D PG_LEVEL_4K, .goal_level =3D PG_LEVEL_4K, diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 4739b53c9734..877ad30bc7ad 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -116,7 +116,7 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_pa= ge *sp, spte |=3D spte_shadow_accessed_mask(spte); =20 if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && - is_nx_huge_page_enabled()) { + is_nx_huge_page_enabled(vcpu->kvm)) { pte_access &=3D ~ACC_EXEC_MASK; } =20 @@ -215,7 +215,8 @@ static u64 make_spte_executable(u64 spte) * This is used during huge page splitting to build the SPTEs that make up= the * new page table. */ -u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, int index) +u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, int huge_lev= el, + int index) { u64 child_spte; int child_level; @@ -243,7 +244,7 @@ u64 make_huge_page_split_spte(u64 huge_spte, int huge_l= evel, int index) * When splitting to a 4K page, mark the page executable as the * NX hugepage mitigation no longer applies. */ - if (is_nx_huge_page_enabled()) + if (is_nx_huge_page_enabled(kvm)) child_spte =3D make_spte_executable(child_spte); } =20 diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 73f12615416f..e4142caff4b1 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -415,7 +415,8 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_pa= ge *sp, unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn, u64 old_spte, bool prefetch, bool can_unsync, bool host_writable, u64 *new_spte); -u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, int index); +u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, int huge_lev= el, + int index); u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled); u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access); u64 mark_spte_for_access_track(u64 spte); diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 566548a3efa7..03aa1e0f60e2 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1469,7 +1469,8 @@ static int tdp_mmu_split_huge_page(struct kvm *kvm, s= truct tdp_iter *iter, * not been linked in yet and thus is not reachable from any other CPU. */ for (i =3D 0; i < PT64_ENT_PER_PAGE; i++) - sp->spt[i] =3D make_huge_page_split_spte(huge_spte, level, i); + sp->spt[i] =3D make_huge_page_split_spte(kvm, huge_spte, + level, i); =20 /* * Replace the huge spte with a pointer to the populated lower level diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 665c1fa8bb57..27631c3b53c2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4286,6 +4286,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, lon= g ext) case KVM_CAP_SYS_ATTRIBUTES: case KVM_CAP_VAPIC: case KVM_CAP_ENABLE_CAP: + case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: r =3D 1; break; case KVM_CAP_EXIT_HYPERCALL: @@ -6079,6 +6080,28 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, } mutex_unlock(&kvm->lock); break; + case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: + r =3D -EINVAL; + if (cap->args[0]) + break; + + /* + * Since the risk of disabling NX hugepages is a guest crashing + * the system, ensure the userspace process has permission to + * reboot the system. + */ + if (!capable(CAP_SYS_BOOT)) { + r =3D -EPERM; + break; + } + + mutex_lock(&kvm->lock); + if (!kvm->created_vcpus) { + kvm->arch.disable_nx_huge_pages =3D true; + r =3D 0; + } + mutex_unlock(&kvm->lock); + break; default: r =3D -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index dd1d8167e71f..7155488164bd 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1148,6 +1148,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_PMU_CAPABILITY 212 #define KVM_CAP_DISABLE_QUIRKS2 213 #define KVM_CAP_VM_TSC_CONTROL 214 +#define KVM_CAP_VM_DISABLE_NX_HUGE_PAGES 215 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C944BC433F5 for ; Wed, 13 Apr 2022 18:02:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237659AbiDMSEc (ORCPT ); Wed, 13 Apr 2022 14:04:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237606AbiDMSC2 (ORCPT ); Wed, 13 Apr 2022 14:02:28 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E939241611 for ; Wed, 13 Apr 2022 11:00:04 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id m11-20020a170902f64b00b0015820f8038fso1519346plg.23 for ; Wed, 13 Apr 2022 11:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=3UKcgaouWDljoBhDJNavl7iHJ9K4UWQ5k+7D01IUkUU=; b=i1LjNyj0MfWmClJT9PfmfWxlCGWG1mhzWBvkSRz4Hwmt2mE12WeqUlJ2ktSPAWym7p 2lceXs2Ff5HmbmubdwUFXPqbvPDNnD26dUUz3C7nKYW7Ol8ZGz+TbasHddOngbsv7M22 Rm/Y0C4ulAOrpjWMCxARkkPhjEhweZ4zzLmh8WlRzPD1u3nnikEzmmsLLOjl55/0cX7q iHd2HBP9IcAQB5JXMMA0yM38wgkXg5F5vQEyZB/0/z5egSRt9khEg/oS6WW8O7J+ofNb Lrg9o+7uJpBVNv+QEYewY6Okig2iZRfkaYE+KIPpM+aWuc5zOYfbj7Hy6R0awrlbI1tW B4JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=3UKcgaouWDljoBhDJNavl7iHJ9K4UWQ5k+7D01IUkUU=; b=53XOC/3hJvcH1+aoJlfnctkmxcmlH7odjEwBH1P5CR7251MHuqdib7RcmA7LLKv7rk oMs+wxAdDMhi8hlM4R7+iQqOoHDUQl/RNjBntbvOxcbJpKXnFKm3Wp9+ucdXzobIA5C6 lvGT81lM2xi73nChkwRzIb7aVdB/I2mc9CukhQ5c7xUrwNQ95QUmlKlZnQYZJqFHwkET jUPfhaJT30af/8qBFov54g9wLdnWejiBk6jA3UVW8+cMC09clQldlQFgrhBRpXGpCbJ6 MzU4w6r/2fidvBhd8CRRTIj460kMO04Mf6A2KXY6GzvhtYRom7R1qllaDnmcy37RlYgO Kh3w== X-Gm-Message-State: AOAM533+M3ZdJfQ1Tsxe9BriPh8cW7HM5Jpl0dh5XPfp9zbF5Pvl0VoW 75s71BWrhFfotYJWL0xrru+znJogqy4VY2vjUPssypP6yUO6DdPQG8dhIRgschNQ2jLWwdzPdD/ m9Cu5f9Lyr1Wima0CB+pKIO/emwwHhp3auqHol4KvxUM2fkkb3EWlnFplcx7KyK6xJm0/h526 X-Google-Smtp-Source: ABdhPJxEgv3bZO/MXBspajYZ97mvWEzxbBffsN8qoEnCjAE++uaayaerZdHkHynBoa07zL4ad89k0EzRJ/Ns X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a05:6a00:22c7:b0:505:9c6e:de39 with SMTP id f7-20020a056a0022c700b005059c6ede39mr23398922pfj.79.1649872804260; Wed, 13 Apr 2022 11:00:04 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:43 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-10-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 09/10] KVM: selftests: Factor out calculation of pages needed for a VM From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Factor out the calculation of the number of pages needed for a VM to make it easier to separate creating the VM and adding vCPUs. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/include/kvm_util_base.h | 4 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 59 ++++++++++++++----- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 001b55ae25f8..1dac3c6607f1 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -312,6 +312,10 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_= t num, vm_paddr_t paddr_min, uint32_t memslot); vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm); =20 +uint64_t vm_pages_needed(enum vm_guest_mode mode, uint32_t nr_vcpus, + uint64_t slot0_mem_pages, uint64_t extra_mem_pages, + uint32_t num_percpu_pages); + /* * Create a VM with reasonable defaults * diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index d332f02370d1..5ffed44ab328 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -377,7 +377,7 @@ struct kvm_vm *vm_create_without_vcpus(enum vm_guest_mo= de mode, uint64_t pages) } =20 /* - * VM Create with customized parameters + * Get the number of pages needed for a VM * * Input Args: * mode - VM Mode (e.g. VM_MODE_P52V48_4K) @@ -385,27 +385,17 @@ struct kvm_vm *vm_create_without_vcpus(enum vm_guest_= mode mode, uint64_t pages) * slot0_mem_pages - Slot0 physical memory size * extra_mem_pages - Non-slot0 physical memory total size * num_percpu_pages - Per-cpu physical memory pages - * guest_code - Guest entry point - * vcpuids - VCPU IDs * * Output Args: None * * Return: - * Pointer to opaque structure that describes the created VM. - * - * Creates a VM with the mode specified by mode (e.g. VM_MODE_P52V48_4K), - * with customized slot0 memory size, at least 512 pages currently. - * extra_mem_pages is only used to calculate the maximum page table size, - * no real memory allocation for non-slot0 memory in this function. + * The number of pages needed for the VM. */ -struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_v= cpus, - uint64_t slot0_mem_pages, uint64_t extra_mem_pages, - uint32_t num_percpu_pages, void *guest_code, - uint32_t vcpuids[]) +uint64_t vm_pages_needed(enum vm_guest_mode mode, uint32_t nr_vcpus, + uint64_t slot0_mem_pages, uint64_t extra_mem_pages, + uint32_t num_percpu_pages) { uint64_t vcpu_pages, extra_pg_pages, pages; - struct kvm_vm *vm; - int i; =20 /* Force slot0 memory size not small than DEFAULT_GUEST_PHY_PAGES */ if (slot0_mem_pages < DEFAULT_GUEST_PHY_PAGES) @@ -421,11 +411,48 @@ struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mod= e mode, uint32_t nr_vcpus, extra_pg_pages =3D (slot0_mem_pages + extra_mem_pages + vcpu_pages) / PTE= S_PER_MIN_PAGE * 2; pages =3D slot0_mem_pages + vcpu_pages + extra_pg_pages; =20 + pages =3D vm_adjust_num_guest_pages(mode, pages); + + return pages; +} + +/* + * VM Create with customized parameters + * + * Input Args: + * mode - VM Mode (e.g. VM_MODE_P52V48_4K) + * nr_vcpus - VCPU count + * slot0_mem_pages - Slot0 physical memory size + * extra_mem_pages - Non-slot0 physical memory total size + * num_percpu_pages - Per-cpu physical memory pages + * guest_code - Guest entry point + * vcpuids - VCPU IDs + * + * Output Args: None + * + * Return: + * Pointer to opaque structure that describes the created VM. + * + * Creates a VM with the mode specified by mode (e.g. VM_MODE_P52V48_4K), + * with customized slot0 memory size, at least 512 pages currently. + * extra_mem_pages is only used to calculate the maximum page table size, + * no real memory allocation for non-slot0 memory in this function. + */ +struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_v= cpus, + uint64_t slot0_mem_pages, uint64_t extra_mem_pages, + uint32_t num_percpu_pages, void *guest_code, + uint32_t vcpuids[]) +{ + uint64_t pages; + struct kvm_vm *vm; + int i; + TEST_ASSERT(nr_vcpus <=3D kvm_check_cap(KVM_CAP_MAX_VCPUS), "nr_vcpus =3D %d too large for host, max-vcpus =3D %d", nr_vcpus, kvm_check_cap(KVM_CAP_MAX_VCPUS)); =20 - pages =3D vm_adjust_num_guest_pages(mode, pages); + pages =3D vm_pages_needed(mode, nr_vcpus, slot0_mem_pages, + extra_mem_pages, num_percpu_pages); =20 vm =3D vm_create_without_vcpus(mode, pages); =20 --=20 2.35.1.1178.g4f1659d476-goog From nobody Mon May 11 05:35:00 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE2F1C433F5 for ; Wed, 13 Apr 2022 18:01:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234950AbiDMSD3 (ORCPT ); Wed, 13 Apr 2022 14:03:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59114 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237609AbiDMSC3 (ORCPT ); Wed, 13 Apr 2022 14:02:29 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B484141F9D for ; Wed, 13 Apr 2022 11:00:06 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id y3-20020a17090a8b0300b001cb4831a8fbso4108977pjn.1 for ; Wed, 13 Apr 2022 11:00:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Gy/3X4u6MXYQtgeHNH5kjdgpJgGkBIMGxlSxtIk71CY=; b=jeGlCKN9OtluiB/5f/mJ9LQLzPoIDA1Wo+ibNZbKfTzUBIfygIxTfP4/+r2jKj+CP8 sHxurmH0mY3yJKOKlNTH+0RoAMkUitaxWjrqDItdQ8HCkNO9wFU5kl944VOmC4Lvlo3X r2HpwlzwF6RnQ/Tfv7u6VF/GTdN8H4GGtWRExbNtz2clbV3GLugVjcADcv+pCUVZdkrw K+0yVf6TK7pTD7kbO+s+2ZV8D1h6oEb3bGTwVwYKdD4l2A9xUSoTnCF3pbXMxpy0gILc hKKFOAP4IeC7EJtvsikgfNdxnSetjqRxOfjbQ1nQyYifBugi0k5an28llAE9HQUgS2Ws eDZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Gy/3X4u6MXYQtgeHNH5kjdgpJgGkBIMGxlSxtIk71CY=; b=cvX6aRKgNHLDPtp0jIJyJzVwvCT7p6c8Xde+DeMe2exrjohVj1grXFwZSOy4zzd3kr Y09aXuyTgH2aIpsI0elLuLHOrsbAmzeUgkgUx/9/8/TC85RKjpvQQC/pdeXWUbBFGYjP y0Be8xNoECnK3IUdbLxA7d43sHBnFk8vIlAntgYyVtli/RALOuWwnRreLDhwO9EQHZPb PRPWmfc3/yPV5k9QpGyxjeeq2+Ko1Flhy0ORz/bKLeMr21s+YmOU4eQ9iQ7LirMbG1BW XM+bML361UreWupZFbIRCuH2ubNDyLX2fN9PEW7u3vQlMcuGnw572sVDsyhMHxSkHDk9 e86A== X-Gm-Message-State: AOAM532kO5gUnw6W7vPRk+8m/pl6/RospZRatF5NFZty49DFkRGMYSXk 35mwbaWti5lCEamGvTWF3KiScw+h8NwK3dtxtMlD7UFq8hbZFnNTGkk+/iFg8F2AQl8bTftYzYX VxJm6u6sJ71ad2lmma4DsAemqUhTsw7WDUS8xlw0i47+llLmFu6dusgFZJ0QduetiKrkfdd2X X-Google-Smtp-Source: ABdhPJwdQGF6KfkCW4KBWs4LWsNAoyhQDkcsu5V93bneH+RboPTeqdazql3ja8rt6ulHljKweQjRBB7F9n2e X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:c087:f2f2:f5f0:f73]) (user=bgardon job=sendgmr) by 2002:a05:6a00:3406:b0:505:7a1c:c553 with SMTP id cn6-20020a056a00340600b005057a1cc553mr30393pfb.2.1649872806122; Wed, 13 Apr 2022 11:00:06 -0700 (PDT) Date: Wed, 13 Apr 2022 10:59:44 -0700 In-Reply-To: <20220413175944.71705-1-bgardon@google.com> Message-Id: <20220413175944.71705-11-bgardon@google.com> Mime-Version: 1.0 References: <20220413175944.71705-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v5 10/10] KVM: selftests: Test disabling NX hugepages on a VM From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an argument to the NX huge pages test to test disabling the feature on a VM using the new capability. Signed-off-by: Ben Gardon Reviewed-by: David Matlack --- .../selftests/kvm/include/kvm_util_base.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 16 ++++- .../selftests/kvm/x86_64/nx_huge_pages_test.c | 62 +++++++++++++++---- 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 1dac3c6607f1..8f6aad253392 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -414,4 +414,6 @@ uint64_t vm_get_stat(struct kvm_vm *vm, const char *sta= t_name); =20 uint32_t guest_get_vcpuid(void); =20 +int vm_disable_nx_huge_pages(struct kvm_vm *vm); + #endif /* SELFTEST_KVM_UTIL_BASE_H */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 5ffed44ab328..ef01858745e9 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -112,6 +112,11 @@ int vm_check_cap(struct kvm_vm *vm, long cap) return ret; } =20 +static int __vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap) +{ + return ioctl(vm->fd, KVM_ENABLE_CAP, cap); +} + /* VM Enable Capability * * Input Args: @@ -128,7 +133,7 @@ int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_= cap *cap) { int ret; =20 - ret =3D ioctl(vm->fd, KVM_ENABLE_CAP, cap); + ret =3D __vm_enable_cap(vm, cap); TEST_ASSERT(ret =3D=3D 0, "KVM_ENABLE_CAP IOCTL failed,\n" " rc: %i errno: %i", ret, errno); =20 @@ -2740,3 +2745,12 @@ uint64_t vm_get_stat(struct kvm_vm *vm, const char *= stat_name) stat_name, ret); return data; } + +int vm_disable_nx_huge_pages(struct kvm_vm *vm) +{ + struct kvm_enable_cap cap =3D { 0 }; + + cap.cap =3D KVM_CAP_VM_DISABLE_NX_HUGE_PAGES; + cap.args[0] =3D 0; + return __vm_enable_cap(vm, &cap); +} diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tool= s/testing/selftests/kvm/x86_64/nx_huge_pages_test.c index 7f80e48781fd..21c31e1d567e 100644 --- a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include =20 #include #include "kvm_util.h" @@ -80,13 +82,45 @@ static void check_split_count(struct kvm_vm *vm, int ex= pected_splits) expected_splits, actual_splits); } =20 -int main(int argc, char **argv) +void run_test(bool disable_nx) { struct kvm_vm *vm; struct timespec ts; + uint64_t pages; void *hva; - - vm =3D vm_create_default(0, 0, guest_code); + int r; + + pages =3D vm_pages_needed(VM_MODE_DEFAULT, 1, DEFAULT_GUEST_PHY_PAGES, + 0, 0); + vm =3D vm_create_without_vcpus(VM_MODE_DEFAULT, pages); + + if (disable_nx) { + kvm_check_cap(KVM_CAP_VM_DISABLE_NX_HUGE_PAGES); + + /* + * Check if this process has the reboot permissions needed to + * disable NX huge pages on a VM. + * + * The reboot call below will never have any effect because + * the magic values are not set correctly, however the + * permission check is done before the magic value check. + */ + r =3D syscall(SYS_reboot, 0, 0, 0, NULL); + if (r && errno =3D=3D EPERM) { + r =3D vm_disable_nx_huge_pages(vm); + TEST_ASSERT(r =3D=3D EPERM, + "This process should not have permission to disable NX huge pages"= ); + return; + } + + TEST_ASSERT(r && errno =3D=3D EINVAL, + "Reboot syscall should fail with -EINVAL"); + + r =3D vm_disable_nx_huge_pages(vm); + TEST_ASSERT(!r, "Disabling NX huge pages should succeed if process has r= eboot permissions"); + } + + vm_vcpu_add_default(vm, 0, guest_code); =20 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, HPAGE_GPA, HPAGE_SLOT, @@ -121,21 +155,21 @@ int main(int argc, char **argv) * to be remapped at 4k. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 1); + check_2m_page_count(vm, disable_nx ? 2 : 1); + check_split_count(vm, disable_nx ? 0 : 1); =20 /* * Executing from the third huge page (previously unaccessed) will * cause part to be mapped at 4k. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 1); + check_split_count(vm, disable_nx ? 0 : 2); =20 /* Reading from the first huge page again should have no effect. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 1); + check_split_count(vm, disable_nx ? 0 : 2); =20 /* * Give recovery thread time to run. The wrapper script sets @@ -148,7 +182,7 @@ int main(int argc, char **argv) /* * Now that the reclaimer has run, all the split pages should be gone. */ - check_2m_page_count(vm, 1); + check_2m_page_count(vm, disable_nx ? 3 : 1); check_split_count(vm, 0); =20 /* @@ -156,10 +190,16 @@ int main(int argc, char **argv) * reading from it causes a huge page mapping to be installed. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 2); check_split_count(vm, 0); =20 kvm_vm_free(vm); +} + +int main(int argc, char **argv) +{ + run_test(false); + run_test(true); =20 return 0; } --=20 2.35.1.1178.g4f1659d476-goog