From nobody Mon Jun 22 13:25:03 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 87857C433EF for ; Wed, 23 Mar 2022 18:49:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344068AbiCWSvD (ORCPT ); Wed, 23 Mar 2022 14:51:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344036AbiCWSu6 (ORCPT ); Wed, 23 Mar 2022 14:50:58 -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 2DB36606C9 for ; Wed, 23 Mar 2022 11:49:28 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id j15-20020a17090a2a8f00b001c6d6b729f1so1537217pjd.3 for ; Wed, 23 Mar 2022 11:49:28 -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=qTS21wkEWABNY1jzlT826LGEEw+Mx9qBCQN67s1iDR0=; b=ojSuOEDbQMMJrJdn8gzbLSLOHX10VrXaeCYOwNgJtqZXGAxsdk0LnEnzw+WEL9URty RKgVq5IJFM2+stHUcL+5KyUa+67vcJ2iwyVPUqz1JIxV4o2FkwMR1hLy2XO+nUtUdqg/ /Z8popm0QbG58Ijeh8QfmRgWF9E//Pe5mZ/lLbjjuv5/dAqpEvC1m0+Uo731v7qyY3ha WPZgePdvuwcW2LFVqlMiHf+QzFHb5rj5Zxn5rMezvOc+PYYAdM9SKZPrSw9NiusFSTzn z/aZp2AoIoTLOEsm2mWTzsk8Pxdj9MCEioKW8GWwtNzcA3Dh3VL8k27p1fwQAlC+7Ow7 e81w== 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=qTS21wkEWABNY1jzlT826LGEEw+Mx9qBCQN67s1iDR0=; b=yvkcOuT6ZpE3719Sx84S5P8pCJl324jWKq3R61xCYwSEXcyszp3SbQwVm5b0QfiG9O 37Xa55I4LPjV1tpiRedmt11k3OMMcz0iT3EeB8HM73+ltGEPizojtjH7guCcGIeY61MN E5jO5ULlkWYwRfzspio1U9/f/jZifza56MQWSFXBvDlyTyby7bgErvCxUEBNYOTdU1Q1 5HPsfSC3U27zLJSVSbj23386ycKzOuK2p+wOh2M5NZKvGRNBdVWVWqJajEE0ja200Rep HLtnxarZpWALW7qD6gjuUieL5wADYKh4yGhQpMKuAFGpb/C/cuYxmoee+bQIBbWFuU9k Rl2Q== X-Gm-Message-State: AOAM530ufpGqnO6PuDMUUdOouHe76ac/MBQKPj8oEeB20wwjjWJT3Geg edIRuZ8ueKSpp74DyGzTGRHizknm/CsD X-Google-Smtp-Source: ABdhPJyoVcF8h6jck24aHkxoGr/x2SGTRsrf5r2aJG6aCMt9tl3FAUkOyFAPpHl2MoKfj7GT64tuvM2YzQIr X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:903:2411:b0:151:8304:6936 with SMTP id e17-20020a170903241100b0015183046936mr1432965plo.134.1648061367699; Wed, 23 Mar 2022 11:49:27 -0700 (PDT) Reply-To: Mingwei Zhang Date: Wed, 23 Mar 2022 18:49:12 +0000 In-Reply-To: <20220323184915.1335049-1-mizhang@google.com> Message-Id: <20220323184915.1335049-3-mizhang@google.com> Mime-Version: 1.0 References: <20220323184915.1335049-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.1021.g381101b075-goog Subject: [PATCH v2 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 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.1021.g381101b075-goog From nobody Mon Jun 22 13:25:03 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 0AF59C433EF for ; Wed, 23 Mar 2022 18:49:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344094AbiCWSvO (ORCPT ); Wed, 23 Mar 2022 14:51:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344053AbiCWSvA (ORCPT ); Wed, 23 Mar 2022 14:51:00 -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 D72CA60A88 for ; Wed, 23 Mar 2022 11:49:29 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id j15-20020a17090a2a8f00b001c6d6b729f1so1537248pjd.3 for ; Wed, 23 Mar 2022 11:49:29 -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=ZvZ7NXHw7GzgGFsDiaZ7LRsy8v/D1TyF5VT8AtGFPGQ=; b=DePjTDEbt2mBZO6bE7QxHlJoCYjmip+Tcmpp5fXYjuKqOHHl8lmUfImaNga5rahcF5 xuJirINC1eb3WRbNw3LHscTxBz9j6ruk47BtkQpLOZVRh7LGeyjES1/eMCKqhYX8tNl1 QDUEbfO68/Ua3Ww1rGQw4wDKDUQFutiLqXYpO/CUG7dkHS0XhTWqChff5ETD37vFIFjB uf+0RYheQSH1lMCj4QIMhdu9+DIdzjdrEEHOGJh9K1KmEO5/1Tlq+xVRQ+HR0oOizO0v q2c6oAfx54KDKI3xbJRK6aqlllVbSejtYLtTEPaoTRyIHTCoGrJGDjtvQ/KejvdkmSee PiAA== 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=ZvZ7NXHw7GzgGFsDiaZ7LRsy8v/D1TyF5VT8AtGFPGQ=; b=jo502TEYCIzouTlY2mjnk5qbigayLDAOMsKXMBbr928Q6HOw8UJejP2x3lNSARuW4c Zh9JfHgmxuvpJHvUOmqJzizx912o+UlENVYy/WEIHqqnpc0/66Xz40zKpm8zzsfU/H0e Ul/1Ry0kBUwIdZW9q0Aw1X8nZK5rYPpttxE4ILp8MQjnaexv60sqd+5aGTPJ90CfS4s4 mpCrYXXOrGwODDsEvfyLKiAjphk+RMBtUGmbq0mtMmRabvIVwrKT7C+HM40mhEi6TZvl c6GE434cJ41+UfIhTOzxbmkTFxL3nlUr7OK+KrFHOmM+YUiaKBPhkNVQpp95C2nzLwEn Ckmw== X-Gm-Message-State: AOAM532i9OySPdcj7uYo2g/nx9Qrp8jXMCyF4ZwwXwkjRXk54dfvijpo I0Wj0wEefAi8N+iaJQoVUEK2q01QNDuq X-Google-Smtp-Source: ABdhPJyGv0uu1UznuwbbBIAbEyI3XHYc+M6XclgiUwlGGmq73ohYQxiTedK9gcBFElWoRgfQeW4Eb4SD5uFb X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a63:7f1c:0:b0:382:1fb5:58b8 with SMTP id a28-20020a637f1c000000b003821fb558b8mr947103pgd.507.1648061369343; Wed, 23 Mar 2022 11:49:29 -0700 (PDT) Reply-To: Mingwei Zhang Date: Wed, 23 Mar 2022 18:49:13 +0000 In-Reply-To: <20220323184915.1335049-1-mizhang@google.com> Message-Id: <20220323184915.1335049-4-mizhang@google.com> Mime-Version: 1.0 References: <20220323184915.1335049-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.1021.g381101b075-goog Subject: [PATCH v2 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 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.1021.g381101b075-goog From nobody Mon Jun 22 13:25:03 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 13051C433FE for ; Wed, 23 Mar 2022 18:49:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344070AbiCWSvL (ORCPT ); Wed, 23 Mar 2022 14:51:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49282 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344032AbiCWSvB (ORCPT ); Wed, 23 Mar 2022 14:51:01 -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 66D7C60CC8 for ; Wed, 23 Mar 2022 11:49:31 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id g19-20020a17090a579300b001b9d80f3714so1528204pji.7 for ; Wed, 23 Mar 2022 11:49:31 -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=i3y/R2G/yOzk3wi7p2qOKXA2BvyWMGeSAE7HqxAnaPU=; b=eZP/RLC9xeAaOFNwwbxYUIxPtQMvTN3IXnMmR4pGyi2YtpEhddJBpbpmaTPlJD1MYD 1LivnC4WvLcy+TtAP1TFFzuD35h42ZXmVOtHd4cn7vMNKfDVtNNrKdVPLAfNJnajfCsb c8DX7jLm1/Da4Cv8rR+1R2oBGizMEEbDZoaWHGXlr5I9XdE4M1aMRAc6VjZxJ+wyU6KC OBZoBMaArnYbwAU3rogO0VToAPFYgdJY//UDGCMX6YljpHNPHkHAwHMoPOld2MbEBSKF d8WjcmsMnQYBKH6f2XJ1VP19vPxMpbypqayzj/MUSwLpUkChdDY1hmBHhP2ZRb3KhWQf GC1g== 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=i3y/R2G/yOzk3wi7p2qOKXA2BvyWMGeSAE7HqxAnaPU=; b=al2jpc6UGjq88tPvgHB6PayGjZbdSOr9+goTby8Lqi9+T0zUKgdzMERu2vkLvxR7B4 Rexot11V4HvJx3ZHH9eOmVa8Tm1hflLvV90lcq2DXNmdEwKohNeN6JFAR7j65Zf4wxyt 5SolqR3iANZfGAudBN5QTuNF5JQmzWL/4pW9RhLEEYbxl/c+S8u8jg5+7tKxyHaMjIb5 nuIEZ2FB+M+IvF8lsxeBmHXo6JtyoYCt0Qt+yOQL33TBrDNk72SKHwb4rmgpUQ/rT3rG 7d1lzR1gZSsM+oBK1idoupNknuy5o6S9ERgCm8gn03Jj3nujGadMIU+sus/oz1fSisn9 7WxQ== X-Gm-Message-State: AOAM531TBOnHSFG+mXgJxTU0WKBwSelZkBIzS4PNvutG2Vk+QlmBw4ux QHpw0z70iJtI3GRJfi9EZrGnwoeuwiBJ X-Google-Smtp-Source: ABdhPJwy9+hoP4haE+2RiusYHIP0dKJx4cZVl9ra6s7X/D91BaloL9b86cNA0SFB2RLUzX7nIuAmslbBtlfI X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:90a:1d04:b0:1bc:98ca:5e6f with SMTP id c4-20020a17090a1d0400b001bc98ca5e6fmr13721397pjd.32.1648061370937; Wed, 23 Mar 2022 11:49:30 -0700 (PDT) Reply-To: Mingwei Zhang Date: Wed, 23 Mar 2022 18:49:14 +0000 In-Reply-To: <20220323184915.1335049-1-mizhang@google.com> Message-Id: <20220323184915.1335049-5-mizhang@google.com> Mime-Version: 1.0 References: <20220323184915.1335049-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.1021.g381101b075-goog Subject: [PATCH v2 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 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). Note that when dirty logging is disabled, KVM calls kvm_mmu_zap_collapsible_sptes() which only zaps leaf SPTEs. 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 KVM zaps only leafs 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 issue in shadow mmu and potentially in TDP mmu as well. 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..d9b2001d8217 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 KVM re-generate large + * mappings after dirty logging disabled. + */ + 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.1021.g381101b075-goog From nobody Mon Jun 22 13:25:03 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 11E9EC433F5 for ; Wed, 23 Mar 2022 18:49:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344117AbiCWSv0 (ORCPT ); Wed, 23 Mar 2022 14:51:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344073AbiCWSvH (ORCPT ); Wed, 23 Mar 2022 14:51:07 -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 BE1D260D8D for ; Wed, 23 Mar 2022 11:49:32 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id z10-20020a634c0a000000b0036c5eb39076so1091748pga.18 for ; Wed, 23 Mar 2022 11:49:32 -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=c5fKyu9jH6XE+xJIVIS/L5W4c26nrxs3xWXA5jPM5YY=; b=C10LlrNWhm5bgZg0y2T/cSnRWn4NBv6Ijy73wn6fsYLtVEUL3MMaxw54JXOLlBTv5a rEp1JHZVuekBqV0GnPIZlSn42sL9jJxM5z2FiEMxawlv8e4IFUnLSht3LAgncURiXIv9 X03pTiQKbwSpWLbW/+uv9hfjxViNtYEzD9Q4TG5xr3CXpfkGhNIa9hYJQrjNuzueHEvb AmRBZAsmQpWTw5SkbcX5z4s1q7yCKJXgnGdcOnEiUi7GoBsWclCRnC1hxRxrFOOAAolz lC6jkplgy96DC+JPbcLIxIZLrEO9c7Lw65m4cw726nQuwRnrV++Y//AN7EwTVIB1HLcc 8ZBg== 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=c5fKyu9jH6XE+xJIVIS/L5W4c26nrxs3xWXA5jPM5YY=; b=7wL7TYpdPVTMSuRhrkGiujyzgaAjcZa1h9RHgC6p/A81mLM5kM+BYZgG0PAERcfkoc xQb0NUpX7/+l9uSKlr9p/1BtbLQ0WcKkY7A6M7bbsdtN0pphvRYLIl4Z49pZmzGdkjPs 1X3+CoCDY9VXbY1gZ6EoRZcLMxpZjqtLmTqCLYcPPcHzb/i2tHRi9FEAW4tOlduMM0u5 K7vfQqJpYRzk0go0+aSbVSlkHpmeCbmu44krzgzghAdAb84eyMa84i1huGrA5153bz3w UnHONr2fs7bPilZ8phIDyKvsz6caC/HNws+9SqC8EIszV3OVEKzZddV6sOunXiAj56we cO3A== X-Gm-Message-State: AOAM530DqN/hbfgFvcsyVh01PEBZPoLRSGMPklC4TCaa9Gf88V8PiaFZ fRKq4+AmN4UnvVi0zQg7421vXSgLdv+G X-Google-Smtp-Source: ABdhPJw3TuVBjn2xN6D1q57cS12a8wgK2abT8t4Ffi0TQtHWkk8eOzNArS5pVnsQWrxWouXWLqUKQflUznSt X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:903:1d1:b0:154:61ec:749b with SMTP id e17-20020a17090301d100b0015461ec749bmr1495211plh.52.1648061372281; Wed, 23 Mar 2022 11:49:32 -0700 (PDT) Reply-To: Mingwei Zhang Date: Wed, 23 Mar 2022 18:49:15 +0000 In-Reply-To: <20220323184915.1335049-1-mizhang@google.com> Message-Id: <20220323184915.1335049-6-mizhang@google.com> Mime-Version: 1.0 References: <20220323184915.1335049-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.1021.g381101b075-goog Subject: [PATCH v2 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 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 will remap all accessed pages in NPT/EPT at 4K. 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; - finish dirty logging but before disabling it; - behind the final iteration after disabling dirty logging. Tested using commands: - ./dirty_log_perf_test -s anonymous_hugetlb_1gb - ./dirty_log_perf_test -s anonymous_hugetlb_2mb - ./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 Reviewed-by: Ben Gardon --- .../selftests/kvm/dirty_log_perf_test.c | 53 +++++++++++++++++++ 1 file changed, 53 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..21431b0f5547 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,17 @@ 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 || + p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_HUGETLB_2MB) + 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 +290,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 +306,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 + /* + * Increment iteration to run the vcpus again to ensure all pages come + * back. + */ + iteration++; + pr_info("Starting the final iteration to get all pages back.\n"); + for (vcpu_id =3D 0; vcpu_id < nr_vcpus; vcpu_id++) { + while (READ_ONCE(vcpu_last_completed_iteration[vcpu_id]) + !=3D iteration) + ; + } + +#ifdef __x86_64__ + if (p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_THP || + p->backing_src =3D=3D VM_MEM_SRC_ANONYMOUS_HUGETLB_2MB) + 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.1021.g381101b075-goog