From nobody Mon Jun 22 16:32:45 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 25B41C433FE for ; Mon, 21 Mar 2022 00:26:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343915AbiCUA2L (ORCPT ); Sun, 20 Mar 2022 20:28:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343896AbiCUA2H (ORCPT ); Sun, 20 Mar 2022 20:28:07 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB0FBDE915 for ; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id t184-20020a6281c1000000b004e103c5f726so8951190pfd.8 for ; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=ZnD2DMccysTRV29OOaip4kblVakt/ZXloOGMe9n4Sq8=; b=KDMyBdZmkNm9VQre/sHHd+UF3yLIF3XPElWKa82CiPy1b7hEVh9nyWahmPuLote377 KSDkZZqhX/BR9824SpZY9nY/1qeWg5iLaIw79JX0wKagPNLtWpFCr9Xyk3iGC4svbs4H UMHBiMVexnJw3LuAwJeYPqtRSf7zqf3/bp32cAM0ZwjYjaqcZlFXOetCtOMQ9Z155UO4 nSaquyHHmSm+3HvKXJaY3xsm5XvZrXrene3Lp2Cto/v5sdLMOYM3DChdG5UoUllKEM8y MjjUnMWOvBoAOzLet0kHzmhoBrr7ttSa26hRSaztdAmnHtnAYPTNFoOCHh3thtt3uRpu /3sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=ZnD2DMccysTRV29OOaip4kblVakt/ZXloOGMe9n4Sq8=; b=bx6QTvrTZ472Owu83Q6c+Lz18mOOIFc7X8lgqAAM1tNWAjC2l5cUykd48Ota3HIaS+ VirJifdw1qw/qmOAlnjWq1teJtQCMIdMder3snrq0jyw2FURk5pyscc/w12rfSaUIBn7 Ywkl15ZWJn0mSeoqU7ur3RTsAKmnCYiu7kqiq4HbeIP563vWs9afBQcZDKOYLSuwcWM5 GnGqIKUpVqoUz+V9MGNuQDzMjM6D0LVvX2gYVy27RQBs/6+9Hl39gIbqSVqgQJ58hC+X MnNx8Mnu3pumdWAWcYY/XmH1FLTg8D1Qjfbp4d4xNTxtio4J+yFem03vmVeDOG3DrOpv cRFg== X-Gm-Message-State: AOAM532bTtcR52PR1hWUmGcv73YrlCkCObYQky284BlfH/Aae+LucQlZ zHJl/6F1ne3UK5cdQRZ6DSynbD0x6eg6 X-Google-Smtp-Source: ABdhPJxBa/87UWDZmU7EDsZl+WZSJ+96ppP55fnQay9zpPrkfeF9vKo9OqM19uQ4CNgZgV0Unu/Rdf89sZaW X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a05:6a00:1992:b0:4fa:7438:870a with SMTP id d18-20020a056a00199200b004fa7438870amr13100130pfl.48.1647822402113; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:35 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-2-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 1/4] selftests: KVM: Dump VM stats in binary stats test From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , 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: Ben Gardon Add kvm_util library functions to read KVM stats through the binary stats interface and then dump them to stdout when running the binary stats test. Subsequent commits will extend the kvm_util code and use it to make assertions in a test for NX hugepages. CC: Jing Zhang Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 1 + .../selftests/kvm/kvm_binary_stats_test.c | 3 + tools/testing/selftests/kvm/lib/kvm_util.c | 143 ++++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 4ed6aa049a91..160b9ad8474a 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -392,6 +392,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 dump_vm_stats(struct kvm_vm *vm); =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 17f65d514915..afc4701ce8dd 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -174,6 +174,9 @@ static void vm_stats_test(struct kvm_vm *vm) stats_test(stats_fd); close(stats_fd); TEST_ASSERT(fcntl(stats_fd, F_GETFD) =3D=3D -1, "Stats fd not freed"); + + /* Dump VM stats */ + dump_vm_stats(vm); } =20 static void vcpu_stats_test(struct kvm_vm *vm, int vcpu_id) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index d8cf851ab119..d9c660913403 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2517,3 +2517,146 @@ int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t v= cpuid) =20 return ioctl(vcpu->fd, KVM_GET_STATS_FD, NULL); } + +/* Caller is responsible for freeing the returned kvm_stats_header. */ +static struct kvm_stats_header *read_vm_stats_header(int stats_fd) +{ + struct kvm_stats_header *header; + ssize_t ret; + + /* 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"); + + return header; +} + +static void dump_header(int stats_fd, struct kvm_stats_header *header) +{ + ssize_t ret; + char *id; + + printf("flags: %u\n", header->flags); + printf("name size: %u\n", header->name_size); + printf("num_desc: %u\n", header->num_desc); + printf("id_offset: %u\n", header->id_offset); + printf("desc_offset: %u\n", header->desc_offset); + printf("data_offset: %u\n", header->data_offset); + + /* Read kvm stats id string */ + id =3D malloc(header->name_size); + TEST_ASSERT(id, "Allocate memory for id string"); + ret =3D pread(stats_fd, id, header->name_size, header->id_offset); + TEST_ASSERT(ret =3D=3D header->name_size, "Read id string"); + + printf("id: %s\n", id); + + free(id); +} + +static ssize_t stats_desc_size(struct kvm_stats_header *header) +{ + return sizeof(struct kvm_stats_desc) + header->name_size; +} + +/* Caller is responsible for freeing the returned kvm_stats_desc. */ +static struct kvm_stats_desc *read_vm_stats_desc(int stats_fd, + struct kvm_stats_header *header) +{ + struct kvm_stats_desc *stats_desc; + size_t size_desc; + ssize_t ret; + + size_desc =3D header->num_desc * stats_desc_size(header); + + /* Allocate memory for stats descriptors */ + stats_desc =3D malloc(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->desc_offset); + TEST_ASSERT(ret =3D=3D size_desc, "Read KVM stats descriptors"); + + return stats_desc; +} + +/* Caller is responsible for freeing the memory *data. */ +static int read_stat_data(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc, uint64_t **data) +{ + u64 *stats_data; + ssize_t ret; + + stats_data =3D malloc(desc->size * sizeof(*stats_data)); + + ret =3D pread(stats_fd, stats_data, desc->size * sizeof(*stats_data), + header->data_offset + desc->offset); + + /* ret is in bytes. */ + ret =3D ret / sizeof(*stats_data); + + TEST_ASSERT(ret =3D=3D desc->size, + "Read data of KVM stats: %s", desc->name); + + *data =3D stats_data; + + return ret; +} + +static void dump_stat(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc) +{ + u64 *stats_data; + ssize_t ret; + int i; + + printf("\tflags: %u\n", desc->flags); + printf("\texponent: %u\n", desc->exponent); + printf("\tsize: %u\n", desc->size); + printf("\toffset: %u\n", desc->offset); + printf("\tbucket_size: %u\n", desc->bucket_size); + printf("\tname: %s\n", (char *)&desc->name); + + ret =3D read_stat_data(stats_fd, header, desc, &stats_data); + + printf("\tdata: %lu", *stats_data); + for (i =3D 1; i < ret; i++) + printf(", %lu", *(stats_data + i)); + printf("\n\n"); + + free(stats_data); +} + +void dump_vm_stats(struct kvm_vm *vm) +{ + struct kvm_stats_desc *stats_desc; + struct kvm_stats_header *header; + struct kvm_stats_desc *desc; + size_t size_desc; + int stats_fd; + int i; + + stats_fd =3D vm_get_stats_fd(vm); + + header =3D read_vm_stats_header(stats_fd); + dump_header(stats_fd, header); + + stats_desc =3D read_vm_stats_desc(stats_fd, header); + + size_desc =3D stats_desc_size(header); + + /* Read kvm stats data one by one */ + for (i =3D 0; i < header->num_desc; ++i) { + desc =3D (void *)stats_desc + (i * size_desc); + dump_stat(stats_fd, header, desc); + } + + free(stats_desc); + free(header); + + close(stats_fd); +} + --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 16:32:45 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 ECB81C433FE for ; Mon, 21 Mar 2022 00:27:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343928AbiCUA2V (ORCPT ); Sun, 20 Mar 2022 20:28:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343899AbiCUA2I (ORCPT ); Sun, 20 Mar 2022 20:28:08 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBA47DE910 for ; Sun, 20 Mar 2022 17:26:43 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id c6-20020a621c06000000b004fa7307e2e0so4369871pfc.6 for ; Sun, 20 Mar 2022 17:26:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=ONXdbAN8amlEB9qh6OgAKGOjSA/PDIQV8SIv35wcs8A=; b=M+NOaEnG6mj6JNTytwlFELsq2MhitrDFldJcZeXo09FgI1nAz5E+TAv3aUmQVZQZnj 3D1EbJ8yTnWcGrQnNk0NpqHgtPgIRkexkaos7Ic84kCeANiIoaiXaoVRmcNzC0r01STI BF33pX+0Uem/BI64+Tdln+4OqbAIgUNOoObYnK6wb6vPI/gWddA0PjEFLdkCMTcKfZdH M9ks8wNMR5HVMB/4es2FMurFj6AoIzhWTewYuQGw+DTIdzN/JK5ySU7ayXmkpgJYvXDv fq80XL3SnVLntF8x1coPEThYe+KNcfUz4NTk0WUSoiRjTJ0BCUV77/4evNYpEq0HIBK3 GN2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=ONXdbAN8amlEB9qh6OgAKGOjSA/PDIQV8SIv35wcs8A=; b=aZSIS62IHWX4jyShwPG5IJRs9QcIHu6vFIFvBxRjCozOxCYI+NOi2DDDEXdxYmGaRx 6WzT34zmWlM2B3MvCy0tnaKQuzDCPAbu3Ttozwtq17HHdzIf87v3LV9quqzjAw5oRdNL +uEGLs7Oi3O3iGYHBTdMcIS4YPs4GO1wLLbJRnM5wlT1bnnKaS+YApob0oIl+omT7tVP 2GY9PI71cgbxzL96N8Bb72wz81MVmfnjK/1mT5MpWgK4XlfvhhhrFiSz9RYSgVW1n/js /KTRXoMFoizm4zI23um5jGmxlsp7xKMm7Zgip+e6E52CBTv4246kNisSqheuizTrJlue v5Gw== X-Gm-Message-State: AOAM53391ADlJh5k8TVKJZWuCleQkxGZ+I/gfgSo+F+U/RL6hCS1BINC iIO/OljxevGJz6CrZkMNFhRd/D7liDRj X-Google-Smtp-Source: ABdhPJyQh0cpfhcq39A4la7k4keyo7dVFdF0fGkivbfV/iyl7s5g/kW3RQ8CmP/A+Tpauwan61zOFPISJtTf X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:902:b097:b0:154:2bda:bd38 with SMTP id p23-20020a170902b09700b001542bdabd38mr9344521plr.155.1647822403459; Sun, 20 Mar 2022 17:26:43 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:36 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-3-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 2/4] selftests: KVM: Test reading a single stat From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , 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: Ben Gardon Retrieve the value of a single stat by name in the binary stats test to ensure the kvm_util library functions work. CC: Jing Zhang Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 1 + .../selftests/kvm/kvm_binary_stats_test.c | 3 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 160b9ad8474a..a07964c95941 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -393,6 +393,7 @@ 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 dump_vm_stats(struct kvm_vm *vm); +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name); =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 afc4701ce8dd..97bde355f105 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -177,6 +177,9 @@ static void vm_stats_test(struct kvm_vm *vm) =20 /* Dump VM stats */ dump_vm_stats(vm); + + /* Read a single stat. */ + printf("remote_tlb_flush: %lu\n", vm_get_single_stat(vm, "remote_tlb_flus= h")); } =20 static void vcpu_stats_test(struct kvm_vm *vm, int vcpu_id) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index d9c660913403..dad54f5d57e7 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2660,3 +2660,56 @@ void dump_vm_stats(struct kvm_vm *vm) close(stats_fd); } =20 +static int vm_get_stat_data(struct kvm_vm *vm, const char *stat_name, + uint64_t **data) +{ + 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; + + *data =3D NULL; + + stats_fd =3D vm_get_stats_fd(vm); + + header =3D read_vm_stats_header(stats_fd); + + stats_desc =3D read_vm_stats_desc(stats_fd, header); + + size_desc =3D stats_desc_size(header); + + /* 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); + } + + free(stats_desc); + free(header); + + close(stats_fd); + + return ret; +} + +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name) +{ + uint64_t *data; + uint64_t value; + int ret; + + ret =3D vm_get_stat_data(vm, stat_name, &data); + TEST_ASSERT(ret =3D=3D 1, "Stat %s expected to have 1 element, but has %d= ", + stat_name, ret); + value =3D *data; + free(data); + return value; +} + --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 16:32:45 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 722A4C433EF for ; Mon, 21 Mar 2022 00:27:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343924AbiCUA21 (ORCPT ); Sun, 20 Mar 2022 20:28:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343901AbiCUA2J (ORCPT ); Sun, 20 Mar 2022 20:28:09 -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 87BCCDE924 for ; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id x18-20020a170902ea9200b00153e0dbca9bso3395054plb.9 for ; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=w72ktL2NVaulWnSOLwhUAw/SEUZ2qLk7Ydqg7suvoo4=; b=fx1XCeSYsDcHoKzCEPO5QZTH/7lJHeMLn4C/eT3bSq9992/wm8zBqAZSk2S8ps8OVp YVMnCJq6mRf809eIU4L/Cez2s4PciznmUAWKOwgFPAp82mqDTNJnQY4VLW7Odu7kWy5I K5X/MNocMz7n6KTZPyq7pkGdo5582uc8RzaV4LVqKe5OYI/C7nLQovCZYIQKKlT0jqGu H28bbR4alZOzfpAwlcHASL/0YDA46pxKWiSHQUpbGUQkE5ccSQDXy7tm3II7/dBe9UeA BXovdb4Gr/rmvzC405fiMovRJthVWFMRzeRyKDahyKfYQeVZ60hGjjcMbkUQ3fO7ZSE6 DpTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=w72ktL2NVaulWnSOLwhUAw/SEUZ2qLk7Ydqg7suvoo4=; b=NqKQS4xpRohqLAhKwx+g8cHt1i6D1WmLD1HeXBC1RtfdNqxkR8DQ7R2oNdROg4uRqC NdD2TbOJBmwmgiiCzWbOxaMtwf57CJKAt7r7rL/vkBIDHpaxo/wIyNo1+JQib3CQnKuX GxPgVllexKY9pCT4bVXMYFufItmDar+9WsGFfIxkmOtDE51sVMX+nM4xsqQA8c81FCXm wNveMRnaDk47lNKP1oNc6jIIxc3MLkbJPUk9f3yQtGvFpbIsRLDyYK7ITU8SI2J9s9Xu 2ho5382kgHSndtZRQy7a7L1ui/zDGaFuFP9igQTe1Trpaxx+0NPhgm5Og/nQKMgqeVTH KN+A== X-Gm-Message-State: AOAM533vy0Xf4uLgQWo5PO6jNXv6b6bbybHYS7534zgluOIY6EQXbWya QUNbWcvynjKl+ME/EWLihFyiPG6ug7Sw X-Google-Smtp-Source: ABdhPJxbX88VuJKl737VvBq/vCrgo6XQMNEN18CqZbwf3ZJmJ6wNbhkzBo6bEjn+oSxahPeVrtMULAZs1R6L X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:aa7:8432:0:b0:4f6:6dcd:4f19 with SMTP id q18-20020aa78432000000b004f66dcd4f19mr21345407pfn.53.1647822405012; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:37 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-4-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 3/4] KVM: x86/mmu: explicitly check nx_hugepage in disallowed_hugepage_adjust() From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , 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 extra check to specify the case of nx hugepage and allow KVM to reconstruct large mapping after dirty logging is disabled. Existing code works only for nx hugepage but the condition is too general in that does not consider other usage case (such as dirty logging). Moreover, existing code assumes that a present PMD or PUD indicates that there exist 'smaller SPTEs' under the paging structure. This assumption may no be true if consider the zapping leafs only behavior in MMU. Missing the check causes KVM incorrectly regards the faulting page as a NX huge page and refuse to map it at desired level. And this leads to back performance in shadow mmu and potentiall TDP mmu. Fixes: b8e8c8303ff2 ("kvm: mmu: ITLB_MULTIHIT mitigation") Cc: stable@vger.kernel.org Reviewed-by: Ben Gardon Signed-off-by: Mingwei Zhang --- arch/x86/kvm/mmu/mmu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 5628d0ba637e..4d358c273f6c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -2919,6 +2919,16 @@ void disallowed_hugepage_adjust(struct kvm_page_faul= t *fault, u64 spte, int cur_ cur_level =3D=3D fault->goal_level && is_shadow_present_pte(spte) && !is_large_pte(spte)) { + struct kvm_mmu_page *sp; + u64 page_mask; + /* + * When nx hugepage flag is not set, there is no reason to + * go down to another level. This helps demand paging to + * generate large mappings. + */ + sp =3D to_shadow_page(spte & PT64_BASE_ADDR_MASK); + if (!sp->lpage_disallowed) + return; /* * A small SPTE exists for this pfn, but FNAME(fetch) * and __direct_map would like to create a large PTE @@ -2926,8 +2936,8 @@ void disallowed_hugepage_adjust(struct kvm_page_fault= *fault, u64 spte, int cur_ * patching back for them into pfn the next 9 bits of * the address. */ - u64 page_mask =3D KVM_PAGES_PER_HPAGE(cur_level) - - KVM_PAGES_PER_HPAGE(cur_level - 1); + page_mask =3D KVM_PAGES_PER_HPAGE(cur_level) - + KVM_PAGES_PER_HPAGE(cur_level - 1); fault->pfn |=3D fault->gfn & page_mask; fault->goal_level--; } --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 16:32:45 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 87102C433EF for ; Mon, 21 Mar 2022 00:27:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343946AbiCUA23 (ORCPT ); Sun, 20 Mar 2022 20:28:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343912AbiCUA2L (ORCPT ); Sun, 20 Mar 2022 20:28:11 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08B7DDE915 for ; Sun, 20 Mar 2022 17:26:47 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id mm2-20020a17090b358200b001bf529127dfso8195674pjb.6 for ; Sun, 20 Mar 2022 17:26:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=Fmv+HMc2DFxNt8CxUdSLz9dfbbTJJCLxSOxGsXm4RyU=; b=p6WWOu56th14hFbz/vDJsj1YNlhWpB7KWlRQjlG5lF4dyCxZxdkzJkQU/tJPoez92d maakq/dfxmhfKGNOZYWMgEKpDoKtFAgijvHMmtYdKhUALE5ymi1R5lTAcHpGpyth9NMf zLrmS3vhHPaaPsoQVmefiC/MjXoB0+gEZmiY0coOY2wrbWU/wCxd4F5t1N8bnMiJd+ab nhjgojLKs3DtNzC0Bm6ejviuERcb3oxb7/dkWQtPSyV0kSSm2ArXx1WZTCNoLXs8rwBY ecDJ78LUFg6Exe7b5GrWHuRX2wfCdtxK8sQe0zG5z1W/0Afu2KR9/lsuAYZrKEoSzkgu 7KrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=Fmv+HMc2DFxNt8CxUdSLz9dfbbTJJCLxSOxGsXm4RyU=; b=YEdiCDyHe/KwXyMeJqGpM737PXoGemSD7uFoGUuEYusJC+v5Wxo9aOm7TTiogL003B 8OYGd6IW7h9xgrf2INI0cpt6KlAXPKMdV5UcxGrA5Pi6c2tpwKTYx2BWaB61WMBcv2QR MokIGBp9EGdOSOlw4AHeZT5FBD0dWyqp/6mSC1oOd583LWxkCFJY4sCkWrKds0q5rAGE z5lTDa7kQJoyrPM+XFMsUI8hH6RMv57bZmXkFso3BWvGiRbK68NQpS14GqZY92Jc7Or3 agmBEqbL2F3tTslJV97cgHc4FXYUV9sj0v5QbL+yImzVYk+j0nLiqvM04PikUGLCWyOU I8EA== X-Gm-Message-State: AOAM530E/ksQTx9hjgRjIpqju44hdVLOJuoMSa5Jk4MKGcrVsUih0Jxk AJl7+rXY4Y8nB1qaXtwD795RKDJBM541 X-Google-Smtp-Source: ABdhPJyKZwK8L7OgfM5eCJrVgG7L/KDRJs9ML8qnRmGqUKzDjY6RiXCxrTBNf2fA8anI5bY3FN33eH2UxTo1 X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:902:b941:b0:14d:af72:3f23 with SMTP id h1-20020a170902b94100b0014daf723f23mr10621824pls.6.1647822406401; Sun, 20 Mar 2022 17:26:46 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:38 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-5-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 4/4] selftests: KVM: use dirty logging to check if page stats work correctly From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , 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" When dirty logging is enabled, KVM splits the all hugepage mapping in NPT/EPT into the smallest 4K size. This property could be used to check if the page stats metrics work properly in KVM mmu. At the same time, this logic might be used the other way around: using page stats to verify if dirty logging really splits all huge pages. Moreover, when dirty logging is disabled, KVM zaps corresponding SPTEs and we could check whether the large pages come back when guest touches the pages again. So add page stats checking in dirty logging performance selftest. In particular, add checks in three locations: - just after vm is created; - after populating memory into vm but before enabling dirty logging; - just after turning on dirty logging. - after one final iteration after turning off dirty logging. Tested using commands: - ./dirty_log_perf_test -s anonymous_hugetlb_1gb - ./dirty_log_perf_test -s anonymous_thp Cc: Sean Christopherson Cc: David Matlack Cc: Jing Zhang Cc: Peter Xu Suggested-by: Ben Gardon Signed-off-by: Mingwei Zhang Suggested-by: Ben Gardon --- .../selftests/kvm/dirty_log_perf_test.c | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index 1954b964d1cf..ab0457d91658 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -19,6 +19,10 @@ #include "perf_test_util.h" #include "guest_modes.h" =20 +#ifdef __x86_64__ +#include "processor.h" +#endif + /* How many host loops to run by default (one KVM_GET_DIRTY_LOG for each l= oop)*/ #define TEST_HOST_LOOP_N 2UL =20 @@ -185,6 +189,14 @@ static void run_test(enum vm_guest_mode mode, void *ar= g) p->slots, p->backing_src, p->partition_vcpu_memory_access); =20 +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") =3D=3D 0, + "4K page is non zero"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") =3D=3D 0, + "2M page is non zero"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") =3D=3D 0, + "1G page is non zero"); +#endif perf_test_set_wr_fract(vm, p->wr_fract); =20 guest_num_pages =3D (nr_vcpus * guest_percpu_mem_size) >> vm_get_page_shi= ft(vm); @@ -222,6 +234,16 @@ static void run_test(enum vm_guest_mode mode, void *ar= g) pr_info("Populate memory time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); =20 +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") !=3D 0, + "4K page is zero"); + if (p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_THP) + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") !=3D 0, + "2M page is zero"); + if (p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB) + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") !=3D 0, + "1G page is zero"); +#endif /* Enable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); enable_dirty_logging(vm, p->slots); @@ -267,6 +289,14 @@ static void run_test(enum vm_guest_mode mode, void *ar= g) iteration, ts_diff.tv_sec, ts_diff.tv_nsec); } } +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") !=3D 0, + "4K page is zero after dirty logging"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") =3D=3D 0, + "2M page is non-zero after dirty logging"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") =3D=3D 0, + "1G page is non-zero after dirty logging"); +#endif =20 /* Disable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); @@ -275,6 +305,28 @@ static void run_test(enum vm_guest_mode mode, void *ar= g) pr_info("Disabling dirty logging time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); =20 +#ifdef __x86_64__ + /* + * Increment iteration to run the vcpus again to verify if huge pages + * come back. + */ + iteration++; + pr_info("Starting the final iteration to verify page stats\n"); + + for (vcpu_id =3D 0; vcpu_id < nr_vcpus; vcpu_id++) { + while (READ_ONCE(vcpu_last_completed_iteration[vcpu_id]) + !=3D iteration) + ; + } + + if (p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_THP) + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") !=3D 0, + "2M page is zero"); + if (p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB) + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") !=3D 0, + "1G page is zero"); +#endif + /* Tell the vcpu thread to quit */ host_quit =3D true; perf_test_join_vcpu_threads(nr_vcpus); --=20 2.35.1.894.gb6a874cedc-goog