From nobody Sun May 10 12:46:32 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 EFFFDC433EF for ; Tue, 3 May 2022 18:31:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241413AbiECSea (ORCPT ); Tue, 3 May 2022 14:34:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241397AbiECSe0 (ORCPT ); Tue, 3 May 2022 14:34:26 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DB473F881 for ; Tue, 3 May 2022 11:30:51 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id t70-20020a638149000000b0039daafb0a84so6200998pgd.7 for ; Tue, 03 May 2022 11:30: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=o+9dMFvOF/uQRsa+w9rvsKEr6Xu+97MPujOp8DaGSWQ=; b=YNVFwxmLSNwpDixl0NaC6u+hi3RLewRjZw6w0PQzTlNHNib/cU4B/YuckuLd5QLD6p HVsvUBbA9EWG6nhe3m8NWTJe65BzEdLYthpilNYdljmvCHp21qV8ITvxhU3O8rOXNPU7 mWa3xJbF8ug7i74BXDuKlC8DvXtwvL0J434gPAs4fL5np+kbRd0MGV1dxp3zLGiE5uip xKrI5eM3XhZ6f8zN7Ru8mq9+s4MeB6X/huooRGHOlxkS3eWZLDAYWmbQbyoPMZZEvWHJ 9XFc9qSjB1D5EHk2mvmGCAwb7XMTqEY5HWhpB7dyMlLLXpKXKnV9yrtYSTJ8EI/Aze+q Rznw== 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=o+9dMFvOF/uQRsa+w9rvsKEr6Xu+97MPujOp8DaGSWQ=; b=V88Lh3N3jPCN4qfEETmwO2KZwS6gAJwRLouEVAbm/D+loX8JUqHBWX4eRCPZ5fE3wH R5Ql0zMchLFbmj6+MtmgpPhOSByjxoPQOC8zXwgcJcylS9NDclw7+SolFpO2NCBSGXdQ CbDnGdFdR8+rKFttj3/vVG9fIbL2k3+sTItIBlpTqFPEZFhnfZeb6R68XPDEMiHaFqFa ZO56rg6inNgRuflV2T0vseOoHyOMEDM3VSM+a5TwzGN5h+38uDaeZN8BZ1/RXQeUUzMA N1eLON6pVLQol6IJzVmsldit9k3J7dxBjzl3N46onhJb018DiVExyWsiZNjt1ZaOHims L0pg== X-Gm-Message-State: AOAM530869rFgpfrLb9R4YKkMtgYr+tbaL08Fet4Q+RVhdbQGmyk7LA6 XkDCQ+XPzsjtNkpo+tUP8iMHPhluTRAhaMAHrnIZJjkUJfnzHeO8nGPUPD6bcjXUk5J/tM5XB4+ /7jCsiGIwv5IQnbAru+sJEZlesaMCfHdXT8mCDyV24Cdu6DoFJE24WMEWFIV955s3AGWMqqL+ X-Google-Smtp-Source: ABdhPJzAPuswW5dNUvPFhVFDcBZIKWoohMUIvkWvdkD2Vp5/L6y6iZnIn+DTXhC9gGYHxuP4pn8UbDdXs+gR X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:902:e5cc:b0:15e:b8b2:25be with SMTP id u12-20020a170902e5cc00b0015eb8b225bemr3558167plf.27.1651602650362; Tue, 03 May 2022 11:30:50 -0700 (PDT) Date: Tue, 3 May 2022 18:30:35 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-2-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 01/11] 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. Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- .../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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 3480FC433EF for ; Tue, 3 May 2022 18:31:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241381AbiECSee (ORCPT ); Tue, 3 May 2022 14:34:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241376AbiECSe1 (ORCPT ); Tue, 3 May 2022 14:34:27 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE6823CFDA for ; Tue, 3 May 2022 11:30:52 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id t24-20020a17090a449800b001d2d6e740c3so1669289pjg.9 for ; Tue, 03 May 2022 11:30:52 -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=ZlzC2bfcuGT4kbRVJ38+TB0qj+KtuXSymHV+fLhrqvw=; b=UNVc0C+eq6p83NWSllrNv5vO03WvpL18Ik3qfB7ruLNFwQwMaEJ7qiP+UQSUliQEHD /PJbDZ2K7y0ewOQnSfElgAi1UW+ZUKv1uIGszPfnGnNGF88dKsO+x0GQiovhA2qNCxh/ E59XRfRAAKtt6wXhFVgTFSDW8u7JBcT7w9Tycxlp73UKrVAIaNPVkH5Drz0bLR7QuAw+ 8585xvagTNnO58b4HSSyt7VaVRsftRAKSj0wOaarjX7xJxn3SPE0DHaD2FSbEMXxYWOd i+SIr1gkIH+fH4gIW4vscRog7xH7cvmiMqAw/5sA+OIIEdOkt2Jk7HOkVx8SSs+Yv0NW Jc+A== 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=ZlzC2bfcuGT4kbRVJ38+TB0qj+KtuXSymHV+fLhrqvw=; b=a+w9YVbAhCArMhpZtHp02WoKWszZKDPpW+zsrD9VOvO+PQVmN78Ubz8H0yfO4Q1Xsr bYqbjzWZZHt1unbOHvLQyaEhUobHRsvGLq4SkVF7+b9x4v0oMH6cr5b4DNSY4aup+7CY cSZSm5hHYqYU9mYzLHCTsoRdIBf3XI6v5DMTd6Fh9rU2vG6kPQ1xuN0svYYglC/7KJmp uoYLGbkViZc3nE8RSd3uo+LLVAtsmLgYtf+n1ITTc4gb1ceDYwhuBl+ynV3L0rdj73t/ JR7ee0+Q1YwTmJWSny6zBEPQ5ALo7uFE/s7/rsoqNChVv4zcA78sfMDuXsqW5mO7Kviq F4KQ== X-Gm-Message-State: AOAM533oHrPRx/me3yxeiFae7hjW5aWtc2eouFIIu1BGavU0QXB1LlXz XvgAXw1c2PIBZb37LIamuR6MJcf8ZPdwUhHtbN09GjLs87mZxS+u5ycca/yp+iIjY94/wYBzIS+ icpQyBSwlqlHHh3OGPKpVk1OBXK1L/wE21QlSEvPgRWooGu3Cv6/gLLJ85kiHRVtq10SAwy1e X-Google-Smtp-Source: ABdhPJw65eq8HHy3awj9KFCl7Lo1isD3it+/ihQmFligXTbVgbokMql8ff24EbJ+Pn0P6xQorDV+TVbhf55l X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a05:6a00:1991:b0:50e:697:53f9 with SMTP id d17-20020a056a00199100b0050e069753f9mr6097951pfl.22.1651602651975; Tue, 03 May 2022 11:30:51 -0700 (PDT) Date: Tue, 3 May 2022 18:30:36 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-3-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 02/11] 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. Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- .../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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 03663C433EF for ; Tue, 3 May 2022 18:31:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241433AbiECSej (ORCPT ); Tue, 3 May 2022 14:34:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241425AbiECSe2 (ORCPT ); Tue, 3 May 2022 14:34:28 -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 9832B1EAC0 for ; Tue, 3 May 2022 11:30:54 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id j11-20020a05690212cb00b006454988d225so16121503ybu.10 for ; Tue, 03 May 2022 11:30:54 -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=3/QOXmo+jSd7MUY1n1sbQqzuMbb/wqCHqK/oyoJG464=; b=XzuEAgapJuZ4gslUfI9xP5hZtQX0BO5IYLc1XWxKwO4vFs3yQJf1/JEgC4P2C6ayu5 c8zFJkqvyVOTDBI39Gge7pWgFPx6xwujBMf1VH/O27lsSOvvWwrrm2/99tn/wfV+5uAI i+RWF5TtAeOzVZrEeaG7/k1bJHWAqkTBoA0m2ha6ACTyCVWJdT/39IJh2yK47nHVKmAp JCJuyKLpZDyZu4I/tWolCNP2unndLsRUSPeY0FPde4d2d+y2QgdfczGOFMi19UJ/SUVN NxCMnl+oVGFEcuswZHxQaGQ8lN1T2qlyKnhzjKXMZbX9mi7zIdFB0tZF6GnZ7lBPCsSS goRg== 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=3/QOXmo+jSd7MUY1n1sbQqzuMbb/wqCHqK/oyoJG464=; b=WNGGTZUaYXs4YxNOhqmEHtabFG3qd1C7OOolueCRojocU1AgbvmJLCvUkQrjN1dD8t hQNqy+fxHwH6E9y0HaEqlFnFzapBnBNm/4fwpmiIG7mr76polYVspS08QuXXgSDfJPRf CWcxm9dy8GlDTgVSE3gILyKaHbz7BYc2IPotnoef63CQsFAGOqRJE+Osb/suAmRvqVkn sAiLuHrDfskGFubJ6jugJdmx0SrKpGoqI/uLSyS/OUy/YHh5RsVKNs+l8Ea7h6ajhQwZ wTY2Mxd1M0Bqazy49pRmHUPy/fXKo1IIU/WkBKohhguUW4JCO0AVLVWAqD5kbTYc3gqS k1CQ== X-Gm-Message-State: AOAM533MJf9kQCvd+pJGIY/hlyV4o91euKIC9PLjDLiliKtcKJUXt9Ux AKgquwolwy1fqtq+WaucO1lxT4A09uK5YY6y9JhstuMuNcmON12dZoHUO/tp0Q3xWwmQjJZFqmt FQlCd6+aO8QsDhmoB0Dc0snspr0vZRTPYnmtfz4518WI76nXjGjCilhZgGnrgmf8recGeB2ms X-Google-Smtp-Source: ABdhPJzOdIxW1iRe2vRKUNc/Nj7MyA6lA4aRxsBwZOdbYZZvrJz2siQXwDQza6mdWwtDSaTyeF/70nWoEP+4 X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a05:6902:703:b0:649:3ed0:a132 with SMTP id k3-20020a056902070300b006493ed0a132mr16872059ybt.185.1651602653774; Tue, 03 May 2022 11:30:53 -0700 (PDT) Date: Tue, 3 May 2022 18:30:37 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-4-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 03/11] 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. Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- .../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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 EC818C433FE for ; Tue, 3 May 2022 18:31:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241439AbiECSeu (ORCPT ); Tue, 3 May 2022 14:34:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241454AbiECSe3 (ORCPT ); Tue, 3 May 2022 14:34:29 -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 DF6D81EACB for ; Tue, 3 May 2022 11:30:55 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id m11-20020a170902f64b00b0015820f8038fso8220553plg.23 for ; Tue, 03 May 2022 11:30: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=ZcTa31/SHnSC3s49aeO+K0dpZ+qhe9XO6pQANg17BXs=; b=a/uhsK4RxHQP14ztHfIBSg/ZakJ/fA1TktE7S4+NmjsAWXMvT7CHxbvRcXbpPxTnI4 FJ7DNFpnR2rgysgV3lab22Gx49Y8jYUzy/PyiIfY2+lC9hkVtENJiHwOzbtSZSC5h1Jn TVGZ4o3FY5VoGf1OBlTVKhdZusATR7tfAKQXdUmslb9QWP5LjXzYNmQauFLTPDIWGJzl VeMF3MPtyRQw1DOx+azwWeB6ffJSJelEpeH7m65S/xoY9ziCjS866cesm5Uydxousnvz Q4ypxTqYWCcii2ghtZMepBSSe9GlGH+4dc5x9x9sKzkWXPRZE6pauzBo5e8+tWP381u3 kxqg== 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=ZcTa31/SHnSC3s49aeO+K0dpZ+qhe9XO6pQANg17BXs=; b=Yfaqpe7/xIKxrmND7ErmF6L4UnEaBHS8UpVM0wcM2uKF/Cfeoc/yMS6mcNF+Xa+NGX O7w8OQ4CijuECQlFWNQRbNWW6qzi7BI9uK9kzvKEa8cz8ud8NC8iCqTvqXx669jjuDLr 0haRoHFc4jW4xOIL3apPtkUJaG5jHQOvawmPKe31h2dPIZdjOuO96YT0Jt5Klmj+5tHH RhwAE886yi57JO/+4ftTv5LBkGM1yzpB84KrXtILvXmuusdpj6u4VIpwYB5hWHsim0MS qdBF8B2FQ/I5sUWW36nHVicJkU5MdGwY8ALqWrg1EuH3IfE4nJbBnQxAhy4368i7AAgr PxGQ== X-Gm-Message-State: AOAM530hPhzoijrLCqWAa/mdDrbqLf5JLPnrN9Fi4topvJDNIXM19qIV cx3AJd5FukU4POYs3AHU9Ai6cZYbEw1KSqY/rSCm4J2v1GB7nnj5bFNls3gmyKl2vkCC8AT3Nz9 aV2vB7/14s7vAbii7O7KShHsoUR9vLi2QnD/GrAHhUm289wxYngWuNF0AbUROQgbXNFn+nxFy X-Google-Smtp-Source: ABdhPJwKNcoCpu+ARCo6tvNf0QQNqqET3WtWsj+SzdxHk4KQcXVPUEr+UmdvoeaImFrUbpaNsddEqZnU1Gtb X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:902:8644:b0:15a:3b4a:538a with SMTP id y4-20020a170902864400b0015a3b4a538amr17965247plt.146.1651602655150; Tue, 03 May 2022 11:30:55 -0700 (PDT) Date: Tue, 3 May 2022 18:30:38 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-5-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 04/11] 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 Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- .../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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 4F976C433FE for ; Tue, 3 May 2022 18:31:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241532AbiECSex (ORCPT ); Tue, 3 May 2022 14:34:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241457AbiECSea (ORCPT ); Tue, 3 May 2022 14:34:30 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C4B71EAC4 for ; Tue, 3 May 2022 11:30:57 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id r204-20020a632bd5000000b003c1720b306bso7644849pgr.8 for ; Tue, 03 May 2022 11:30: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=F1YFA94P1++LikfS1g8U/kKLAsz7yw4a/MvxHPVvBOI=; b=LRHBMVUxHaAXjbu6bocKLBht9ff7SwaBfohWLxDr8xiB3shAvodzjiD31TjLPVffiT PfRUafOYAZNXw9UD6jS7CznHlLRSFfDnwPjhjF9cCwoLCV8TWiV7gBvYxAfP30z9egyy IC0uChw5HdzSJs/VUBoG/fyESxizHbHkSCfCJLZWVti1HDYzQD1oDE6rjlB9pfou1cys uykjtPh0b6vMwgepGrQhJUQT9K9XmeBRKkUXBy3UqXM7lj0OfSKErqoRy7WvwjAoNmPn YXczqIg2rIVt493Y5FYxC71tN2kjXk+Y2IbZKhjpLMwjp7mzN4Z/K3ARhC1vvqmAHXoU epMg== 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=F1YFA94P1++LikfS1g8U/kKLAsz7yw4a/MvxHPVvBOI=; b=jo5xdCFNfFSBTe+mN+K0kM75uu0U2TpqpI2UgDeplFm88aZDrR8pLW1TYhC8Rv8Za3 mmKALmMZ4ROGHiSNxfnam3bYJD+jhnPNkSdvQcl6AY5MgLaOvdhz70xia+t7OG03ApIY UDo02C27MaBq1bYZpXm12LU3zw+CCr34Zd79spSuHf+BPt6C0qIuheQytRgVjZFWeGCr X0C/nLf0tD0MxgcZir27FvXTgXsL2PceETTsS9TNeMm79qBahCZcxBuGzG43sH3LYLKQ X9SpdpmK0fMvPOapT7KiqxZUetOP+RybdvdBu7qIJTAQreoK9yScuOTIGV2xAoYnfn72 nOWw== X-Gm-Message-State: AOAM533SaSeWE+LiKHYg7FXppCmRFrreMM7Yj9RAy1dX5dELyWf1GACo +qcr9vO5ztGNpE7GBmLMPN8PFjgup0Hpqf0JOfjR10RXmbQCUI3XQene8A6FrG71RR0fmaatbMM rFebfXbduIpBn4VA0Qa9gwUIo5SpqCBOBLY0P5C0pGBK9d4/S/AaSDxUZd5wig+hAez+0l1a3 X-Google-Smtp-Source: ABdhPJxb5sHYMrvzaFL/U4Z43+cSJQgwNTQaJ89YOGdvUtVxphK9ndXvdKQurfkNV32hZuqagK95Y6FoPWi1 X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:90b:245:b0:1dc:1597:20e with SMTP id fz5-20020a17090b024500b001dc1597020emr6089939pjb.151.1651602656813; Tue, 03 May 2022 11:30:56 -0700 (PDT) Date: Tue, 3 May 2022 18:30:39 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-6-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 05/11] 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. Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- .../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..ea4ab64e5997 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_t(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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 54E07C433EF for ; Tue, 3 May 2022 18:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241500AbiECSfB (ORCPT ); Tue, 3 May 2022 14:35:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241440AbiECSel (ORCPT ); Tue, 3 May 2022 14:34:41 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C41E3F880 for ; Tue, 3 May 2022 11:30:58 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id l72-20020a63914b000000b003c1ac4355f5so5609966pge.4 for ; Tue, 03 May 2022 11:30:58 -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=ZYsDGkjzJMEUY489cF/q4E8fpSxjDZsZ+buXTqonbtQ=; b=MemcUGAjEMah/ZaTJ/CJrMnizulS8u5+PqEXQAS6VyPYkayFha1FMan+n2ae2uoLk5 fBHZc6QmURA/9x+oypg7YqEEUi1jD62/oG0C/s5ogIPykDI+huJJ5UpKeLAd4vadYnjC Rpg4PxLWuKbECt/bIXRK4g0iIix5yL1ISqZxZBX2jA3EFUlXwPU6pbaqsS7j2iIT6nbG Td0LdiymwsJzvaE2tmNM1bXeNyezjeLDo6Q7QAuqDvxmUcKC5Ew5JUVpoAP7/m/fr0+n yVXP0ZcIfPR8jyKkRpjeaTWKzu9sl67ljXhAYlMJ7Fmn6RI3FbgW4jV7w7ZEuYlP9Kmr WXPQ== 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=ZYsDGkjzJMEUY489cF/q4E8fpSxjDZsZ+buXTqonbtQ=; b=msqM7Wv0IH1T3RAyC1zefM+gOexqf5yxbJr1vzVQAFhoNbIIgpG1VdHCPDqpHuqSJZ mFEFmv58qGsRsh2BUBcQRXW6AYvXIISjPodcMBriYqctgogXCOXtxL8uOSibroxPKXRz h00zbUvF3ZSA5e2Xa9a6EnQ+Mwj1b4oAOAFlQURqDGbfZy9gusz9KaSvNEJVD8psnRNJ i008FIwPLqQJngwAO/MMePk4oD3BP/cPWK8un0K38EGpsTWiFLlkeMw7+5FrKW1Kx2Oh oDbvyB/iNpHEFjOhlaM52shnDrLCOOjGJ6bAgMjhhRglu3+Ykzey1YVQaEtXRpOU62uC SXxQ== X-Gm-Message-State: AOAM530aAFPITdhmrJAEgbz930gUIESEM1MPIU5trX/fSWUZN6a8ottK z5M8jhnIPtut2Ra2hIR9j3eLVK/ro7jxoV0uH6ml0Eue1Pn8medNnsm0Aqpce2QqZB2TR21TMiO c2B7H7i6Org79Tj19g5QefK0mjm8V851S+uJ9w1NQjoOqL09rDCAxvhAMlGnr3Z41waanErHr X-Google-Smtp-Source: ABdhPJyTHHW1fKXQc0wpqNze6EuL/2Uice8+pEklKwuKfKFb5+O/Kd+Ze6OcTmTVNTB6pHOd4KUzK/cWTGbB X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a05:6a00:2348:b0:50d:9be4:4c02 with SMTP id j8-20020a056a00234800b0050d9be44c02mr17572857pfj.5.1651602658269; Tue, 03 May 2022 11:30:58 -0700 (PDT) Date: Tue, 3 May 2022 18:30:40 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-7-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 06/11] 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. Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/Makefile | 10 + .../selftests/kvm/include/kvm_util_base.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 80 ++++++++ .../selftests/kvm/x86_64/nx_huge_pages_test.c | 180 ++++++++++++++++++ .../kvm/x86_64/nx_huge_pages_test.sh | 36 ++++ 5 files changed, 307 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 ea4ab64e5997..6930ba298170 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2651,3 +2651,83 @@ int read_stat_data(int stats_fd, struct kvm_stats_he= ader *header, =20 return ret; } + +/* + * Read the data 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 + * 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. + */ +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); + + break; + } + + 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..238a6047791c --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -0,0 +1,180 @@ +// 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 + +/* + * Passed by nx_huge_pages_test.sh to provide an easy warning if this test= is + * being run without it. + */ +#define MAGIC_TOKEN 887563923 + +/* + * 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. + * + * See the below for an explanation of how each access should affect the + * backing mappings. + */ +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 huge page 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; + + if (argc !=3D 2 || strtol(argv[1], NULL, 0) !=3D MAGIC_TOKEN) { + printf("This test must be run through nx_huge_pages_test.sh"); + return KSFT_SKIP; + } + + 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..60bfed8181b9 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only */ +# +# Wrapper script which performs setup and cleanup for nx_huge_pages_test. +# Makes use of root privileges to set up huge pages and KVM module paramet= ers. +# +# tools/testing/selftests/kvm/nx_huge_page_test.sh +# Copyright (C) 2022, Google LLC. + +set -e + +NX_HUGE_PAGES=3D$(sudo cat /sys/module/kvm/parameters/nx_huge_pages) +NX_HUGE_PAGES_RECOVERY_RATIO=3D$(sudo cat /sys/module/kvm/parameters/nx_hu= ge_pages_recovery_ratio) +NX_HUGE_PAGES_RECOVERY_PERIOD=3D$(sudo cat /sys/module/kvm/parameters/nx_h= uge_pages_recovery_period_ms) +HUGE_PAGES=3D$(sudo cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugep= ages) + +set +e + +( + set -e + + sudo echo 1 > /sys/module/kvm/parameters/nx_huge_pages + sudo echo 1 > /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio + sudo echo 100 > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_= ms + sudo echo 3 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + + "$(dirname $0)"/nx_huge_pages_test 887563923 +) +RET=3D$? + +sudo echo $NX_HUGE_PAGES > /sys/module/kvm/parameters/nx_huge_pages +sudo echo $NX_HUGE_PAGES_RECOVERY_RATIO > /sys/module/kvm/parameters/nx_hu= ge_pages_recovery_ratio +sudo echo $NX_HUGE_PAGES_RECOVERY_PERIOD > /sys/module/kvm/parameters/nx_h= uge_pages_recovery_period_ms +sudo echo $HUGE_PAGES > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugep= ages + +exit $RET --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 45F78C433EF for ; Tue, 3 May 2022 18:31:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238162AbiECSfT (ORCPT ); Tue, 3 May 2022 14:35:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241404AbiECSel (ORCPT ); Tue, 3 May 2022 14:34:41 -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 5DED23F314 for ; Tue, 3 May 2022 11:31:00 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 64-20020a630843000000b0039d909676d5so8775264pgi.16 for ; Tue, 03 May 2022 11:31: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=xswzH/Bbil9zpaQ4laTDHIN9myBOysbLUHFynw5y6xc=; b=VqB8rjIXOtLuE0VJ1xycczkIMarEZrfY/e2JGoH2Rr2NV7qkzB4ygYQtZr51hgCro0 UGK5tMHuWbqeFVCKG/vgmz1a/HoJlUfbCJGD65QT1tShrCWEujpNC4z0AkI+x9aMpJUC TXeioZyUTKy1Lpr9mIieayddzozTsUDqTMwjVJGPXQ0LZY8Bd5q3KZYJKCCPtfTTRXO4 UwHixsWHz8cDtdu+2SrYbok7/fH/FSjmwYMuR4LKa7uCnULL81IJOZog7zxTrO1dWxPX I8iXtPhLI39wezrY3pudK0kh83BIXP/tzpOBWlEdLegxtBjgpOzOvcDIWwYI84pd+r+c Dfuw== 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=xswzH/Bbil9zpaQ4laTDHIN9myBOysbLUHFynw5y6xc=; b=iHHDu+vCnT3VGTKXz3nUukq47iG6OPKCTx1UaJZl177gXS6ITLE6Jhl99hOXlp4IgU 5gGsMITkN7KcdJSWx2CVyvxJJudbGpniyTWTcT+T+VhDR8YK/fAY89F+Myw7Eid/z+wl Ns/NeOsIrf4Jb5BCiw3peHiBuDv93sC2C6nW1LEzC2Fl8uadRfUy0yX5O4VwXzRFdCBm UX8llP3umxaT/0akuJRlZHNz5bjR3dfNznL4xWq25XR4rtYa14/ga4T9RiIXHNKWWMoo Cu6QcDeEX7lk89lcJPfFPqfB7ykCOePOMwPSPQBdvZI2sMsd34I0emR7gH0HytZulItm USQA== X-Gm-Message-State: AOAM531r+RY93N/fcUeBNaP/7RsV+Mrbrw5yndNKuqYln1jMYoc0UuNR NKa4DKaJu6ti0fFirXymyi4eoRyjdX0H4TRE24i1OSJt9RWtVP0czqKcb3s+TIYvvF+eY8uimRS +KmSc6DCJu5y6IQB4LLAtWA9O7QqT/pRfH7cKnpAwGeSbYTBoAyaQOd2RIrzhYfUKLmuOdpHW X-Google-Smtp-Source: ABdhPJyZ4iLDny5B9TJHOLEZRFr/+K04g9w9/rCRKqe1027R7q4Lcz3kfqmAjEjnxIIB82jFNN5gGg/+6Q3A X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:90a:fa06:b0:1d7:765d:111b with SMTP id cm6-20020a17090afa0600b001d7765d111bmr6080511pjb.185.1651602659687; Tue, 03 May 2022 11:30:59 -0700 (PDT) Date: Tue, 3 May 2022 18:30:41 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-8-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 07/11] 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") Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- 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 8ee8c91fa762..5ba9c7c8140a 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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 2DB6EC433EF for ; Tue, 3 May 2022 18:31:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241634AbiECSf0 (ORCPT ); Tue, 3 May 2022 14:35:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241425AbiECSel (ORCPT ); Tue, 3 May 2022 14:34:41 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7396D1EAC0 for ; Tue, 3 May 2022 11:31:01 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id t24-20020a17090a449800b001d2d6e740c3so1669289pjg.9 for ; Tue, 03 May 2022 11:31:01 -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=wsR3FwABhxtWZiXpEXHgrlRr8UQyeh37PG+bJ+BbATQ=; b=gpE9lffWd+RjZAvhIe1TTpYRZRNX4gDPOvBDs8jwoAsVO38JV+VxAqH2HCSVavh4C1 k7c2+xu+TJRn+V+faSB4IWA+v/DfdH8xGVpW+QaDnKEnjPsMZA41zw2sEJmHn+Vz0w5c LnUyxL7Y2dc3Fv/QqCJp+cLNibrnUPl8rNVS9NhEKpyO9XP+JDL/UC813NnroS+nEnQ5 Ki2geda8ckujtnUmb8ynOyoBFAllGdWt6vJqlTMT6WUcCw4tYVRDIyYfBboYCpJxCM+x UbAk321irMb7mGzhYHz3/yfHtxtfW9k89YJU9TnawUQlvT0RbDfvWzsYywlATmlsN3cr Rvig== 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=wsR3FwABhxtWZiXpEXHgrlRr8UQyeh37PG+bJ+BbATQ=; b=CvUjsyFMjJ3zRtFa9Qo78fLZLubWrhWtAt2sXzHyPoVaMbJWH0wGW60GvpNvsomFWl tiUWJRaP0Q7TY5F4iHMXTtjXa4uKy6jiLg/BROriEAo0x8A2Xpxb23UwYc/Rk9V/dZ+k sg/rtb/4ZAMz5c9xEVTMuvoDszMzI0goOzEtskI5emfxxoWMivz52Drn4sCKSwducfGq n6TkroNwKkaLToRbSLYzkIBliLgNzsbjFBAvZMSzCdPD1l7pGFPAmgw70PToHDhRSES+ vYCB9S2le/nTqhdHrfhFrlgbTbtwrDiYtDfswaXlyho0eRceWuR0jSV9usiwhWOM9oh2 3O3Q== X-Gm-Message-State: AOAM533mKuyR6tc7J52tyuKDfvgticKjDpkxQAdbyhxiA20cjIf4kmf9 sOwfKypgtiHLTK/Lwxt6bi3sJURwu3JvPtIpLFNgHdJhYT1VrZjLQZlaDVquTXXhORHk8Xiw/xr VPoj1FOlZk2Ht7X42AkKE8Xg0Eantnzm3eKBExSne/GHIztubGW3cgflDGBJVi1quzCNhdvDK X-Google-Smtp-Source: ABdhPJyyIjj4x1oAp6FH5w7F+vcQ9Lq8vVei9cT0OjIYCO9q8ktLY7EHmyp6RAG3DLJThIhiEv9KUo2VgrfJ X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a62:b60f:0:b0:508:2a61:2c8b with SMTP id j15-20020a62b60f000000b005082a612c8bmr17327945pff.2.1651602661050; Tue, 03 May 2022 11:31:01 -0700 (PDT) Date: Tue, 3 May 2022 18:30:42 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-9-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 08/11] 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 Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- Documentation/virt/kvm/api.rst | 17 +++++++++++++++++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/mmu.h | 8 ++++---- arch/x86/kvm/mmu/spte.c | 7 ++++--- arch/x86/kvm/mmu/spte.h | 3 ++- arch/x86/kvm/mmu/tdp_mmu.c | 2 +- arch/x86/kvm/x86.c | 30 ++++++++++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + 8 files changed, 61 insertions(+), 9 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 23baf7fce038..ddda1f1440d6 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7879,6 +7879,23 @@ 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_VM_DISABLE_NX_HUGE_PAGES +:Architectures: x86 +:Type: vm +:Parameters: arg[0] must be 0. +:Returns 0 on success, -EPERM if the userspace process does not + have CAP_SYS_BOOT, -EINVAL if args[0] is not 0 or any vCPUs have been + created. + +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. + +This capability may only be set before any vCPUs are created. + 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 c59fea4bdb6e..0a1bb01c3229 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1249,6 +1249,8 @@ struct kvm_arch { * the global KVM_MAX_VCPU_IDS may lead to significant memory waste. */ u32 max_vcpu_ids; + + 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 7e258cc94152..0ce84042c059 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -217,9 +217,9 @@ 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, @@ -235,8 +235,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 75c9e87d446a..ecea6cfc965d 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -117,7 +117,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 @@ -216,7 +216,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; @@ -244,7 +245,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 fbbab180395e..19eb5ea67d95 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -412,7 +412,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 4fabb2cd0ba9..36f33a95a414 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1470,7 +1470,7 @@ 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 5ba9c7c8140a..6ce2b18dcaa1 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: @@ -6093,6 +6094,35 @@ 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; + + /* + * Since the risk of disabling NX hugepages is a guest crashing + * the system, ensure the userspace process has permission to + * reboot the system. + * + * Note that unlike the reboot() syscall, the process must have + * this capability in the root namespace because exposing + * /dev/kvm into a container does not limit the scope of the + * iTLB multihit bug to that container. In other words, + * this must use capable(), not ns_capable(). + */ + if (!capable(CAP_SYS_BOOT)) { + r =3D -EPERM; + break; + } + + if (cap->args[0]) + 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 e10d131edd80..3a09528a9a81 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1153,6 +1153,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_DISABLE_QUIRKS2 213 #define KVM_CAP_VM_TSC_CONTROL 214 #define KVM_CAP_SYSTEM_EVENT_DATA 215 +#define KVM_CAP_VM_DISABLE_NX_HUGE_PAGES 216 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 B4765C4332F for ; Tue, 3 May 2022 18:31:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241501AbiECSfF (ORCPT ); Tue, 3 May 2022 14:35:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241382AbiECSep (ORCPT ); Tue, 3 May 2022 14:34:45 -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 8865A3F89D for ; Tue, 3 May 2022 11:31:03 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id u18-20020a170902e21200b0015e5e660618so6841929plb.5 for ; Tue, 03 May 2022 11:31: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=UI0i04LOeDv306YCyysgbmYsjYLKqLtrpgIp2tMXlhg=; b=BaTAJBbtgdle1GlFYIxOKqwCwV9qPPsN0DN3CdhUWT+UQKmDWmL5/2GR7zcx9m227i /iD+cqmiMcA3jCvEQSuHz1e6ySu0Xin2ah6AuoRg3nHzO6M6LLj0W7FUxZOgksKTkUCg 4pkYK+VFcAclXZ5/crt9hNnrdM1KW4irzX3r+yZd0zjOWe6/I8bKUmWmIQXc7yQXBiNn vJS8rXZzzxdn8DMNwi9QLz7vmoM2mpvaRXlzA/EmSTeZAbp7QbI1+TnQj6aupPRYdPSZ n+60zANuUT3WGGIVyGYIv9lUBJ6JcDRhgWSwWmW1A1wAjb1OD92dhRjcLy5uqfgaXo2d VOPQ== 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=UI0i04LOeDv306YCyysgbmYsjYLKqLtrpgIp2tMXlhg=; b=2dBpbLNnnCVMK1c1oZYjgl6BgHgBF+C9cp6DHciOVTph2wvpVCQyTLNb3DZIEfN0u6 IZ/QSTHF3HyF4kIDXApxot7OePLnBVCDI1HeNJzOjKWbxB99dOmtqfpygZKUJKi1EQ4Y NCWm85rnGF9kRJ4FUpMjo6XZoT8fcJz1aHgl9gzslNOeb+de3WrPwGw6f4QZQt5LDFw0 ULTCQMPfVt71zNS07jamzCcPoy5xKyDJCtGc42b0ZaKrT/wG5Js+Be/wLDvKgYtFRePr 7jVJv/H/DxmDIgChHVazmF0kiKUnPfRbgpfWDek9b06r7uBqG+NEvkhAJQ6IhM6EvJtU gTaQ== X-Gm-Message-State: AOAM531DnKtoC9Zid4PKL6n15+T1tuXPTJld3JR0vYfeLm3mfU0Yq8Ky KkvQn6hLcf84GLkaOh7CZ1ex6dB94vMAiy/kqKpp4zZFjnIs9q9Yj0Vs9SGcIJJ5v4ke/0jPzDB qva/gW1gdUVDbNwCrFHY1ScNuiwBp8HL6uPppEukLJBPSbwqPFnlzfvoH+8y5hKbLx4jfVpis X-Google-Smtp-Source: ABdhPJyF8hUdbSgAbutlP4Dw9VQ1NedW9z01ve5CYxvBWcspa31Ucxue0zxi7oN5C5UCCbsMRv4ytdlUb4vO X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:90a:e510:b0:1d9:ee23:9fa1 with SMTP id t16-20020a17090ae51000b001d9ee239fa1mr95259pjy.0.1651602662631; Tue, 03 May 2022 11:31:02 -0700 (PDT) Date: Tue, 3 May 2022 18:30:43 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-10-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 09/11] 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. Reviewed-by: David Matlack Reviewed-by: Peter Xu Signed-off-by: Ben Gardon --- .../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 6930ba298170..27ffd2537df6 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.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 9B319C433EF for ; Tue, 3 May 2022 18:31:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241544AbiECSfN (ORCPT ); Tue, 3 May 2022 14:35:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241399AbiECSeu (ORCPT ); Tue, 3 May 2022 14:34:50 -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 89C863F89F for ; Tue, 3 May 2022 11:31:05 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id l6-20020a170903120600b0014f43ba55f3so8251941plh.11 for ; Tue, 03 May 2022 11:31:05 -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=PH+xG6MpJgOWP4Nd5wbkgZPXGVxwqiuyEnG1R2LsJQQ=; b=GELegNYt7SuUFUfWOpcWuqF4CQjFOL1qCR3ckZDviaWyVJAl+zmPfWpNqVPzTXDXHc ZAkQqE90tJVIPKEjYTKhwA6OSIt8wfHOVRjew7839NmsmSelV99i1MzB0Sn/i87v4ELp wFstXhIhWniFuji/fvIVWJIILUtKPxKRIyYsi7WmbRcSjz8koDflEs9CZRt1z7X4KXJT RsCwZCCSeykNJ8fhz5BbYNZX4Ss+r6DUgCkK4Bs2nps/iW/gqrsAGGvgWmSJpERX3Bez XdAzDW7KcP/jDIiPn9reOWhUYM/yH0/RF8UhGHdsI8jqrGmayL/qYsWO9TNVl07E67vg gf9A== 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=PH+xG6MpJgOWP4Nd5wbkgZPXGVxwqiuyEnG1R2LsJQQ=; b=FCyyUgao7Nz9h4FwEDkie51iUT5dXc7gfuPgYXrnuTfqwsbZih61DlV4UAXlNY3lKw NJW5uelOCFvwCrD+J96DOC8Bz9J+TiJIW6QEnjRzJxYQ7WYX1etNbAs2MirZwxb3NGD+ pNf1IBDJAIJJ387TCrlhE4dZnTDQtHIX7QaSPMMgJucdvISaTwJzGN4DdPWWxPNXiE3P r80wqZ9fbHq50Sc64kYT38TOd7AzDQp/ngr7lBtaO4Rf34dt9Mqn3o+oG4+bYksn7vqv vFbu+dP2oRHCCp2JkpLwIZqxG2nxJlDO+pimGW6Dhkd9s7b+PsU/dSh2Lzlfc+t5IMd2 TkJQ== X-Gm-Message-State: AOAM530HGQ+yrOoNSGE6LuDTdFFrtKKYerQBvpDEHIAU6xAVTs5v/iDR TcGsbKLQxi1efokfwd8oCIsy/nk5pEDCGy73E96gLHYP5UE2AAAzZI4b9QETjbGPsbGOZsMXNsw WJjZTzCHTsvGa8mM5bj4xuTfpx8jkiORWpYy9U5iUdkEsq0YqI6UJ7nbZbGF4IzCNAHDPs8Ue X-Google-Smtp-Source: ABdhPJxDr77DJ1rH+k3RFe0iH6545KQm+EtT7iY4DHLcjsZKZHMBguFZE6i+E8tvMW70pQfVeFBI4O+/Ytq/ X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:902:e550:b0:15c:f4f2:814f with SMTP id n16-20020a170902e55000b0015cf4f2814fmr17804676plf.123.1651602664332; Tue, 03 May 2022 11:31:04 -0700 (PDT) Date: Tue, 3 May 2022 18:30:44 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-11-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 10/11] 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. Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 27 ++++++- .../selftests/kvm/x86_64/nx_huge_pages_test.c | 70 +++++++++++++++---- .../kvm/x86_64/nx_huge_pages_test.sh | 12 +++- 4 files changed, 95 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 1dac3c6607f1..eee96189c1c4 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 27ffd2537df6..0ec7efc2900d 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 @@ -2758,3 +2763,23 @@ uint64_t vm_get_stat(struct kvm_vm *vm, const char *= stat_name) stat_name, ret); return data; } + +/* VM disable NX huge pages + * + * Input Args: + * vm - Virtual Machine + * + * Output Args: None + * + * Return: On success, 0 -ERRNO on failure. + * + * Disables NX huge pages for the VM. + */ +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 238a6047791c..1e7328dd33d2 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" @@ -89,18 +91,36 @@ 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_huge_pages, bool reboot_permissions) { struct kvm_vm *vm; struct timespec ts; + uint64_t pages; void *hva; - - if (argc !=3D 2 || strtol(argv[1], NULL, 0) !=3D MAGIC_TOKEN) { - printf("This test must be run through nx_huge_pages_test.sh"); - return KSFT_SKIP; + 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_huge_pages) { + /* + * Cannot run the test without NX huge pages if the kernel + * does not support it. + */ + if (!kvm_check_cap(KVM_CAP_VM_DISABLE_NX_HUGE_PAGES)) + return; + + r =3D __vm_disable_nx_huge_pages(vm); + if (reboot_permissions) { + TEST_ASSERT(!r, "Disabling NX huge pages should succeed if process has = reboot permissions"); + } else { + TEST_ASSERT(r =3D=3D -EPERM, "This process should not have permission t= o disable NX huge pages"); + return; + } } =20 - vm =3D vm_create_default(0, 0, guest_code); + vm_vcpu_add_default(vm, 0, guest_code); =20 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, HPAGE_GPA, HPAGE_SLOT, @@ -133,23 +153,27 @@ int main(int argc, char **argv) /* * Next, the guest will execute from the first huge page, causing it * to be remapped at 4k. + * + * If NX huge pages are disabled, this should have no effect. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 1); + check_2m_page_count(vm, disable_nx_huge_pages ? 2 : 1); + check_split_count(vm, disable_nx_huge_pages ? 0 : 1); =20 /* * Executing from the third huge page (previously unaccessed) will * cause part to be mapped at 4k. + * + * If NX huge pages are disabled, it should be mapped at 2M. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 1); + check_split_count(vm, disable_nx_huge_pages ? 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_huge_pages ? 3 : 1); + check_split_count(vm, disable_nx_huge_pages ? 0 : 2); =20 /* * Give recovery thread time to run. The wrapper script sets @@ -161,8 +185,11 @@ int main(int argc, char **argv) =20 /* * Now that the reclaimer has run, all the split pages should be gone. + * + * If NX huge pages are disabled, the relaimer will not run, so + * nothing should change from here on. */ - check_2m_page_count(vm, 1); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 1); check_split_count(vm, 0); =20 /* @@ -170,10 +197,25 @@ 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_huge_pages ? 3 : 2); check_split_count(vm, 0); =20 kvm_vm_free(vm); +} + +int main(int argc, char **argv) +{ + bool reboot_permissions; + + if (argc !=3D 3 || strtol(argv[1], NULL, 0) !=3D MAGIC_TOKEN) { + printf("This test must be run through nx_huge_pages_test.sh"); + return KSFT_SKIP; + } + + reboot_permissions =3D strtol(argv[2], NULL, 0); + + run_test(false, reboot_permissions); + run_test(true, reboot_permissions); =20 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 index 60bfed8181b9..c21c1f639141 100755 --- a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh @@ -16,6 +16,8 @@ HUGE_PAGES=3D$(sudo cat /sys/kernel/mm/hugepages/hugepage= s-2048kB/nr_hugepages) =20 set +e =20 +NXECUTABLE=3D"$(dirname $0)/nx_huge_pages_test" + ( set -e =20 @@ -24,7 +26,15 @@ set +e sudo echo 100 > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_= ms sudo echo 3 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages =20 - "$(dirname $0)"/nx_huge_pages_test 887563923 + # Test with reboot permissions + sudo setcap cap_sys_boot+ep $NXECUTABLE + $NXECUTABLE 887563923 1 + + # Test without reboot permissions + if [ $(whoami) !=3D "root" ] ; then + sudo setcap cap_sys_boot-ep $NXECUTABLE + $NXECUTABLE 887563923 0 + fi ) RET=3D$? =20 --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 12:46:32 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 41E8EC433F5 for ; Tue, 3 May 2022 18:31:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241526AbiECSfK (ORCPT ); Tue, 3 May 2022 14:35:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241486AbiECSev (ORCPT ); Tue, 3 May 2022 14:34:51 -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 290663F8AB for ; Tue, 3 May 2022 11:31:06 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id a11-20020a170902900b00b0015ebbae6dd9so809139plp.6 for ; Tue, 03 May 2022 11:31: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=kdhiU9fwdUmCUThSgoTZng+IDRrmraex/lfG5pPhseg=; b=c8DzY+1F+9gWJxr1pR9f+htywCO1jkCNviVAvOHO019VMJ2e5OILY0r5nmZJBc+l7A Gwt3R7gK6uP809S23n7mTj2sgBSIPR59yCQy0r3V03W5Kyh72v1VMdFmDEwjqOCwLeT5 9n/jwpwUnGU8eZkJ9HWCY4Ww2OWYkhmWA3tvEhAP0C/WHoLMx+3pzECx/tMk5vBeGk5i rZ6a863DDoqtaEOcMTei0/unIGLeuiEvCwGE8q0A/g32UcWogIeTDuN2S1E43Krcs8j7 ww0TAtnJkRFeVMuSHwWqVeZKn3v09y7dGsMGEArk3MMiOVlFjRKt0no3x73rE70wh00N 2IrQ== 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=kdhiU9fwdUmCUThSgoTZng+IDRrmraex/lfG5pPhseg=; b=y+xgrDeZVcXgvAECO/HhkPmcYw4RFI7F3lF5MC/K3Q4+qbXxBJHLolUpfOR0upLe2T 2S8PoDeJADKpuM87l9Ze2dXj5Wn49GPMPA/i1x5ElC+IoZD647jOIWVmsUkreEfH8cJv r8b0b2IyvJEveYnWmpf3xVRXulsPZwbXG8nVripViCq5QR0sxYBMi5F+7PG6EKCBAcvm TtRfW/C6hkVXFFtx8OcQ9qwlJcXZ/tMbBzpcStUmCfKrDYdMJxbCrZX/Y9+36sEJCEt2 8GVZ7J3ma4LrnTWvfuu2AOL442RFs8O26Ryl8PmVjad+2IaFSSlnzDgZ131XmHRhwrGF ebWg== X-Gm-Message-State: AOAM531mRaZbaxa9lCpicgowP8QJ9szyI9mcuHM0HKNfRD6RZQDD1sjO qsgDLzZcuyN/OC25xCp8rbFEPTBhdXyULh3rh6ztxYSKQ9DvQyTrWgT1u6PWB+zY4pmD/c1CNAj /O8w+QGC4uVihC3kl0Sgdriff5mju0ygPxzmCSwDtp9Sjj6MXrx59EegcdeljI6LKI+P3Uhy1 X-Google-Smtp-Source: ABdhPJxlCSSj5oS9+YkkTe2pxdKzfgfB0SGrTOFE9i3HpygSw76Igjy+5YIFfuGMaV2X+WJZag9fF/HyoIhX X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:a17:90b:f03:b0:1d9:a8e9:9e35 with SMTP id br3-20020a17090b0f0300b001d9a8e99e35mr6253446pjb.48.1651602665962; Tue, 03 May 2022 11:31:05 -0700 (PDT) Date: Tue, 3 May 2022 18:30:45 +0000 In-Reply-To: <20220503183045.978509-1-bgardon@google.com> Message-Id: <20220503183045.978509-12-bgardon@google.com> Mime-Version: 1.0 References: <20220503183045.978509-1-bgardon@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 11/11] KVM: selftests: Cache binary stats metadata for duration of 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" In order to improve performance across multiple reads of VM stats, cache the stats metadata in the VM struct. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/lib/kvm_util.c | 31 ++++++++++--------- .../selftests/kvm/lib/kvm_util_internal.h | 5 +++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 0ec7efc2900d..4bb012efcc88 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -736,6 +736,12 @@ void kvm_vm_free(struct kvm_vm *vmp) if (vmp =3D=3D NULL) return; =20 + /* Free cached stats metadata and close FD */ + if (vmp->stats_fd) { + free(vmp->stats_desc); + close(vmp->stats_fd); + } + /* Free userspace_mem_regions. */ hash_for_each_safe(vmp->regions.slot_hash, ctr, node, region, slot_node) __vm_mem_region_delete(vmp, region, false); @@ -2703,37 +2709,32 @@ int read_stat_data(int stats_fd, struct kvm_stats_h= eader *header, 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; =20 - stats_fd =3D vm_get_stats_fd(vm); - - read_stats_header(stats_fd, &header); - - stats_desc =3D read_stats_desc(stats_fd, &header); + if (!vm->stats_fd) { + vm->stats_fd =3D vm_get_stats_fd(vm); + read_stats_header(vm->stats_fd, &vm->stats_header); + vm->stats_desc =3D read_stats_desc(vm->stats_fd, &vm->stats_header); + } =20 - size_desc =3D sizeof(struct kvm_stats_desc) + header.name_size; + size_desc =3D sizeof(struct kvm_stats_desc) + vm->stats_header.name_size; =20 /* Read kvm stats data one by one */ - for (i =3D 0; i < header.num_desc; ++i) { - desc =3D (void *)stats_desc + (i * size_desc); + for (i =3D 0; i < vm->stats_header.num_desc; ++i) { + desc =3D (void *)vm->stats_desc + (i * size_desc); =20 if (strcmp(desc->name, stat_name)) continue; =20 - ret =3D read_stat_data(stats_fd, &header, desc, data, - max_elements); + ret =3D read_stat_data(vm->stats_fd, &vm->stats_header, desc, + data, max_elements); =20 break; } =20 - free(stats_desc); - close(stats_fd); return ret; } =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util_internal.h b/tools/te= sting/selftests/kvm/lib/kvm_util_internal.h index a03febc24ba6..e753edd7b8d3 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util_internal.h +++ b/tools/testing/selftests/kvm/lib/kvm_util_internal.h @@ -67,6 +67,11 @@ struct kvm_vm { vm_vaddr_t idt; vm_vaddr_t handlers; uint32_t dirty_ring_size; + + /* Cache of information for binary stats interface */ + int stats_fd; + struct kvm_stats_header stats_header; + struct kvm_stats_desc *stats_desc; }; =20 struct vcpu *vcpu_find(struct kvm_vm *vm, uint32_t vcpuid); --=20 2.36.0.464.gb9c8b46e94-goog