From patchwork Mon Apr 11 21:10:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809651 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 71A73C433FE for ; Mon, 11 Apr 2022 21:10:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350025AbiDKVM5 (ORCPT ); Mon, 11 Apr 2022 17:12:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38008 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350014AbiDKVMz (ORCPT ); Mon, 11 Apr 2022 17:12:55 -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 A1B6E18B0D for ; Mon, 11 Apr 2022 14:10:38 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id z3-20020a170903018300b001585ef89813so1475573plg.21 for ; Mon, 11 Apr 2022 14:10:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kJgMoCAjhZF08CgV3+jJ2ov9zdWBjUSyLPZfA15qjOk=; b=B1yK7n6ZfFUfK1bizsnRSAreeQmV+uitxPCS7NJyd6tleGrqGPsczFz4fmJWbnJT8i c9J395P0abuq+kKprK3PO0O6A7vhMQsPNcD9akSwJaJUMktxk/LN44khMc1bwMeJ4ZZI j6waqiifNBYXRR5UpjRk/nff2Az0lr4T/eqOoidoYzmnbpswmssa8p4FIWLmOo0LeUfi RwTMlnheEI30n2vRphdKBlzjdoK47/lwN1D5JLPCfXbw57klYnTkZ9EA7bKvNTo5a61u JaUSJEW9zldw4y+QNyCpt9cqiL0r97EmYULHjPeNkAWpVMlrwLkV9EVwDHRQuFvaBPMv jDdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kJgMoCAjhZF08CgV3+jJ2ov9zdWBjUSyLPZfA15qjOk=; b=MZcvqtRIUTOIL/dhXT513r0+v27JqGe9PFePDA93aD98OJl2/+8xOh68guVRN8k0fe pf+mk05VkkcenkgQGXgPaN263S2Euy3vDJg2BJctBDaQkBFZv10mcr7uNQb4AfeBdACs biz9LM3QQZgLdE+2kokp20/8KMJ2BhxuKEykrGro08HxKpDsX8A/5YwpOZiUywC353AP f1OhCsxyuXectgyQPQqO3hntxeLwswF1BhGuIZchVBXbawuPQFaxmMYroWeSjAZI61Ex YvFB2sYyFCcQguqJeBUwj9U2tNGrmGt5cntSVpMN1je0cdKL/hXnywynlXRg3WWb+AX5 JvxA== X-Gm-Message-State: AOAM530EbhapYio6qK2hxbIl/44M4ucjKJxWDKofiL/x+c9uIz35JjnW tUOno2u49+bYW7POpapYVdr/QmXQnHve X-Google-Smtp-Source: ABdhPJxRz84knoKx1GpcAy3ttUlScLwKOziY1SrT418kLk5rHFDxHG/9t9dbma3H8fJL3QXGxEkPuoDVYIsO X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:903:1251:b0:156:9d8e:1077 with SMTP id u17-20020a170903125100b001569d8e1077mr33659510plh.116.1649711438004; Mon, 11 Apr 2022 14:10:38 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:06 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-2-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 01/10] KVM: selftests: Remove dynamic memory allocation for stats header From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org There's no need to allocate dynamic memory for the stats header since its size is known at compile time. Signed-off-by: Ben Gardon Reviewed-by: David Matlack Reviewed-by: Mingwei Zhang --- .../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/testing/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 = 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; /* Read kvm stats header */ - header = malloc(sizeof(*header)); - TEST_ASSERT(header, "Allocate memory for stats header"); - - ret = read(stats_fd, header, sizeof(*header)); - TEST_ASSERT(ret == sizeof(*header), "Read stats header"); - size_desc = sizeof(*stats_desc) + header->name_size; + ret = read(stats_fd, &header, sizeof(header)); + TEST_ASSERT(ret == sizeof(header), "Read stats header"); + size_desc = sizeof(*stats_desc) + header.name_size; /* Read kvm stats id string */ - id = malloc(header->name_size); + id = malloc(header.name_size); TEST_ASSERT(id, "Allocate memory for id string"); - ret = read(stats_fd, id, header->name_size); - TEST_ASSERT(ret == header->name_size, "Read id string"); + ret = read(stats_fd, id, header.name_size); + TEST_ASSERT(ret == header.name_size, "Read id string"); /* 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); /* Sanity check for other fields in header */ - if (header->num_desc == 0) { + if (header.num_desc == 0) { printf("No KVM stats defined!"); return; } /* Check overlap */ - TEST_ASSERT(header->desc_offset > 0 && header->data_offset > 0 - && header->desc_offset >= sizeof(*header) - && header->data_offset >= sizeof(*header), + TEST_ASSERT(header.desc_offset > 0 && header.data_offset > 0 + && header.desc_offset >= sizeof(header) + && header.data_offset >= sizeof(header), "Invalid offset fields in header"); - TEST_ASSERT(header->desc_offset > header->data_offset || - (header->desc_offset + size_desc * header->num_desc <= - header->data_offset), + TEST_ASSERT(header.desc_offset > header.data_offset || + (header.desc_offset + size_desc * header.num_desc <= + header.data_offset), "Descriptor block is overlapped with data block"); /* Allocate memory for stats descriptors */ - stats_desc = calloc(header->num_desc, size_desc); + stats_desc = calloc(header.num_desc, size_desc); TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); /* Read kvm stats descriptors */ ret = pread(stats_fd, stats_desc, - size_desc * header->num_desc, header->desc_offset); - TEST_ASSERT(ret == size_desc * header->num_desc, + size_desc * header.num_desc, header.desc_offset); + TEST_ASSERT(ret == size_desc * header.num_desc, "Read KVM stats descriptors"); /* Sanity check for fields in descriptors */ - for (i = 0; i < header->num_desc; ++i) { + for (i = 0; i < header.num_desc; ++i) { pdesc = (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 += pdesc->size * sizeof(*stats_data); } /* Check overlap */ - TEST_ASSERT(header->data_offset >= header->desc_offset - || header->data_offset + size_data <= header->desc_offset, + TEST_ASSERT(header.data_offset >= header.desc_offset + || header.data_offset + size_data <= header.desc_offset, "Data block is overlapped with Descriptor block"); /* Check validity of all stats data size */ - TEST_ASSERT(size_data >= header->num_desc * sizeof(*stats_data), + TEST_ASSERT(size_data >= header.num_desc * sizeof(*stats_data), "Data size is not correct"); /* Check stats offset */ - for (i = 0; i < header->num_desc; ++i) { + for (i = 0; i < header.num_desc; ++i) { pdesc = (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 = malloc(size_data); TEST_ASSERT(stats_data, "Allocate memory for stats data"); /* Read kvm stats data as a bulk */ - ret = pread(stats_fd, stats_data, size_data, header->data_offset); + ret = pread(stats_fd, stats_data, size_data, header.data_offset); TEST_ASSERT(ret == size_data, "Read KVM stats data"); /* Read kvm stats data one by one */ size_data = 0; - for (i = 0; i < header->num_desc; ++i) { + for (i = 0; i < header.num_desc; ++i) { pdesc = (void *)stats_desc + i * size_desc; ret = pread(stats_fd, stats_data, pdesc->size * sizeof(*stats_data), - header->data_offset + size_data); + header.data_offset + size_data); TEST_ASSERT(ret == pdesc->size * sizeof(*stats_data), "Read data of KVM stats: %s", pdesc->name); size_data += 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); } From patchwork Mon Apr 11 21:10:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809652 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 99CD1C433F5 for ; Mon, 11 Apr 2022 21:10:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350030AbiDKVM5 (ORCPT ); Mon, 11 Apr 2022 17:12:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350015AbiDKVMz (ORCPT ); Mon, 11 Apr 2022 17:12:55 -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 5C37715822 for ; Mon, 11 Apr 2022 14:10:40 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id l3-20020a170903244300b001570540beb6so5012260pls.16 for ; Mon, 11 Apr 2022 14:10:40 -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=6WTud4t2/o0hsvjWQOQfdmuf5Jf6mvrUa1JIGUzDHLI=; b=VHuO5hifqls6sBiOFF5trRISTudPJeSwLA69oUCU92UK7hmXgQ3INRQpOKeXurszhH EDVKKYo5KOuKzaHnVJfH22q6tXxy+3wf3b+YDD40dAt1q2vuG18/51poqqXCto931V/n gP7pZY6UPTcqwOeqUPzi+IQAZne0jzBjhUbZE+qNGzBkT/TuS7m1NMlSZ/ruGj/aWvXQ Fly45ZuxfYEGtm15GgL0luQMUfYss1s3Bao9xsB5D/Wkb9pgR4C++cy6sRx6dlbfZFij AuOL6YT/sCdXkE9G/r3cSEpeSB3fJ3ayZ5QUgjExwRLjnlYd+SlX/ddQ6sktXzv8zTtg EPPg== 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=6WTud4t2/o0hsvjWQOQfdmuf5Jf6mvrUa1JIGUzDHLI=; b=rFGOPH+RetQ2M+MwvWjzjw5RBaLR1saKbXLiOLsH5YjyroM6iIjXAq8P2wqeXUZtrg Xud+kyl1PEfKz9wzWz7TQC/ZcKoo5Q8vufyTq9NrG4BxeehUsYMNEza6sZz8PB6t6NHP +xR6sJGFNLKzAP5W31B4OkMYYxHXzdh+rW0AJ2y2IJHTZtEkhxK+A0ULWcQBggKzcHLM wYPGPQWrSH2vmQFeoD9hvxHLoMNQzvADuc8lMCzj1Z2OdI7+FdZyuZ9lJXJ8h5pzSLU7 IvpdYbXLDnmrGIcTNsBQPuO7fb87Yuw1rqfZCOG0T+V+4P+DglLQE2Nm3iWvidOZVB5h 1qlg== X-Gm-Message-State: AOAM530IBduvg5PPVeLI/tPmJj7Rf4PwSBbT5P0JpLR6e7phGhxtBMLW V1smtZaKbws8ZP58cXRjn6ELPkgDoskE X-Google-Smtp-Source: ABdhPJzijb1tEhtGCiz626QqQz2oBsdS4t++17JOsaPUm80osckqSdyQGNl8CQiPE3Gl+j2KfvnOxc2Gz00D X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:903:2488:b0:156:1e8d:a82 with SMTP id p8-20020a170903248800b001561e8d0a82mr34228889plw.51.1649711439874; Mon, 11 Apr 2022 14:10:39 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:07 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-3-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 02/10] KVM: selftests: Read binary stats header in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move the code to read the binary stats header to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/include/kvm_util_base.h | 1 + tools/testing/selftests/kvm/kvm_binary_stats_test.c | 4 ++-- tools/testing/selftests/kvm/lib/kvm_util.c | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 92cef0ffb19e..5ba3132f3110 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, uint32_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_vm_stats_header(int stats_fd, struct kvm_stats_header *header); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index dad34d8a41fe..22c22a90f15a 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; /* Read kvm stats header */ - ret = read(stats_fd, &header, sizeof(header)); - TEST_ASSERT(ret == sizeof(header), "Read stats header"); + read_vm_stats_header(stats_fd, &header); + size_desc = sizeof(*stats_desc) + header.name_size; /* Read kvm stats id string */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 1665a220abcb..0caf28e324ed 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2556,3 +2556,11 @@ int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid) return ioctl(vcpu->fd, KVM_GET_STATS_FD, NULL); } + +void read_vm_stats_header(int stats_fd, struct kvm_stats_header *header) +{ + ssize_t ret; + + ret = read(stats_fd, header, sizeof(*header)); + TEST_ASSERT(ret == sizeof(*header), "Read stats header"); +} From patchwork Mon Apr 11 21:10:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809653 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 B6CB0C433F5 for ; Mon, 11 Apr 2022 21:10:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350038AbiDKVM7 (ORCPT ); Mon, 11 Apr 2022 17:12:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350014AbiDKVM5 (ORCPT ); Mon, 11 Apr 2022 17:12:57 -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 838D315822 for ; Mon, 11 Apr 2022 14:10:42 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id 78-20020a630551000000b0039958c05e70so9454362pgf.8 for ; Mon, 11 Apr 2022 14:10:42 -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=jowVcPeazSi67SHgtKHyWBS9ErkTHd94DAj2Ts0QL0M=; b=Fkyh/qBc5dAbHEPYor9iqLZ2edWjPV7qo03ufqQAJHs5D95oaD8g1hbsktBpWjPvd8 Tj9GgivDJotqnPauWNFysO5DvaLksOyFYeq0WEOq9k+BXexF9ZK5YA7j27I9YinVQRuq YYo8VRSpCeYCmwERrYYwq1qXnVf7h47eFGcKneLkLYymrLIVwooPor/E3ApLLjyp0+VC ASaaFV8CVJClt7aQtjPiw7HsMJERACVWfm/BoluRf+O1D0t2GM+vb/IZEgO+SO0K+IgB mFIPumy9JwhOMQtO3nHrUZLgCcirwK7VfF4EWnCjEf6WGiPnNXtTf0jtX1s8uhh3oIL8 X7HQ== 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=jowVcPeazSi67SHgtKHyWBS9ErkTHd94DAj2Ts0QL0M=; b=U/KaxIfsZKJgQebAsp0lUsQojflrLQk/cWZLNNjR0oKNauZb9pP81Dz/vLUTryqxLo dQFNIxao00m5NEW2dWRfuVVTWPqiuQqA4xbyn4DycrWv/4p17DQE50w3LKzzV/N2bztR 3AcoGrLl7fdpgNeuGG9GsiIj4meIHWaD3hH/2+zqJQPJ6hCPs8YwtKeRm7vvd8rMDcZa WsX4jZq5l65rpGWb8K6rk5jf9Pvqmgc+bSkd6R5Vn1cffsQXBD8WPT9a1nF+6kJE02TL 0SP9QGCZUfY/496yjQvPz1nXnfp/3KWJJsTtGniXvF/CXweTMG3BU78jZKV1PsYo1SWH YTjQ== X-Gm-Message-State: AOAM530/t3rq4qKL4yb4Lk9zQjvOXa/TjWuctWErBsldFrbT1zx15jew 6DGw1iuD1lFOKZhFOew+CbVi7HiNyCkV X-Google-Smtp-Source: ABdhPJw5goVNxXsGn1XxWfE1rh4zn1jaQ5MJFUoJlaymhAL+7IoXVGg0+wZdui9Zaj+6jHwCcufa++gDmrrn X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:90b:2384:b0:1cb:5223:9dc4 with SMTP id mr4-20020a17090b238400b001cb52239dc4mr116087pjb.1.1649711441713; Mon, 11 Apr 2022 14:10:41 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:08 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-4-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 03/10] KVM: selftests: Read binary stats desc in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move the code to read the binary stats descriptors to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon Signed-off-by: Sean Christopherson --- .../selftests/kvm/include/kvm_util_base.h | 4 +++ .../selftests/kvm/kvm_binary_stats_test.c | 9 ++---- tools/testing/selftests/kvm/lib/kvm_util.c | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 5ba3132f3110..c5f34551ff76 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -401,6 +401,10 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_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_vm_stats_header(int stats_fd, struct kvm_stats_header *header); +struct kvm_stats_desc *alloc_vm_stats_desc(int stats_fd, + struct kvm_stats_header *header); +void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *stats_desc); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index 22c22a90f15a..e4795bad7db6 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -62,14 +62,9 @@ static void stats_test(int stats_fd) header.data_offset), "Descriptor block is overlapped with data block"); - /* Allocate memory for stats descriptors */ - stats_desc = calloc(header.num_desc, size_desc); - TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); /* Read kvm stats descriptors */ - ret = pread(stats_fd, stats_desc, - size_desc * header.num_desc, header.desc_offset); - TEST_ASSERT(ret == size_desc * header.num_desc, - "Read KVM stats descriptors"); + stats_desc = alloc_vm_stats_desc(stats_fd, &header); + read_vm_stats_desc(stats_fd, &header, stats_desc); /* Sanity check for fields in descriptors */ for (i = 0; i < header.num_desc; ++i) { diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 0caf28e324ed..e3ae26fbef03 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2564,3 +2564,32 @@ void read_vm_stats_header(int stats_fd, struct kvm_stats_header *header) ret = read(stats_fd, header, sizeof(*header)); TEST_ASSERT(ret == 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); +} + +/* Caller is responsible for freeing the returned kvm_stats_desc. */ +struct kvm_stats_desc *alloc_vm_stats_desc(int stats_fd, + struct kvm_stats_header *header) +{ + struct kvm_stats_desc *stats_desc; + + stats_desc = malloc(stats_descs_size(header)); + TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); + + return stats_desc; +} + +void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *stats_desc) +{ + ssize_t ret; + + ret = pread(stats_fd, stats_desc, stats_descs_size(header), + header->desc_offset); + TEST_ASSERT(ret == stats_descs_size(header), + "Read KVM stats descriptors"); +} From patchwork Mon Apr 11 21:10:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809654 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 072B4C433EF for ; Mon, 11 Apr 2022 21:10:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350040AbiDKVNI (ORCPT ); Mon, 11 Apr 2022 17:13:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350014AbiDKVM7 (ORCPT ); Mon, 11 Apr 2022 17:12:59 -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 636B228989 for ; Mon, 11 Apr 2022 14:10:44 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id i184-20020a62c1c1000000b0050569a135c1so7683056pfg.3 for ; Mon, 11 Apr 2022 14:10:44 -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=PnhCdKeHHZWArDQ1iucb3AijNBhmwdSe4l8urUqIw/o=; b=kWej4LqMy2wG9GiOMR4EBwr5fY8uQGDDjlYT4c+BSMgcMMr/n4pfu/ZkxaknhQX9mQ HQ9PnUGA/rLimezn+RYxZT1qDXT+Xk8Kp8Oed0uBrJ93Mw0D49MzRmUmWdyqxZU6XKLn dsZWAj2kVr3HmVKSyzSfOFO/1XJ/lZmKhZc1UCo2xD/lLxE+LLVuJR/o/OTQ9fyEHbQ+ fEs4g83jZGh0KXTL0ATE7EgDsqvpqNsUfUGLDi6kAOHDk7wmlsX/pAHOqXIRzF07Oj35 UYhH09I8HwmBQMF1oJ2P5fGGSC5bASUCobdXbkesfpbyqcQXm80AYPTEKydotOIppkiJ T2PA== 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=PnhCdKeHHZWArDQ1iucb3AijNBhmwdSe4l8urUqIw/o=; b=fIHtefPpTaeLo/4MOAk9U7HN7J3XRJFZEGq82zLYn1l3mmfN8q/fZQmb2mgP2JjLlL 6YKAURFyaPvws+NJ0d/fwbUmEeD25ZYkAPQYO6cCMgWjxcApOS6sAkbkhFcR9MNl/vig 7IpKqeu+4KpVtOfTxWZWyDPcyBp7sYHbDvMZRzd5bIRE/add4C5roWnJcHP36RYwnRgQ NqYRheGqQ6bSk9QwVTQLDhd37Yu7Jrpwgo+2G5ZhZM9fDUKtEinkz0vF72bnAwHo+N/W O3cqxDnNoUJT8pX9PSRFVXANttJtJXPDjAjgHpXuItH7CBPM4NNjA79ZV+MIx2L3b/CS Hbsw== X-Gm-Message-State: AOAM5327SW2x/LwB1HPVBIZ/e2ZnnfLOxfg2RwiT6Cjxc8oKqn7UX/lo IANcQ/WgSUT3XGVrZTJLyH+QGjTXOMrx X-Google-Smtp-Source: ABdhPJzyY925u/CK4XLi0NlB4Y6g2g9YO6PFKhDKu7ugWNkxp0SyHsGt8vwqyRqoSKM8xEXH8oneEN7MaUsE X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:902:70c8:b0:156:509b:68e3 with SMTP id l8-20020a17090270c800b00156509b68e3mr34743852plt.113.1649711443803; Mon, 11 Apr 2022 14:10:43 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:09 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-5-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 04/10] KVM: selftests: Read binary stat data in lib From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move the code to read the binary stats data to the KVM selftests library. It will be re-used by other tests to check KVM behavior. No functional change intended. Signed-off-by: Ben Gardon Reviewed-by: Mingwei Zhang Signed-off-by: Mingwei Zhang --- .../selftests/kvm/include/kvm_util_base.h | 3 +++ .../selftests/kvm/kvm_binary_stats_test.c | 20 +++++------------- tools/testing/selftests/kvm/lib/kvm_util.c | 21 +++++++++++++++++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index c5f34551ff76..b2684cfc2cb1 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -405,6 +405,9 @@ struct kvm_stats_desc *alloc_vm_stats_desc(int stats_fd, struct kvm_stats_header *header); void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header, struct kvm_stats_desc *stats_desc); +int read_stat_data(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc, uint64_t *data, + ssize_t max_elements); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index e4795bad7db6..97b180249ba0 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -20,6 +20,8 @@ #include "asm/kvm.h" #include "linux/kvm.h" +#define STAT_MAX_ELEMENTS 1000 + static void stats_test(int stats_fd) { ssize_t ret; @@ -29,7 +31,7 @@ static void stats_test(int stats_fd) struct kvm_stats_header header; char *id; struct kvm_stats_desc *stats_desc; - u64 *stats_data; + u64 stats_data[STAT_MAX_ELEMENTS]; struct kvm_stats_desc *pdesc; /* Read kvm stats header */ @@ -130,25 +132,13 @@ static void stats_test(int stats_fd) pdesc->offset, pdesc->name); } - /* Allocate memory for stats data */ - stats_data = malloc(size_data); - TEST_ASSERT(stats_data, "Allocate memory for stats data"); - /* Read kvm stats data as a bulk */ - ret = pread(stats_fd, stats_data, size_data, header.data_offset); - TEST_ASSERT(ret == size_data, "Read KVM stats data"); /* Read kvm stats data one by one */ - size_data = 0; for (i = 0; i < header.num_desc; ++i) { pdesc = (void *)stats_desc + i * size_desc; - ret = pread(stats_fd, stats_data, - pdesc->size * sizeof(*stats_data), - header.data_offset + size_data); - TEST_ASSERT(ret == pdesc->size * sizeof(*stats_data), - "Read data of KVM stats: %s", pdesc->name); - size_data += pdesc->size * sizeof(*stats_data); + read_stat_data(stats_fd, &header, pdesc, stats_data, + ARRAY_SIZE(stats_data)); } - free(stats_data); free(stats_desc); free(id); } diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index e3ae26fbef03..64e2085f1129 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2593,3 +2593,24 @@ void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header, TEST_ASSERT(ret == stats_descs_size(header), "Read KVM stats descriptors"); } + +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 ret; + + TEST_ASSERT(desc->size <= max_elements, + "Max data elements should be at least as large as stat data"); + + ret = pread(stats_fd, data, desc->size * sizeof(*data), + header->data_offset + desc->offset); + + /* ret from pread is in bytes. */ + ret = ret / sizeof(*data); + + TEST_ASSERT(ret == desc->size, + "Read data of KVM stats: %s", desc->name); + + return ret; +} From patchwork Mon Apr 11 21:10:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809655 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 A382AC433FE for ; Mon, 11 Apr 2022 21:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350041AbiDKVNK (ORCPT ); Mon, 11 Apr 2022 17:13:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350051AbiDKVNG (ORCPT ); Mon, 11 Apr 2022 17:13:06 -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 48E3E21812 for ; Mon, 11 Apr 2022 14:10:46 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id p8-20020a170902e74800b001564f2593a5so6743221plf.2 for ; Mon, 11 Apr 2022 14:10:46 -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=aYlpO3UYkAwqMyaI9bGJppa8qvfnaOS91bqZ6ZkHXeY=; b=hLuSzACPO/kznpwt9mGV0klkrntD/6DK7gxP4cnjQvfnVEVuAXeC32X/id5XAmYjys aW/q/Ths/8TCFjD1G0vvymsRN1xFYhtlhARl9j/Ckt+ME9oxTjEIdj/qh5jIryzlnrnh gAoTmMKFb6tnPc/EVjTIgbDgO1Hk26RIhSssE+I2dmOn8f/ObnngLvAwOxne8A/lOF86 Yuv2NxSRiXxzbuxFrncfANxm1I/FMLabsmlfANqfNp1QA55gy1AmgrWxlJl6MQZ3EVL+ RTNEC7Y8c6rsjjAU8NtYb9tNTJPNgKkjb5zcKPD8TmuZiaCpQlvAYC+exvnF/sfeyCNo oBwg== 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=aYlpO3UYkAwqMyaI9bGJppa8qvfnaOS91bqZ6ZkHXeY=; b=UTjCEJpHSCw3fZ8XtbILPPRNRi8cIR3m/vggZQq3kERzu+WRKvEIeQdoHKvCzRY/MA P9QtVqGv8UR7du5uF3E+K3/kosYeuj5ZhzZDi0zIhBZ9WfWDZwH46YE6qGw/KHwMhbFO 4zstdX0UCcElyk6g3nDeURQHCLeXeF+zXH3rJwRkpT8cg/kEUeor1TnynNVq6yGirfzF UVMx4DYB6APOKR7NW3PN3VUr/SIyUy5w+VjTNT930JkntAvzs//dpvxr70bhLP8y2uTi 9VajaiDQbkYmM4nk9VtdqBG96LlPQq46MWnCoZ+fFJ6urt2bT0dKeiVztRy0HXhDG/r2 6J5A== X-Gm-Message-State: AOAM532eTjseosN1gqFIA8B09X6D+dDqeBhBJAhbvFUC1Dgler10ldMJ hUpYZAV7Z/pmC4SEtoVJg1f6jmgqLV6o X-Google-Smtp-Source: ABdhPJwAP4dQmoNOEYjRrqyz1l5KxDJMi14/Y/+uEwvrWrQQyI9TzWEpQ2UPaBEc8XtPQpoQ/ntKReOsDDc0 X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:90a:af86:b0:1c7:db8e:8589 with SMTP id w6-20020a17090aaf8600b001c7db8e8589mr1222150pjq.94.1649711445733; Mon, 11 Apr 2022 14:10:45 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:10 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-6-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 05/10] KVM: selftests: Add NX huge pages test From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org There's currently no test coverage of NX hugepages in KVM selftests, so add a basic test to ensure that the feature works as intended. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/Makefile | 10 ++ .../selftests/kvm/include/kvm_util_base.h | 1 + tools/testing/selftests/kvm/lib/kvm_util.c | 48 ++++++ .../selftests/kvm/x86_64/nx_huge_pages_test.c | 163 ++++++++++++++++++ .../kvm/x86_64/nx_huge_pages_test.sh | 25 +++ 5 files changed, 247 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 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handler LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c LIBKVM_riscv = lib/riscv/processor.c lib/riscv/ucall.c +# Non-compiled test targets +TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh + +# Compiled test targets TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test TEST_GEN_PROGS_x86_64 += x86_64/get_msr_index_features @@ -104,6 +108,9 @@ TEST_GEN_PROGS_x86_64 += steal_time TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test TEST_GEN_PROGS_x86_64 += system_counter_offset_test +# Compiled outputs used by test targets +TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test + TEST_GEN_PROGS_aarch64 += aarch64/arch_timer TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list @@ -142,7 +149,9 @@ TEST_GEN_PROGS_riscv += kvm_page_table_test TEST_GEN_PROGS_riscv += set_memory_region_test TEST_GEN_PROGS_riscv += kvm_binary_stats_test +TEST_PROGS += $(TEST_PROGS_$(UNAME_M)) TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M)) +TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(UNAME_M)) LIBKVM += $(LIBKVM_$(UNAME_M)) INSTALL_HDR_PATH = $(top_srcdir)/usr @@ -193,6 +202,7 @@ $(OUTPUT)/libkvm.a: $(LIBKVM_OBJS) x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))) all: $(STATIC_LIBS) $(TEST_GEN_PROGS): $(STATIC_LIBS) +$(TEST_GEN_PROGS_EXTENDED): $(STATIC_LIBS) cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib .. cscope: diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index b2684cfc2cb1..f9c2ac0a5b97 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -408,6 +408,7 @@ void read_vm_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); +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 64e2085f1129..833c7e63d62d 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2614,3 +2614,51 @@ int read_stat_data(int stats_fd, struct kvm_stats_header *header, return ret; } + +static int vm_get_stat_data(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 = -EINVAL; + int i; + + stats_fd = vm_get_stats_fd(vm); + + read_vm_stats_header(stats_fd, &header); + + stats_desc = alloc_vm_stats_desc(stats_fd, &header); + read_vm_stats_desc(stats_fd, &header, stats_desc); + + size_desc = sizeof(struct kvm_stats_desc) + header.name_size; + + /* Read kvm stats data one by one */ + for (i = 0; i < header.num_desc; ++i) { + desc = (void *)stats_desc + (i * size_desc); + + if (strcmp(desc->name, stat_name)) + continue; + + ret = read_stat_data(stats_fd, &header, desc, data, + max_elements); + } + + free(stats_desc); + close(stats_fd); + return ret; +} + +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name) +{ + uint64_t data; + int ret; + + ret = vm_get_stat_data(vm, stat_name, &data, 1); + TEST_ASSERT(ret == 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/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c new file mode 100644 index 000000000000..3f21726b22c7 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -0,0 +1,163 @@ +// 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 + +/* + * When writing to guest memory, write the opcode for the `ret` instruction so + * that subsequent iteractions can exercise instruction fetch by calling the + * memory. + */ +#define RETURN_OPCODE 0xC3 + +void guest_code(void) +{ + uint64_t hpage_1 = HPAGE_GVA; + uint64_t hpage_2 = hpage_1 + (PAGE_SIZE * 512); + uint64_t hpage_3 = 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 = vm_get_single_stat(vm, "pages_2m"); + + TEST_ASSERT(actual_pages_2m == 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 = vm_get_single_stat(vm, "nx_lpage_splits"); + + TEST_ASSERT(actual_splits == expected_splits, + "Unexpected nx lpage split count. Expected %d, got %d", + expected_splits, actual_splits); +} + +int main(int argc, char **argv) +{ + struct kvm_vm *vm; + struct timespec ts; + void *hva; + + vm = 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 = 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 = 0; + ts.tv_nsec = 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/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh new file mode 100755 index 000000000000..19fc95723fcb --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only */ + +# tools/testing/selftests/kvm/nx_huge_page_test.sh +# Copyright (C) 2022, Google LLC. + +NX_HUGE_PAGES=$(cat /sys/module/kvm/parameters/nx_huge_pages) +NX_HUGE_PAGES_RECOVERY_RATIO=$(cat /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio) +NX_HUGE_PAGES_RECOVERY_PERIOD=$(cat /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms) +HUGE_PAGES=$(cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages) + +echo 1 > /sys/module/kvm/parameters/nx_huge_pages +echo 1 > /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio +echo 100 > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms +echo 200 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +./nx_huge_pages_test +RET=$? + +echo $NX_HUGE_PAGES > /sys/module/kvm/parameters/nx_huge_pages +echo $NX_HUGE_PAGES_RECOVERY_RATIO > /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio +echo $NX_HUGE_PAGES_RECOVERY_PERIOD > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms +echo $HUGE_PAGES > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +exit $RET From patchwork Mon Apr 11 21:10:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809656 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 D4034C433F5 for ; Mon, 11 Apr 2022 21:11:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350117AbiDKVNN (ORCPT ); Mon, 11 Apr 2022 17:13:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350071AbiDKVNI (ORCPT ); Mon, 11 Apr 2022 17:13:08 -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 43E7C2AE24 for ; Mon, 11 Apr 2022 14:10:48 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id l3-20020a170903244300b001570540beb6so5012362pls.16 for ; Mon, 11 Apr 2022 14:10:47 -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=5tb57VTUj7RznBKumT5V0V4sQN1PJknWB+EFTfgC840=; b=RMCbNHtoYWPcEkJzuzyfXlxy2zAVP1QniIXjlRQ/38Vf2MAk8bUqhhZQQ1rfRgEkN7 iBFVV//DIZhLtJpSOZXjJ463UdO0OZlGKCrMUGuNiBlxc/9oDmHZoJ5AeLpxVtqcsDEZ QpuapmLzielQA8/GeJdvDYqEO3BUf3yi+4PjGRwolGhc8rGoreBldynhMPodiOanCNPK ioUbvaqNl6AceqrQGv17BhinSlaxCrUMttGzCVQuokjdno0ZOX1AwgSon2157QhmzM/b gHOQWXUaE84GKJI2CKpFBaC2wYJfzlWtofn/faxjtVxMZaE2/HA2+ewIr8M+DoGtFrCH ZtBA== 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=5tb57VTUj7RznBKumT5V0V4sQN1PJknWB+EFTfgC840=; b=RHiByTrkO4+8IkXwWDG5MgbHwcNlyS/jj1ZFYDEJyrTLzDmnpF/9B+vCLCYu+StIrf ssR632f67j5MBZpY9W+s2twzd/msHJ6mKl70JGtrzOCd3HbDShMddvxaHU7M0WMw7ePU N1NaQ/ny5C42SrBNkWfh3tizRiq1NFUYEATVYknfdk+Dv4nU8p78m6yxRMBjOp3mM6JV 8iBvRanoL7WIn66h/qf722ozCVd+w90D1i8YWvm8Cec8m4A7Bfdv2VCeXDyCtEUSPFNB UBrueK7jjhOwCDbi1bB54dXpZHxdn5943WQ2cGNkWKBYBW1FpBFgrcQuAjx9Ox4NDAKu jM5Q== X-Gm-Message-State: AOAM5306lVrMpZQK8LnQ/RQnx//f5xZcRvajRJXXXXWiBSvI9908/oHT veZjEQVu9u1Ifx88Nk4lOoQjCUAX2kYR X-Google-Smtp-Source: ABdhPJxsL6DdyjLp5LTJtC5jEC9w+gspSh7pE1TloQ0jtcg6QxneuVU1IA0CrHD2zbY1tajWnb1t8UWE1G8x X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:902:d5ce:b0:158:48db:9719 with SMTP id g14-20020a170902d5ce00b0015848db9719mr10966080plh.7.1649711447424; Mon, 11 Apr 2022 14:10:47 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:11 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-7-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 06/10] KVM: x86/MMU: Factor out updating NX hugepages state for a VM From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Factor out the code to update the NX hugepages state for an individual VM. This will be expanded in future commits to allow per-VM control of Nx hugepages. No functional change intended. Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- arch/x86/kvm/mmu/mmu.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 69a30d6d1e2b..caaa610b7878 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -6144,6 +6144,15 @@ static void __set_nx_huge_pages(bool val) nx_huge_pages = itlb_multihit_kvm_mitigation = val; } +static void kvm_update_nx_huge_pages(struct kvm *kvm) +{ + mutex_lock(&kvm->slots_lock); + kvm_mmu_zap_all_fast(kvm); + mutex_unlock(&kvm->slots_lock); + + wake_up_process(kvm->arch.nx_lpage_recovery_thread); +} + static int set_nx_huge_pages(const char *val, const struct kernel_param *kp) { bool old_val = nx_huge_pages; @@ -6166,13 +6175,9 @@ static int set_nx_huge_pages(const char *val, const struct kernel_param *kp) mutex_lock(&kvm_lock); - list_for_each_entry(kvm, &vm_list, vm_list) { - mutex_lock(&kvm->slots_lock); - kvm_mmu_zap_all_fast(kvm); - mutex_unlock(&kvm->slots_lock); + list_for_each_entry(kvm, &vm_list, vm_list) + kvm_update_nx_huge_pages(kvm); - wake_up_process(kvm->arch.nx_lpage_recovery_thread); - } mutex_unlock(&kvm_lock); } From patchwork Mon Apr 11 21:10:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809657 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 D45ACC433F5 for ; Mon, 11 Apr 2022 21:11:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350080AbiDKVNP (ORCPT ); Mon, 11 Apr 2022 17:13:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350079AbiDKVNK (ORCPT ); Mon, 11 Apr 2022 17:13:10 -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 10C842AE3E for ; Mon, 11 Apr 2022 14:10:50 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id y15-20020a17090a154f00b001cb4f2196e1so255415pja.3 for ; Mon, 11 Apr 2022 14:10:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=G74YOGd+KW6PfFvdswhoDzYcIuStPXuwuhYirfhXwiM=; b=EYkBSxlkjezsOn0WSYft+MgmzUxZWXclsjEeb8M/F9g+FhFQUQCNX4yPI8d8FBgRmV pRxUsb4RnLzRHBRa9K054kS4ljLd0ltg4jkjSpodRquXfeW1fovrPRPAB4tlvZfvsIx/ t5NgnCB2ihQ2YSphonkw7EGj3j9juXOLQVBuyX5D9fFEaCQQrigWOQRamSSAg/tfQ+eq RwTIHCCFQDWG5J3Ik0hRJ0BxQ05f1IdoxltA0imoc/HUFgxqxairkXSOYoJBU42hTPfC rpHCTFgLIGceYiqQncQjCJX9vcgtaOuzqrIhLe7EkE7Ulroo+PZg1foCPQBl3+RgRLyy iDCA== 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=G74YOGd+KW6PfFvdswhoDzYcIuStPXuwuhYirfhXwiM=; b=2j/SHVrRe2txkjD8+2uHWf3pf5L6muIwL/MA9unwonyU2Sg576N7PVABGBuWCpEbD6 d9bDY/1UNp6JvOhavby0DRm/vhfGkAeHQYzyPSuzS8dSDenkH3jHtsYRx5WEWVKag/X+ uFx3DszDZPcF55e/yx2VFgRzVaUkqbZwiFhTrycALo0bULOJqqaCRYqbquCarpUjJili PwYzQ/u23+z0kvTqtGE0wmtOVLytvpC9IZMK2QSTzNebKDZ9h1LsUsiEnRvxlgrgSBmg 39GDNoX3Kf41Ugt3sjiw4qp+MnI0jplk/DNvZeObdjOudqArOZQ+D+RxEzgAwu/9Q9uR FYyQ== X-Gm-Message-State: AOAM533HV/0TEHVy56B6bybPqFKfiiJvBADscBj6AXix7JrAFVY3xrBB Pe5fS49zYEYkiF+HHyEEd2IdKhFG6GRF X-Google-Smtp-Source: ABdhPJwbnxlqSVC8vvWdQE7kZzWG12dhBh7iFh7S+OO+ZoQ6+KRaSZGgMcswktkOPo+eA2A2fTdo/1M58Umh X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:90a:ba13:b0:1cb:6296:ce41 with SMTP id s19-20020a17090aba1300b001cb6296ce41mr1224016pjr.104.1649711449422; Mon, 11 Apr 2022 14:10:49 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:12 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-8-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 07/10] KVM: x86/MMU: Allow NX huge pages to be disabled on a per-vm basis From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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. Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- Documentation/virt/kvm/api.rst | 11 +++++++++++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/mmu.h | 10 ++++++---- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/mmu/spte.c | 7 ++++--- arch/x86/kvm/mmu/spte.h | 3 ++- arch/x86/kvm/mmu/tdp_mmu.c | 3 ++- arch/x86/kvm/x86.c | 6 ++++++ include/uapi/linux/kvm.h | 1 + 9 files changed, 35 insertions(+), 10 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 72183ae628f7..31fb002632bb 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7855,6 +7855,17 @@ At this time, KVM_PMU_CAP_DISABLE is the only capability. Setting this capability will disable PMU virtualization for that VM. Usermode should adjust CPUID leaf 0xA to reflect that the PMU is disabled. +8.36 KVM_CAP_VM_DISABLE_NX_HUGE_PAGES +--------------------------- + +:Capability KVM_CAP_PMU_CAPABILITY +:Architectures: x86 +:Type: vm + +This capability disables the NX huge pages mitigation for iTLB MULTIHIT. + +The capability has no effect if the nx_huge_pages module parameter is not set. + 9. Known KVM API problems ========================= diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 2c20f715f009..b8ab4fa7d4b2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1240,6 +1240,8 @@ struct kvm_arch { hpa_t hv_root_tdp; spinlock_t hv_root_tdp_lock; #endif + + bool disable_nx_huge_pages; }; struct kvm_vm_stat { diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 671cfeccf04e..20d12e5b0040 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -173,10 +173,12 @@ struct kvm_page_fault { int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault); 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; } +void kvm_update_nx_huge_pages(struct kvm *kvm); static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u32 err, bool prefetch) @@ -191,8 +193,8 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, .user = err & PFERR_USER_MASK, .prefetch = prefetch, .is_tdp = likely(vcpu->arch.mmu->page_fault == kvm_tdp_page_fault), - .nx_huge_page_workaround_enabled = is_nx_huge_page_enabled(), - + .nx_huge_page_workaround_enabled = + is_nx_huge_page_enabled(vcpu->kvm), .max_level = KVM_MAX_HUGEPAGE_LEVEL, .req_level = PG_LEVEL_4K, .goal_level = PG_LEVEL_4K, diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index caaa610b7878..149f353105f4 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -6144,7 +6144,7 @@ static void __set_nx_huge_pages(bool val) nx_huge_pages = itlb_multihit_kvm_mitigation = val; } -static void kvm_update_nx_huge_pages(struct kvm *kvm) +void kvm_update_nx_huge_pages(struct kvm *kvm) { mutex_lock(&kvm->slots_lock); kvm_mmu_zap_all_fast(kvm); diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 4739b53c9734..877ad30bc7ad 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -116,7 +116,7 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, spte |= spte_shadow_accessed_mask(spte); if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && - is_nx_huge_page_enabled()) { + is_nx_huge_page_enabled(vcpu->kvm)) { pte_access &= ~ACC_EXEC_MASK; } @@ -215,7 +215,8 @@ static u64 make_spte_executable(u64 spte) * This is used during huge page splitting to build the SPTEs that make up the * new page table. */ -u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, int index) +u64 make_huge_page_split_spte(struct kvm *kvm, u64 huge_spte, int huge_level, + int index) { u64 child_spte; int child_level; @@ -243,7 +244,7 @@ u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, 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 = make_spte_executable(child_spte); } diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 73f12615416f..e4142caff4b1 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -415,7 +415,8 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *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_level, + int index); u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled); u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access); u64 mark_spte_for_access_track(u64 spte); diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 566548a3efa7..03aa1e0f60e2 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1469,7 +1469,8 @@ static int tdp_mmu_split_huge_page(struct kvm *kvm, struct tdp_iter *iter, * not been linked in yet and thus is not reachable from any other CPU. */ for (i = 0; i < PT64_ENT_PER_PAGE; i++) - sp->spt[i] = make_huge_page_split_spte(huge_spte, level, i); + sp->spt[i] = make_huge_page_split_spte(kvm, huge_spte, + level, i); /* * 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 ab336f7c82e4..b810ea45f965 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, long ext) case KVM_CAP_SYS_ATTRIBUTES: case KVM_CAP_VAPIC: case KVM_CAP_ENABLE_CAP: + case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: r = 1; break; case KVM_CAP_EXIT_HYPERCALL: @@ -6079,6 +6080,11 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, } mutex_unlock(&kvm->lock); break; + case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: + kvm->arch.disable_nx_huge_pages = true; + kvm_update_nx_huge_pages(kvm); + r = 0; + break; default: r = -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index dd1d8167e71f..7155488164bd 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1148,6 +1148,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_PMU_CAPABILITY 212 #define KVM_CAP_DISABLE_QUIRKS2 213 #define KVM_CAP_VM_TSC_CONTROL 214 +#define KVM_CAP_VM_DISABLE_NX_HUGE_PAGES 215 #ifdef KVM_CAP_IRQ_ROUTING From patchwork Mon Apr 11 21:10:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809658 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 EB62AC433F5 for ; Mon, 11 Apr 2022 21:11:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350098AbiDKVN1 (ORCPT ); Mon, 11 Apr 2022 17:13:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350091AbiDKVNL (ORCPT ); Mon, 11 Apr 2022 17:13:11 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4710F2B1B0 for ; Mon, 11 Apr 2022 14:10:52 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2ec06f77db8so43543137b3.8 for ; Mon, 11 Apr 2022 14:10: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=5cDHQ7aYk/4WlSHe8abtE794AVjCSbjoziFcjScQIDg=; b=EHo4PZTgbcB/cGBBAiyRYVsvxPNAoeEZ5fN/cWjy/KeYesKX7nH4FnJDFlKe21/DM5 jLs2RPbnHA8OBCDkdCL05fYvofTYE4j2wO1J6+MhUjdP3HiCHMmgToc+a39Nd5xLiyjD UO4K/gp66K4tEZNuqVFocRHHlJgLTLzZRHg9XBRDQZRU/k5Dw2XRLvr6YHTkAaW6FICH Rda7WzMpBonouqjbqwkXxZkQCF1jJDXTZKqShJJlIn+MMY2fCqkf6yfWN8+kgPySfL2F DrTUYHik/1yNic3JcSos6vItGPm5wvzqodPdf0Qkywemw6rXS0uD4B9eLp/F4O78Kw8A mKWg== 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=5cDHQ7aYk/4WlSHe8abtE794AVjCSbjoziFcjScQIDg=; b=E4ZNJk8eOTBQENDHmEGzwFoPE3jQwvj4Zep9hesHNcOIZhYWyLALuSOqXCmYah9yCP H6s4O0lhYcmbDFwC+UKQc8MqxnTOM5fDKs3ELn5ZU73b4+8hJWY9iS15N5y4+5wPUsw/ k+fLmryy4qbsOSKhj5G3K1KNYtnX+QMTIzY6bmFOIu0jgrYwjLTD1lud/wxSgn2v6NlQ F/pf4BEebfaWiIbZIkNlhzI3GaOEdeRurNLAT7G8G07Pi9bgk/EMsHp65rHCJ02vqfL8 onOGFtqkExHoccef8MfCE75t9m4IYH7bPKIIOYdkwQDE7BBhrGSmrhbL2ND/jJMI1eDg KuqQ== X-Gm-Message-State: AOAM532vOfG0wEmz+cKYaygTubCWrzE1alpvobf8C34iS7FY4kjmbNr5 FLOwhuzHSs16NlDwCcW4+RzPOE2NBp+U X-Google-Smtp-Source: ABdhPJzYux8ibwEUBRsQsI9vPNp1Exnwx/91xo77Pgzf9e9e6BbohC6/2rA2NAZ7cIlMzGKrYQCU6X1a0A5t X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a81:413:0:b0:2ec:31d7:7e60 with SMTP id 19-20020a810413000000b002ec31d77e60mr5057689ywe.62.1649711451242; Mon, 11 Apr 2022 14:10:51 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:13 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-9-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 08/10] KVM: x86: Fix errant brace in KVM capability handling From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 PMU virtualization") 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 b810ea45f965..de1d211f8aa3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4383,10 +4383,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) if (r < sizeof(struct kvm_xsave)) r = sizeof(struct kvm_xsave); break; + } case KVM_CAP_PMU_CAPABILITY: r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0; break; - } case KVM_CAP_DISABLE_QUIRKS2: r = KVM_X86_VALID_QUIRKS; break; From patchwork Mon Apr 11 21:10:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809660 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 954A9C433F5 for ; Mon, 11 Apr 2022 21:11:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350086AbiDKVNg (ORCPT ); Mon, 11 Apr 2022 17:13:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350069AbiDKVNM (ORCPT ); Mon, 11 Apr 2022 17:13:12 -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 8781819C14 for ; Mon, 11 Apr 2022 14:10:53 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id i2-20020a170902c94200b001586d3264c9so1415273pla.1 for ; Mon, 11 Apr 2022 14:10:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dXlFBD0LldYOfRc7OaKD0wMXPzi3maZCvF8rPD26eTI=; b=od645DgDIiqdxXTXIqTecH/cdEHvdo6xF2qu5T02FMQ19MQNLm9xVN/ZO9o0v93qEW 6kpH4zKRGD2sT+LExaIzj5l4Hp7CRMRF8bLpq6s5ihDNFvAbSv4zOT9ywEHYI53vyLTR jCz9NWc9KdYyem5akZTphuk/sjQ6Tde/iYyfxkuxBjXqop1zMCiSZo7KfPuJm6MACxQU oglTlvRr2XBhY42HCju5FgQRrDnZAsCB7vq3ca9jbt2wTTIBNWEM6zvV3lTVHmQOJ7Dy uYZ4A4QY+6CqedZGz+Q5ng6Q9du0pBMjStji3X/hcVlUKbT3KfYkLQUsCvdH/R4Ku66X 4gnQ== 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=dXlFBD0LldYOfRc7OaKD0wMXPzi3maZCvF8rPD26eTI=; b=hfmu5yNvpLYvPrHLXrMpRsn6vkE+n+IjrkeMAY4LCz29gg//1Nw96Dx4mJ0wezRq36 s2W1sfMD1ruzT7c6umNNL2dtHNrhd8G0mdTCwv30/y5PitkV1qsJWdAvESK4lH4z8UVm hvfNN0RQUeadVPtiHqDGoFU30YlZjCpGAqVEcr56zz1PQjteW0ZPi9KnpZE5+d0z4QjR 0EWBoQUTThp3bilH2JvXosvrgbPtvc8eNpo5yNXJcYyi/sk0X9/GwkiIyKJaHrduhOu/ txP2kRPBpoiC5cj/1183mZ/G2NoQaaCYuJiKNbidXHlF14/dTSIAj46DpaF+twXZJgMN n9rA== X-Gm-Message-State: AOAM530PWeOEB3rjq3szVAGALv57Bxc7Jh0WAq1d1eJkzZiQBYD+P41H jrXpp6W0h+EJqixcnnj0+ijbap6cZdFJ X-Google-Smtp-Source: ABdhPJxRBDuMX+1iIQMZOMQEGWUuODV9pdUUYDXB5DzdeWHVI/JBHhK3LPtoD+bM0n1KR1cloYlAQTXVNNqc X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:90b:1c87:b0:1ca:f4e:4fbe with SMTP id oo7-20020a17090b1c8700b001ca0f4e4fbemr1168462pjb.159.1649711452989; Mon, 11 Apr 2022 14:10:52 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:14 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-10-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 09/10] KVM: x86/MMU: Require reboot permission to disable NX hugepages From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Ensure that the userspace actor attempting to disable NX hugepages has permission to reboot the system. Since disabling NX hugepages would allow a guest to crash the system, it is similar to reboot permissions. This approach is the simplest permission gating, but passing a file descriptor opened for write for the module parameter would also work well and be more precise. The latter approach was suggested by Sean Christopherson. Suggested-by: Jim Mattson Signed-off-by: Ben Gardon --- Documentation/virt/kvm/api.rst | 2 ++ arch/x86/kvm/x86.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 31fb002632bb..021452a9fa91 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7861,6 +7861,8 @@ should adjust CPUID leaf 0xA to reflect that the PMU is disabled. :Capability KVM_CAP_PMU_CAPABILITY :Architectures: x86 :Type: vm +:Returns 0 on success, -EPERM if the userspace process does not + have CAP_SYS_BOOT This capability disables the NX huge pages mitigation for iTLB MULTIHIT. diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index de1d211f8aa3..8d3d6c48c5ec 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6081,6 +6081,15 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, mutex_unlock(&kvm->lock); break; case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: + /* + * Since the risk of disabling NX hugepages is a guest crashing + * the system, ensure the userspace process has permission to + * reboot the system. + */ + if (!capable(CAP_SYS_BOOT)) { + r = -EPERM; + break; + } kvm->arch.disable_nx_huge_pages = true; kvm_update_nx_huge_pages(kvm); r = 0; From patchwork Mon Apr 11 21:10:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 12809659 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 19662C433F5 for ; Mon, 11 Apr 2022 21:11:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350184AbiDKVN3 (ORCPT ); Mon, 11 Apr 2022 17:13:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350079AbiDKVNQ (ORCPT ); Mon, 11 Apr 2022 17:13:16 -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 8B4B52B194 for ; Mon, 11 Apr 2022 14:10:55 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id u10-20020a17090adb4a00b001cb7b5a79e8so253446pjx.5 for ; Mon, 11 Apr 2022 14:10: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=xIMnek+At8iLPkwADBkZ7XrRr/vdRBqsK9zci+WHfIA=; b=C4dFQ0ocxToI8CY7sDWjXFzHFgdTdFWswyceRjb37yOLdjfoDBtbtvTmi5cGq1VEad 7w8VZnkp/JJLp1koNV5oGegMEnys1FuotSD/VT2E99+gGSCbtJHDbEHlaIItSlSUO+tb eviNS42ugJl3zF5thORrX6+krLI00hAQmWFDh59sequdz26pxJLmn5eHdd2XQ8fEEaX1 GQK8xmTzvsluF8s4Zp/5sBH4besgH876R3NeNfZ7AHjIfn/OfaxNPDHjyeNmoIJo+rXM h58xMxL76jasLP7j1ajCTOzysJml3k8TgVcV+noGb9bO3iSj+K1onUAcK60/t9nG3NuV 9XPA== 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=xIMnek+At8iLPkwADBkZ7XrRr/vdRBqsK9zci+WHfIA=; b=Fm2wy7lIDfWNLQ8JHogQ6lpvvSnvSSdJylFUZqcNxn+Zrnf4rVzjZV00xfQwlSbNqK RFFSQqoAVwGNpVU9fNTRNUDoKowc4sF6OtFcklLB7j5/RvCqylE/xnwAlc3XU24YWW9R a7TV6awUV6MG0xkKbjllgWqVT33JIqH6xAe1M4DnhBxfrRl9LMz5QUt1x82hSXiFsd2h NqxEjYE6wUWd+mNR10LLolFY2gC1b74qkXV2s8o/I+zSlbXT/6f9lJQTW4SVeN7xRPcP O4Z66k/1vfXZTQmUIwFpP9Ech9mgbt/vrJgqKHuSxALvZGF0dQXTW03Oprv/NYm/NGeC MI1Q== X-Gm-Message-State: AOAM5335+7FRftIDiK4g+sE+QUFabB2h6BzoGyvQ4KVhOAm47ACto4Pj y2yWfnNsAKhj6LRtB8pSssjA/0fbUm9/ X-Google-Smtp-Source: ABdhPJy2WkMcnAC3gL8ghKY5MA9VSdRNJhjdAS3w/erZboLxL3Zrns0cwsriLs/zATnsIQVyFpAaL6sUNN0D X-Received: from bgardon.sea.corp.google.com ([2620:15c:100:202:a2d0:faec:7d8b:2e0b]) (user=bgardon job=sendgmr) by 2002:a17:902:728f:b0:156:24d3:ae1a with SMTP id d15-20020a170902728f00b0015624d3ae1amr34419549pll.9.1649711454954; Mon, 11 Apr 2022 14:10:54 -0700 (PDT) Date: Mon, 11 Apr 2022 14:10:15 -0700 In-Reply-To: <20220411211015.3091615-1-bgardon@google.com> Message-Id: <20220411211015.3091615-11-bgardon@google.com> Mime-Version: 1.0 References: <20220411211015.3091615-1-bgardon@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH v4 10/10] KVM: selftests: Test disabling NX hugepages on a VM From: Ben Gardon To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Peter Xu , Sean Christopherson , Peter Shier , David Dunn , Junaid Shahid , Jim Mattson , David Matlack , Mingwei Zhang , Jing Zhang , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add an argument to the NX huge pages test to test disabling the feature on a VM using the new capability. Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 19 ++++++- .../selftests/kvm/x86_64/nx_huge_pages_test.c | 53 +++++++++++++++---- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index f9c2ac0a5b97..15f24be6d93f 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -412,4 +412,6 @@ uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name); uint32_t guest_get_vcpuid(void); +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/selftests/kvm/lib/kvm_util.c index 833c7e63d62d..5fa5608eef03 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -112,6 +112,15 @@ int vm_check_cap(struct kvm_vm *vm, long cap) return ret; } +static int __vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap) +{ + int ret; + + ret = ioctl(vm->fd, KVM_ENABLE_CAP, cap); + + return ret; +} + /* VM Enable Capability * * Input Args: @@ -128,7 +137,7 @@ int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap) { int ret; - ret = ioctl(vm->fd, KVM_ENABLE_CAP, cap); + ret = __vm_enable_cap(vm, cap); TEST_ASSERT(ret == 0, "KVM_ENABLE_CAP IOCTL failed,\n" " rc: %i errno: %i", ret, errno); @@ -2662,3 +2671,11 @@ uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name) stat_name, ret); return data; } + +int vm_disable_nx_huge_pages(struct kvm_vm *vm) +{ + struct kvm_enable_cap cap = { 0 }; + + cap.cap = KVM_CAP_VM_DISABLE_NX_HUGE_PAGES; + return __vm_enable_cap(vm, &cap); +} diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c index 3f21726b22c7..f8edf7910950 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 #include #include "kvm_util.h" @@ -77,14 +79,41 @@ static void check_split_count(struct kvm_vm *vm, int expected_splits) expected_splits, actual_splits); } -int main(int argc, char **argv) +void run_test(bool disable_nx) { struct kvm_vm *vm; struct timespec ts; void *hva; + int r; vm = vm_create_default(0, 0, guest_code); + if (disable_nx) { + kvm_check_cap(KVM_CAP_VM_DISABLE_NX_HUGE_PAGES); + + /* + * Check if this process has the reboot permissions needed to + * disable NX huge pages on a VM. + * + * The reboot call below will never have any effect because + * the magic values are not set correctly, however the + * permission check is done before the magic value check. + */ + r = syscall(SYS_reboot, 0, 0, 0, NULL); + if (errno == EPERM) { + r = vm_disable_nx_huge_pages(vm); + TEST_ASSERT(r == EPERM, + "This process should not have permission to disable NX huge pages"); + return; + } + + TEST_ASSERT(errno == EINVAL, + "Reboot syscall should fail with -EINVAL"); + + r = vm_disable_nx_huge_pages(vm); + TEST_ASSERT(!r, "Disabling NX huge pages should not fail if process has reboot permissions"); + } + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, HPAGE_GPA, HPAGE_SLOT, HPAGE_SLOT_NPAGES, 0); @@ -118,21 +147,21 @@ int main(int argc, char **argv) * to be remapped at 4k. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 1); + check_2m_page_count(vm, disable_nx ? 2 : 1); + check_split_count(vm, disable_nx ? 0 : 1); /* * Executing from the third huge page (previously unaccessed) will * cause part to be mapped at 4k. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 1); + check_split_count(vm, disable_nx ? 0 : 2); /* Reading from the first huge page again should have no effect. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 1); + check_split_count(vm, disable_nx ? 0 : 2); /* * Give recovery thread time to run. The wrapper script sets @@ -145,7 +174,7 @@ int main(int argc, char **argv) /* * Now that the reclaimer has run, all the split pages should be gone. */ - check_2m_page_count(vm, 1); + check_2m_page_count(vm, disable_nx ? 3 : 1); check_split_count(vm, 0); /* @@ -153,10 +182,16 @@ int main(int argc, char **argv) * reading from it causes a huge page mapping to be installed. */ vcpu_run(vm, 0); - check_2m_page_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 3 : 2); check_split_count(vm, 0); kvm_vm_free(vm); +} + +int main(int argc, char **argv) +{ + run_test(false); + run_test(true); return 0; }