From nobody Thu Apr 9 00:18:11 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 3263AECAAA1 for ; Mon, 31 Oct 2022 17:38:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230168AbiJaRia (ORCPT ); Mon, 31 Oct 2022 13:38:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229980AbiJaRiZ (ORCPT ); Mon, 31 Oct 2022 13:38:25 -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 CAAB7DF25 for ; Mon, 31 Oct 2022 10:38:24 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id 125-20020a630283000000b0046e9babe7b3so6460860pgc.11 for ; Mon, 31 Oct 2022 10:38:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7Jpq5jfGphmK9drIKQAVv+M/tTwLOmGvjLrn0VHckf8=; b=YPLI9uJ3gSAKoLonts19Zv0B3kfm5cmzTD+PCI18Cp7fF5belHNpwoGaTT6nXkHdnK d/tu7JUiJeqq3rpVel3sasfOjdiLHnp7dUeyP3NTsEPAnPOSrpvbfxPYRbRk4opBZzKk io8XUAK8Cyglj2sXdKPXkG+yQVH5kmeWwO8mxtsrOssf+jejlgb2L9srXRBlqbg+0MtV F9U/lQAqTm2AkgkYBvp0Nqg4Exsu+LltlQ7iLoe0+JEbRwDxh/TFotkO26MetrL7BCa+ NNEfZ52iYcSgBi982Ewr3NnnA6Zjsc3ZxXrs8sciImoVivkngaa1PvPMcHszVdAn9YiZ rq0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7Jpq5jfGphmK9drIKQAVv+M/tTwLOmGvjLrn0VHckf8=; b=Xeoy0aF4WrZ89bw6XO9jrF97tO/h/BkZ9KwQgAji96E3qX6VKvmi9/kjwaZVV4aT4r LCyhXpX3YBUUHrE3UiDDyK/GANVnAlT4FHCv4vzGg2pDSIZFBQsxv3vE9oSU5EoP4J8f Ap0LAmr01SB75B5qCfyg8fRA070fOpaa6M5tM+25IgA/dThoBPjL141Q51tZa7Php60p FgraqOhiRWT165Vsbjr7BhQH8ppcu366nvU9Avn1s0wkhJPTTWUblWRzGawtcR9OFsbj RhuCji7LP206HJGrW94AEv4MMySGuo7jMqWYsV/4R9KjKMFjhduAQcpxyNPVRiTmF3yS 2eWg== X-Gm-Message-State: ACrzQf3E9IUozWnVCGNvA+XVSdMFNJDdXKYCoepk3gK2sjA4Fp37iYQP p4tnA/AgUABk/cd6p6QPGCoqeLITwHom X-Google-Smtp-Source: AMsMyM4Cbtpv/FdUZxJeoD0+/Fl4R4E6qozoguIxnFXwKgT5BcRUM5AsVWymzrMoFALv4gJow+kv3fT5hT7X X-Received: from vipin.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:479f]) (user=vipinsh job=sendgmr) by 2002:a17:902:ce0f:b0:187:640:42f with SMTP id k15-20020a170902ce0f00b001870640042fmr14060846plg.115.1667237904395; Mon, 31 Oct 2022 10:38:24 -0700 (PDT) Date: Mon, 31 Oct 2022 10:38:15 -0700 In-Reply-To: <20221031173819.1035684-1-vipinsh@google.com> Mime-Version: 1.0 References: <20221031173819.1035684-1-vipinsh@google.com> X-Mailer: git-send-email 2.38.1.273.g43a17bfeac-goog Message-ID: <20221031173819.1035684-2-vipinsh@google.com> Subject: [PATCH v7 1/5] KVM: selftests: Add missing break between -e and -g option in dirty_log_perf_test From: Vipin Sharma To: seanjc@google.com, pbonzini@redhat.com, dmatlack@google.com Cc: andrew.jones@linux.dev, wei.w.wang@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vipin Sharma Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Passing -e option (Run VCPUs while dirty logging is being disabled) in dirty_log_perf_test also unintentionally enables -g (Do not enable KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2). Add break between two switch case logic. Fixes: cfe12e64b065 ("KVM: selftests: Add an option to run vCPUs while disa= bling dirty logging") Signed-off-by: Vipin Sharma Reviewed-by: Sean Christopherson --- tools/testing/selftests/kvm/dirty_log_perf_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index f99e39a672d3..56e08da3a87f 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -411,6 +411,7 @@ int main(int argc, char *argv[]) case 'e': /* 'e' is for evil. */ run_vcpus_while_disabling_dirty_logging =3D true; + break; case 'g': dirty_log_manual_caps =3D 0; break; --=20 2.38.1.273.g43a17bfeac-goog From nobody Thu Apr 9 00:18:11 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 8B8A1ECAAA1 for ; Mon, 31 Oct 2022 17:38:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230423AbiJaRie (ORCPT ); Mon, 31 Oct 2022 13:38:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230155AbiJaRi1 (ORCPT ); Mon, 31 Oct 2022 13:38:27 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B544BDFBA for ; Mon, 31 Oct 2022 10:38:26 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id j21-20020a17090a7e9500b00212b3905d87so4611484pjl.9 for ; Mon, 31 Oct 2022 10:38:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Kq/eZnm8KvVNCuvFzuVFxcpb13DgkgGwUFDn8WRVQDY=; b=HEdUgImzn+VEbHPYvaZ0HgFbjDJGIk8wIHqGS/9PCWMgap01r2wCipJs5dGPYKLvfb bkINgkook0xzMYJKEm9F2vj2f7pklzdOOKvDYW8ZHuWm3Y82nbkyOFOQOBGiTKi5QMDz TZnrHhMRvXzvy8MzZbtvqfQeiTjqkK+C+XAXmw+cbKeZ64itLxAZTmHyDLKx/XcwIuUt WQOzEAqVx+C0y47gHA0fRuB5oC3Qfv/sw3GLOqZcUhH575/H+Mft29y8fmkepsZi0FiU aEpPAxvOG/8Bw+fRfi/7TIc9ytUU2zCOFqj2Ci/teIxuO68UFNhFUYEBOL5HU4j02Eqo nakw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Kq/eZnm8KvVNCuvFzuVFxcpb13DgkgGwUFDn8WRVQDY=; b=UVMnHhDuiIN7w/VN2MlhVoF5imVg2Q5JZhJwjrXvsh+FB3thSIGsizV02Mftv64ay8 eFfYjxOHR68O51K1xYKc8/yCp4ViUc9J0aLEx5fVv5hYbzG8qVIu/ureGJlQOBRSNR6x 6w8f+DkjwGx0bdS9pZ18TAGh0MHB4WxHkK0SIx3rXneDHJd0Xud1lZq1dzr3hep7XAjT 8C2pR2sFTW2DXwbBocu85m7ACmXx4lX+bKAY88ZLgCROWyHJP2S7rWCvycRd0zgaMLQe 24SvkZtENP+2sIev+gjXZmcc+P8VZ0V7MYemddTlOcaE6Jt8M32HDd8X/Ief97KWFQMV sD9Q== X-Gm-Message-State: ACrzQf21JCDC2VnHc7wjNZvAkuRp6fgJd6ogb1WFOh1AnZR4rA8RBISL ankzP0Q9wSj12Cfz70ZHlnl7aTwd8yBF X-Google-Smtp-Source: AMsMyM4NICw/E/s0gzfYXMP8cAx4ACX5PLCeF4HuM5mwP9I2cALnY0dhiK/XTkvvJ6lzxx5AtEaNXWS+228h X-Received: from vipin.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:479f]) (user=vipinsh job=sendgmr) by 2002:a17:902:ee52:b0:186:a808:5374 with SMTP id 18-20020a170902ee5200b00186a8085374mr15157892plo.158.1667237906326; Mon, 31 Oct 2022 10:38:26 -0700 (PDT) Date: Mon, 31 Oct 2022 10:38:16 -0700 In-Reply-To: <20221031173819.1035684-1-vipinsh@google.com> Mime-Version: 1.0 References: <20221031173819.1035684-1-vipinsh@google.com> X-Mailer: git-send-email 2.38.1.273.g43a17bfeac-goog Message-ID: <20221031173819.1035684-3-vipinsh@google.com> Subject: [PATCH v7 2/5] KVM: selftests: Put command line options in alphabetical order in dirty_log_perf_test From: Vipin Sharma To: seanjc@google.com, pbonzini@redhat.com, dmatlack@google.com Cc: andrew.jones@linux.dev, wei.w.wang@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vipin Sharma Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There are 13 command line options and they are not in any order. Put them in alphabetical order to make it easy to add new options. No functional change intended. Signed-off-by: Vipin Sharma Reviewed-by: Wei Wang Reviewed-by: Sean Christopherson --- .../selftests/kvm/dirty_log_perf_test.c | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index 56e08da3a87f..5bb6954b2358 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -406,50 +406,52 @@ int main(int argc, char *argv[]) =20 guest_modes_append_default(); =20 - while ((opt =3D getopt(argc, argv, "eghi:p:m:nb:f:v:os:x:")) !=3D -1) { + while ((opt =3D getopt(argc, argv, "b:ef:ghi:m:nop:s:v:x:")) !=3D -1) { switch (opt) { + case 'b': + guest_percpu_mem_size =3D parse_size(optarg); + break; case 'e': /* 'e' is for evil. */ run_vcpus_while_disabling_dirty_logging =3D true; break; + case 'f': + p.wr_fract =3D atoi(optarg); + TEST_ASSERT(p.wr_fract >=3D 1, + "Write fraction cannot be less than one"); + break; case 'g': dirty_log_manual_caps =3D 0; break; + case 'h': + help(argv[0]); + break; case 'i': p.iterations =3D atoi(optarg); break; - case 'p': - p.phys_offset =3D strtoull(optarg, NULL, 0); - break; case 'm': guest_modes_cmdline(optarg); break; case 'n': perf_test_args.nested =3D true; break; - case 'b': - guest_percpu_mem_size =3D parse_size(optarg); + case 'o': + p.partition_vcpu_memory_access =3D false; break; - case 'f': - p.wr_fract =3D atoi(optarg); - TEST_ASSERT(p.wr_fract >=3D 1, - "Write fraction cannot be less than one"); + case 'p': + p.phys_offset =3D strtoull(optarg, NULL, 0); + break; + case 's': + p.backing_src =3D parse_backing_src_type(optarg); break; case 'v': nr_vcpus =3D atoi(optarg); TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; - case 'o': - p.partition_vcpu_memory_access =3D false; - break; - case 's': - p.backing_src =3D parse_backing_src_type(optarg); - break; case 'x': p.slots =3D atoi(optarg); break; - case 'h': default: help(argv[0]); break; --=20 2.38.1.273.g43a17bfeac-goog From nobody Thu Apr 9 00:18:11 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 DA72CECAAA1 for ; Mon, 31 Oct 2022 17:38:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230464AbiJaRii (ORCPT ); Mon, 31 Oct 2022 13:38:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230243AbiJaRi3 (ORCPT ); Mon, 31 Oct 2022 13:38:29 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBCC112D25 for ; Mon, 31 Oct 2022 10:38:28 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id q3-20020a17090311c300b0017898180dddso8544276plh.0 for ; Mon, 31 Oct 2022 10:38:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=tYjAh+WLLLfx8WDyu6rbI20cNUIbYZU4JH1uDqtZgIw=; b=TNvG2uWgDipNP/Z+7ShEA3vq71DmnldvKTB+RZdHYw7SzVECvimBLvC32QDFVD8yKX XFGLZ70mKQo1odPTnvLtQmekMSlqqJCvvYFm99VwyqZr7haGy8RYfyiWHoQVtK96B2EZ +kCRbx2H1Oi9MxhPtyjBDqWQ6DsJ7tIJGYcq2D2FhzCDWOkxS5LOsrLXBaoh4f7YWm+p iQQfPhZ5rvpq94Qa0EfGKvXYrO57t048hkIxknY8zLlNadaR+C63t7SJCBG3RrhQA1M9 8VAlMKfDg84nNdclXU/RgfFskYrf4hs/hzQg7izj+eQlIyM3lNIUtO/jKyH5FyZdJ9hV FM7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tYjAh+WLLLfx8WDyu6rbI20cNUIbYZU4JH1uDqtZgIw=; b=BR8IJbABOtJDN0vSM+K2yMZEr6/7f9jbyd6/IZAWUf3s4efPXtLh3MIw3bIft+i3zC v2axkzh+A6vROKa9KFz6CnX5gvz4yyAXpo2AjAjD+nIcfs26kOWyP4WGeraqcdXopWMu oqIvdR5F+paa06tpboARhFzeXnF5PJNasWzno3GXT+Z+YOuIlIwLeEqaC/md3YwSYCNy VUud0vNg3/rEeU38vyj6HufsXVCT65BYPFNg04JdGK1Rs4z84Q4rJn6mqoxbh7QP6DIL h+xF1wSUgHRhLqFj4MgRKaydBapqrTye1mKMjmsmCx8AgBXTd9rP8IIJ0TsYn50pxWVP g9cQ== X-Gm-Message-State: ACrzQf1zUVn/7iTj7tXirqevXmIneO0ZpkmqspA+sev+0LzvuA/A10pH EHJ/L+UjYOS1Sa+zkS+4KnAeTvOF5twn X-Google-Smtp-Source: AMsMyM72Udc7yXXreXVeyMOaYpgUiRcimjEQ1SLCm8rsjWWLOW3dCXLxHGocA52A01mk/6c+v38PXttfFdLX X-Received: from vipin.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:479f]) (user=vipinsh job=sendgmr) by 2002:a05:6a00:2294:b0:56d:7387:8a06 with SMTP id f20-20020a056a00229400b0056d73878a06mr6759185pfe.17.1667237908335; Mon, 31 Oct 2022 10:38:28 -0700 (PDT) Date: Mon, 31 Oct 2022 10:38:17 -0700 In-Reply-To: <20221031173819.1035684-1-vipinsh@google.com> Mime-Version: 1.0 References: <20221031173819.1035684-1-vipinsh@google.com> X-Mailer: git-send-email 2.38.1.273.g43a17bfeac-goog Message-ID: <20221031173819.1035684-4-vipinsh@google.com> Subject: [PATCH v7 3/5] KVM: selftests: Add atoi_paranoid() to catch errors missed by atoi() From: Vipin Sharma To: seanjc@google.com, pbonzini@redhat.com, dmatlack@google.com Cc: andrew.jones@linux.dev, wei.w.wang@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vipin Sharma Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" atoi() doesn't detect errors. There is no way to know that a 0 return is correct conversion or due to an error. Introduce atoi_paranoid() to detect errors and provide correct conversion. Replace all atoi() calls with atoi_paranoid(). Signed-off-by: Vipin Sharma Suggested-by: David Matlack Suggested-by: Sean Christopherson Reviewed-by: Sean Christopherson --- .../selftests/kvm/aarch64/arch_timer.c | 8 ++++---- .../selftests/kvm/aarch64/debug-exceptions.c | 2 +- .../testing/selftests/kvm/aarch64/vgic_irq.c | 6 +++--- .../selftests/kvm/access_tracking_perf_test.c | 2 +- .../selftests/kvm/demand_paging_test.c | 2 +- .../selftests/kvm/dirty_log_perf_test.c | 8 ++++---- .../testing/selftests/kvm/include/test_util.h | 2 ++ .../selftests/kvm/kvm_page_table_test.c | 2 +- tools/testing/selftests/kvm/lib/test_util.c | 19 +++++++++++++++++++ .../selftests/kvm/max_guest_memory_test.c | 6 +++--- .../kvm/memslot_modification_stress_test.c | 4 ++-- .../testing/selftests/kvm/memslot_perf_test.c | 10 +++++----- .../selftests/kvm/set_memory_region_test.c | 2 +- .../selftests/kvm/x86_64/nx_huge_pages_test.c | 4 ++-- 14 files changed, 49 insertions(+), 28 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testi= ng/selftests/kvm/aarch64/arch_timer.c index 574eb73f0e90..251e7ff04883 100644 --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c @@ -414,7 +414,7 @@ static bool parse_args(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "hn:i:p:m:")) !=3D -1) { switch (opt) { case 'n': - test_args.nr_vcpus =3D atoi(optarg); + test_args.nr_vcpus =3D atoi_paranoid(optarg); if (test_args.nr_vcpus <=3D 0) { pr_info("Positive value needed for -n\n"); goto err; @@ -425,21 +425,21 @@ static bool parse_args(int argc, char *argv[]) } break; case 'i': - test_args.nr_iter =3D atoi(optarg); + test_args.nr_iter =3D atoi_paranoid(optarg); if (test_args.nr_iter <=3D 0) { pr_info("Positive value needed for -i\n"); goto err; } break; case 'p': - test_args.timer_period_ms =3D atoi(optarg); + test_args.timer_period_ms =3D atoi_paranoid(optarg); if (test_args.timer_period_ms <=3D 0) { pr_info("Positive value needed for -p\n"); goto err; } break; case 'm': - test_args.migration_freq_ms =3D atoi(optarg); + test_args.migration_freq_ms =3D atoi_paranoid(optarg); if (test_args.migration_freq_ms < 0) { pr_info("0 or positive value needed for -m\n"); goto err; diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools= /testing/selftests/kvm/aarch64/debug-exceptions.c index 947bd201435c..19fffdf19c9f 100644 --- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c @@ -423,7 +423,7 @@ int main(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "i:")) !=3D -1) { switch (opt) { case 'i': - ss_iteration =3D atoi(optarg); + ss_iteration =3D atoi_paranoid(optarg); break; case 'h': default: diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing= /selftests/kvm/aarch64/vgic_irq.c index 17417220a083..ae90b718070a 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -824,16 +824,16 @@ int main(int argc, char **argv) while ((opt =3D getopt(argc, argv, "hn:e:l:")) !=3D -1) { switch (opt) { case 'n': - nr_irqs =3D atoi(optarg); + nr_irqs =3D atoi_paranoid(optarg); if (nr_irqs > 1024 || nr_irqs % 32) help(argv[0]); break; case 'e': - eoi_split =3D (bool)atoi(optarg); + eoi_split =3D (bool)atoi_paranoid(optarg); default_args =3D false; break; case 'l': - level_sensitive =3D (bool)atoi(optarg); + level_sensitive =3D (bool)atoi_paranoid(optarg); default_args =3D false; break; case 'h': diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tool= s/testing/selftests/kvm/access_tracking_perf_test.c index 76c583a07ea2..c6bcc5301e2c 100644 --- a/tools/testing/selftests/kvm/access_tracking_perf_test.c +++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) params.vcpu_memory_bytes =3D parse_size(optarg); break; case 'v': - params.nr_vcpus =3D atoi(optarg); + params.nr_vcpus =3D atoi_paranoid(optarg); break; case 'o': overlap_memory_access =3D true; diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testi= ng/selftests/kvm/demand_paging_test.c index 779ae54f89c4..82597fb04146 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -427,7 +427,7 @@ int main(int argc, char *argv[]) p.src_type =3D parse_backing_src_type(optarg); break; case 'v': - nr_vcpus =3D atoi(optarg); + nr_vcpus =3D atoi_paranoid(optarg); TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index 5bb6954b2358..ecda802b78ff 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -416,7 +416,7 @@ int main(int argc, char *argv[]) run_vcpus_while_disabling_dirty_logging =3D true; break; case 'f': - p.wr_fract =3D atoi(optarg); + p.wr_fract =3D atoi_paranoid(optarg); TEST_ASSERT(p.wr_fract >=3D 1, "Write fraction cannot be less than one"); break; @@ -427,7 +427,7 @@ int main(int argc, char *argv[]) help(argv[0]); break; case 'i': - p.iterations =3D atoi(optarg); + p.iterations =3D atoi_paranoid(optarg); break; case 'm': guest_modes_cmdline(optarg); @@ -445,12 +445,12 @@ int main(int argc, char *argv[]) p.backing_src =3D parse_backing_src_type(optarg); break; case 'v': - nr_vcpus =3D atoi(optarg); + nr_vcpus =3D atoi_paranoid(optarg); TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; case 'x': - p.slots =3D atoi(optarg); + p.slots =3D atoi_paranoid(optarg); break; default: help(argv[0]); diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testin= g/selftests/kvm/include/test_util.h index befc754ce9b3..feae42863759 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -152,4 +152,6 @@ static inline void *align_ptr_up(void *x, size_t size) return (void *)align_up((unsigned long)x, size); } =20 +int atoi_paranoid(const char *num_str); + #endif /* SELFTEST_KVM_TEST_UTIL_H */ diff --git a/tools/testing/selftests/kvm/kvm_page_table_test.c b/tools/test= ing/selftests/kvm/kvm_page_table_test.c index f42c6ac6d71d..ea7feb69bb88 100644 --- a/tools/testing/selftests/kvm/kvm_page_table_test.c +++ b/tools/testing/selftests/kvm/kvm_page_table_test.c @@ -461,7 +461,7 @@ int main(int argc, char *argv[]) p.test_mem_size =3D parse_size(optarg); break; case 'v': - nr_vcpus =3D atoi(optarg); + nr_vcpus =3D atoi_paranoid(optarg); TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/se= lftests/kvm/lib/test_util.c index 6d23878bbfe1..ec0f070a6f21 100644 --- a/tools/testing/selftests/kvm/lib/test_util.c +++ b/tools/testing/selftests/kvm/lib/test_util.c @@ -334,3 +334,22 @@ long get_run_delay(void) =20 return val[1]; } + +int atoi_paranoid(const char *num_str) +{ + char *end_ptr; + long num; + + errno =3D 0; + num =3D strtol(num_str, &end_ptr, 10); + TEST_ASSERT(!errno, "strtol(\"%s\") failed", num_str); + TEST_ASSERT(num_str !=3D end_ptr, + "strtol(\"%s\") didn't find a valid integer.\n", num_str); + TEST_ASSERT(*end_ptr =3D=3D '\0', + "strtol(\"%s\") failed to parse trailing characters \"%s\".\n", + num_str, end_ptr); + TEST_ASSERT(num >=3D INT_MIN && num <=3D INT_MAX, + "%ld not in range of [%d, %d]", num, INT_MIN, INT_MAX); + + return num; +} diff --git a/tools/testing/selftests/kvm/max_guest_memory_test.c b/tools/te= sting/selftests/kvm/max_guest_memory_test.c index 9a6e4f3ad6b5..1595b73dc09a 100644 --- a/tools/testing/selftests/kvm/max_guest_memory_test.c +++ b/tools/testing/selftests/kvm/max_guest_memory_test.c @@ -193,15 +193,15 @@ int main(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "c:h:m:s:H")) !=3D -1) { switch (opt) { case 'c': - nr_vcpus =3D atoi(optarg); + nr_vcpus =3D atoi_paranoid(optarg); TEST_ASSERT(nr_vcpus > 0, "number of vcpus must be >0"); break; case 'm': - max_mem =3D atoi(optarg) * size_1gb; + max_mem =3D atoi_paranoid(optarg) * size_1gb; TEST_ASSERT(max_mem > 0, "memory size must be >0"); break; case 's': - slot_size =3D atoi(optarg) * size_1gb; + slot_size =3D atoi_paranoid(optarg) * size_1gb; TEST_ASSERT(slot_size > 0, "slot size must be >0"); break; case 'H': diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c= b/tools/testing/selftests/kvm/memslot_modification_stress_test.c index 6ee7e1dde404..865276993ffb 100644 --- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c +++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) guest_percpu_mem_size =3D parse_size(optarg); break; case 'v': - nr_vcpus =3D atoi(optarg); + nr_vcpus =3D atoi_paranoid(optarg); TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) p.partition_vcpu_memory_access =3D false; break; case 'i': - p.nr_memslot_modifications =3D atoi(optarg); + p.nr_memslot_modifications =3D atoi_paranoid(optarg); break; case 'h': default: diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testin= g/selftests/kvm/memslot_perf_test.c index 44995446d942..4bae9e3f5ca1 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -885,21 +885,21 @@ static bool parse_args(int argc, char *argv[], map_unmap_verify =3D true; break; case 's': - targs->nslots =3D atoi(optarg); + targs->nslots =3D atoi_paranoid(optarg); if (targs->nslots <=3D 0 && targs->nslots !=3D -1) { pr_info("Slot count cap has to be positive or -1 for no cap\n"); return false; } break; case 'f': - targs->tfirst =3D atoi(optarg); + targs->tfirst =3D atoi_paranoid(optarg); if (targs->tfirst < 0) { pr_info("First test to run has to be non-negative\n"); return false; } break; case 'e': - targs->tlast =3D atoi(optarg); + targs->tlast =3D atoi_paranoid(optarg); if (targs->tlast < 0 || targs->tlast >=3D NTESTS) { pr_info("Last test to run has to be non-negative and less than %zu\n", NTESTS); @@ -907,14 +907,14 @@ static bool parse_args(int argc, char *argv[], } break; case 'l': - targs->seconds =3D atoi(optarg); + targs->seconds =3D atoi_paranoid(optarg); if (targs->seconds < 0) { pr_info("Test length in seconds has to be non-negative\n"); return false; } break; case 'r': - targs->runs =3D atoi(optarg); + targs->runs =3D atoi_paranoid(optarg); if (targs->runs <=3D 0) { pr_info("Runs per test has to be positive\n"); return false; diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/t= esting/selftests/kvm/set_memory_region_test.c index 0d55f508d595..c366949c8362 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -407,7 +407,7 @@ int main(int argc, char *argv[]) =20 #ifdef __x86_64__ if (argc > 1) - loops =3D atoi(argv[1]); + loops =3D atoi_paranoid(argv[1]); else loops =3D 10; =20 diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tool= s/testing/selftests/kvm/x86_64/nx_huge_pages_test.c index 59ffe7fd354f..354b6902849c 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 @@ -241,10 +241,10 @@ int main(int argc, char **argv) while ((opt =3D getopt(argc, argv, "hp:t:r")) !=3D -1) { switch (opt) { case 'p': - reclaim_period_ms =3D atoi(optarg); + reclaim_period_ms =3D atoi_paranoid(optarg); break; case 't': - token =3D atoi(optarg); + token =3D atoi_paranoid(optarg); break; case 'r': reboot_permissions =3D true; --=20 2.38.1.273.g43a17bfeac-goog From nobody Thu Apr 9 00:18:11 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 DAA81FA3741 for ; Mon, 31 Oct 2022 17:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbiJaRiu (ORCPT ); Mon, 31 Oct 2022 13:38:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230243AbiJaRio (ORCPT ); Mon, 31 Oct 2022 13:38:44 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7FA813CFC for ; Mon, 31 Oct 2022 10:38:30 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-348608c1cd3so109235977b3.10 for ; Mon, 31 Oct 2022 10:38:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3Evd5a8CRBvv77lAu62Ue9D6+dvJHXkM2aGaB7fGSBE=; b=KULdNN0+qWbIbkXlpv6Y7tyME3a6JSExPnq3RWF/BJxfnyT1kVfbUHzMsFZfQR7uHq I/R8xR31Syks/m9Z4aTIN1hiaS/uEJSJMBhqniQr+kte2gd+6XYHt14qD7bx0R45WlMd zvCg+QpamWHp2oW7weS5F5YLIPwdJ/21c5CPM6geLuaZJhjtgWMsdli6CFnYEeBIKBmb Jx6qmrX0Z1B3ixNTtzI4BxxbXdetxOZ0cMOfCUWc/oZ6hAinCt/5qzYxM7Cf9cuwm3Hh GfYFotJqMEGW0n040eaggLkZQcUuIlrqok4Keyg3nMReSYVx7BRbUOCLu6JlwnD+O8oe Jz6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3Evd5a8CRBvv77lAu62Ue9D6+dvJHXkM2aGaB7fGSBE=; b=1NzED5R428zfObz1kbhIaGx7/LMaQnvUm+k05vSj/gdWVUuLkZV/8goHUbVQsbDnfU WQAkXuFN3eUcUUNfNIuWtj3SX7JhFPaCupfQ3t6i3CO1ICqd6ckC7ePrJGC/832auoz9 RPeA5moY4/WKhMz/jArGvCm7E2CxFPTyT08lLXkQK9lMscb5W02M5a17rBBWEnrK/61Q IXHQv8LupTzCeKTci7Z0cpuejrz4Q15rJZ9v+kToQw0DkFPvP9yO+6fYXnoRQlFEDuED wWq68OrsPeT7aA/SF4/9uNryYb2nSUSWxQOCtFcIRxq+xkAgDtEPgrj2p+YdkQW6hHnI iNrQ== X-Gm-Message-State: ACrzQf3VipOJ4YLuTRFQAkb3d0oMrDgPN1DRmxwBpWA1gFKcOX+yRSWo uypazn8qjjAv5HBew/rxwXdjPLyf457W X-Google-Smtp-Source: AMsMyM6GOTjwGRuKEpV1nQGiQo9Hor2jMO1CHX9couHv5Qq8ZV+2+zz9owvsVLnJhgwRmljFQtGNmcOoloCS X-Received: from vipin.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:479f]) (user=vipinsh job=sendgmr) by 2002:a25:bec1:0:b0:6cc:57e2:6f2c with SMTP id k1-20020a25bec1000000b006cc57e26f2cmr10823139ybm.544.1667237910170; Mon, 31 Oct 2022 10:38:30 -0700 (PDT) Date: Mon, 31 Oct 2022 10:38:18 -0700 In-Reply-To: <20221031173819.1035684-1-vipinsh@google.com> Mime-Version: 1.0 References: <20221031173819.1035684-1-vipinsh@google.com> X-Mailer: git-send-email 2.38.1.273.g43a17bfeac-goog Message-ID: <20221031173819.1035684-5-vipinsh@google.com> Subject: [PATCH v7 4/5] KVM: selftests: Add atoi_positive() and atoi_non_negative() for input validation From: Vipin Sharma To: seanjc@google.com, pbonzini@redhat.com, dmatlack@google.com Cc: andrew.jones@linux.dev, wei.w.wang@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vipin Sharma Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Many KVM selftests take command line arguments which are supposed to be positive (>0) or non-negative (>=3D0). Some tests do these validation and some missed adding the check. Add atoi_positive() and atoi_non_negative() to validate inputs in selftests before proceeding to use those values. Signed-off-by: Vipin Sharma --- .../selftests/kvm/aarch64/arch_timer.c | 25 ++++--------------- .../selftests/kvm/aarch64/debug-exceptions.c | 2 +- .../testing/selftests/kvm/aarch64/vgic_irq.c | 2 +- .../selftests/kvm/access_tracking_perf_test.c | 2 +- .../selftests/kvm/demand_paging_test.c | 4 +-- .../selftests/kvm/dirty_log_perf_test.c | 12 ++++----- .../testing/selftests/kvm/include/test_util.h | 2 ++ .../selftests/kvm/kvm_page_table_test.c | 4 +-- tools/testing/selftests/kvm/lib/test_util.c | 16 ++++++++++++ .../selftests/kvm/max_guest_memory_test.c | 7 +++--- .../kvm/memslot_modification_stress_test.c | 6 ++--- .../testing/selftests/kvm/memslot_perf_test.c | 22 ++++------------ .../selftests/kvm/set_memory_region_test.c | 2 +- 13 files changed, 47 insertions(+), 59 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testi= ng/selftests/kvm/aarch64/arch_timer.c index 251e7ff04883..24dffcaf7a9f 100644 --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c @@ -414,36 +414,21 @@ static bool parse_args(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "hn:i:p:m:")) !=3D -1) { switch (opt) { case 'n': - test_args.nr_vcpus =3D atoi_paranoid(optarg); - if (test_args.nr_vcpus <=3D 0) { - pr_info("Positive value needed for -n\n"); - goto err; - } else if (test_args.nr_vcpus > KVM_MAX_VCPUS) { + test_args.nr_vcpus =3D atoi_positive(optarg); + if (test_args.nr_vcpus > KVM_MAX_VCPUS) { pr_info("Max allowed vCPUs: %u\n", KVM_MAX_VCPUS); goto err; } break; case 'i': - test_args.nr_iter =3D atoi_paranoid(optarg); - if (test_args.nr_iter <=3D 0) { - pr_info("Positive value needed for -i\n"); - goto err; - } + test_args.nr_iter =3D atoi_positive(optarg); break; case 'p': - test_args.timer_period_ms =3D atoi_paranoid(optarg); - if (test_args.timer_period_ms <=3D 0) { - pr_info("Positive value needed for -p\n"); - goto err; - } + test_args.timer_period_ms =3D atoi_positive(optarg); break; case 'm': - test_args.migration_freq_ms =3D atoi_paranoid(optarg); - if (test_args.migration_freq_ms < 0) { - pr_info("0 or positive value needed for -m\n"); - goto err; - } + test_args.migration_freq_ms =3D atoi_non_negative(optarg); break; case 'h': default: diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools= /testing/selftests/kvm/aarch64/debug-exceptions.c index 19fffdf19c9f..9650e8a9bac6 100644 --- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c @@ -423,7 +423,7 @@ int main(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "i:")) !=3D -1) { switch (opt) { case 'i': - ss_iteration =3D atoi_paranoid(optarg); + ss_iteration =3D atoi_positive(optarg); break; case 'h': default: diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing= /selftests/kvm/aarch64/vgic_irq.c index ae90b718070a..d7da5f24db35 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -824,7 +824,7 @@ int main(int argc, char **argv) while ((opt =3D getopt(argc, argv, "hn:e:l:")) !=3D -1) { switch (opt) { case 'n': - nr_irqs =3D atoi_paranoid(optarg); + nr_irqs =3D atoi_non_negative(optarg); if (nr_irqs > 1024 || nr_irqs % 32) help(argv[0]); break; diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tool= s/testing/selftests/kvm/access_tracking_perf_test.c index c6bcc5301e2c..b30500cc197e 100644 --- a/tools/testing/selftests/kvm/access_tracking_perf_test.c +++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) params.vcpu_memory_bytes =3D parse_size(optarg); break; case 'v': - params.nr_vcpus =3D atoi_paranoid(optarg); + params.nr_vcpus =3D atoi_positive(optarg); break; case 'o': overlap_memory_access =3D true; diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testi= ng/selftests/kvm/demand_paging_test.c index 82597fb04146..dcdb6964b1dc 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -427,8 +427,8 @@ int main(int argc, char *argv[]) p.src_type =3D parse_backing_src_type(optarg); break; case 'v': - nr_vcpus =3D atoi_paranoid(optarg); - TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, + nr_vcpus =3D atoi_positive(optarg); + TEST_ASSERT(nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; case 'o': diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index ecda802b78ff..618598ddd993 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -416,9 +416,7 @@ int main(int argc, char *argv[]) run_vcpus_while_disabling_dirty_logging =3D true; break; case 'f': - p.wr_fract =3D atoi_paranoid(optarg); - TEST_ASSERT(p.wr_fract >=3D 1, - "Write fraction cannot be less than one"); + p.wr_fract =3D atoi_positive(optarg); break; case 'g': dirty_log_manual_caps =3D 0; @@ -427,7 +425,7 @@ int main(int argc, char *argv[]) help(argv[0]); break; case 'i': - p.iterations =3D atoi_paranoid(optarg); + p.iterations =3D atoi_positive(optarg); break; case 'm': guest_modes_cmdline(optarg); @@ -445,12 +443,12 @@ int main(int argc, char *argv[]) p.backing_src =3D parse_backing_src_type(optarg); break; case 'v': - nr_vcpus =3D atoi_paranoid(optarg); - TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, + nr_vcpus =3D atoi_positive(optarg); + TEST_ASSERT(nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; case 'x': - p.slots =3D atoi_paranoid(optarg); + p.slots =3D atoi_positive(optarg); break; default: help(argv[0]); diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testin= g/selftests/kvm/include/test_util.h index feae42863759..9c7b2c186a48 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -153,5 +153,7 @@ static inline void *align_ptr_up(void *x, size_t size) } =20 int atoi_paranoid(const char *num_str); +uint32_t atoi_positive(const char *num_str); +uint32_t atoi_non_negative(const char *num_str); =20 #endif /* SELFTEST_KVM_TEST_UTIL_H */ diff --git a/tools/testing/selftests/kvm/kvm_page_table_test.c b/tools/test= ing/selftests/kvm/kvm_page_table_test.c index ea7feb69bb88..2f62e19976fd 100644 --- a/tools/testing/selftests/kvm/kvm_page_table_test.c +++ b/tools/testing/selftests/kvm/kvm_page_table_test.c @@ -461,8 +461,8 @@ int main(int argc, char *argv[]) p.test_mem_size =3D parse_size(optarg); break; case 'v': - nr_vcpus =3D atoi_paranoid(optarg); - TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, + nr_vcpus =3D atoi_positive(optarg); + TEST_ASSERT(nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; case 's': diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/se= lftests/kvm/lib/test_util.c index ec0f070a6f21..210e98a49a83 100644 --- a/tools/testing/selftests/kvm/lib/test_util.c +++ b/tools/testing/selftests/kvm/lib/test_util.c @@ -353,3 +353,19 @@ int atoi_paranoid(const char *num_str) =20 return num; } + +uint32_t atoi_positive(const char *num_str) +{ + int num =3D atoi_paranoid(num_str); + + TEST_ASSERT(num > 0, "%s is not a positive integer.\n", num_str); + return num; +} + +uint32_t atoi_non_negative(const char *num_str) +{ + int num =3D atoi_paranoid(num_str); + + TEST_ASSERT(num >=3D 0, "%s is not a non-negative integer.\n", num_str); + return num; +} diff --git a/tools/testing/selftests/kvm/max_guest_memory_test.c b/tools/te= sting/selftests/kvm/max_guest_memory_test.c index 1595b73dc09a..20015de3b91c 100644 --- a/tools/testing/selftests/kvm/max_guest_memory_test.c +++ b/tools/testing/selftests/kvm/max_guest_memory_test.c @@ -193,15 +193,14 @@ int main(int argc, char *argv[]) while ((opt =3D getopt(argc, argv, "c:h:m:s:H")) !=3D -1) { switch (opt) { case 'c': - nr_vcpus =3D atoi_paranoid(optarg); - TEST_ASSERT(nr_vcpus > 0, "number of vcpus must be >0"); + nr_vcpus =3D atoi_positive(optarg); break; case 'm': - max_mem =3D atoi_paranoid(optarg) * size_1gb; + max_mem =3D atoi_positive(optarg) * size_1gb; TEST_ASSERT(max_mem > 0, "memory size must be >0"); break; case 's': - slot_size =3D atoi_paranoid(optarg) * size_1gb; + slot_size =3D atoi_positive(optarg) * size_1gb; TEST_ASSERT(slot_size > 0, "slot size must be >0"); break; case 'H': diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c= b/tools/testing/selftests/kvm/memslot_modification_stress_test.c index 865276993ffb..7539ee7b6e95 100644 --- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c +++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c @@ -166,8 +166,8 @@ int main(int argc, char *argv[]) guest_percpu_mem_size =3D parse_size(optarg); break; case 'v': - nr_vcpus =3D atoi_paranoid(optarg); - TEST_ASSERT(nr_vcpus > 0 && nr_vcpus <=3D max_vcpus, + nr_vcpus =3D atoi_positive(optarg); + TEST_ASSERT(nr_vcpus <=3D max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) p.partition_vcpu_memory_access =3D false; break; case 'i': - p.nr_memslot_modifications =3D atoi_paranoid(optarg); + p.nr_memslot_modifications =3D atoi_positive(optarg); break; case 'h': default: diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testin= g/selftests/kvm/memslot_perf_test.c index 4bae9e3f5ca1..8e6e2d44d002 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -892,33 +892,21 @@ static bool parse_args(int argc, char *argv[], } break; case 'f': - targs->tfirst =3D atoi_paranoid(optarg); - if (targs->tfirst < 0) { - pr_info("First test to run has to be non-negative\n"); - return false; - } + targs->tfirst =3D atoi_non_negative(optarg); break; case 'e': - targs->tlast =3D atoi_paranoid(optarg); - if (targs->tlast < 0 || targs->tlast >=3D NTESTS) { + targs->tlast =3D atoi_non_negative(optarg); + if (targs->tlast >=3D NTESTS) { pr_info("Last test to run has to be non-negative and less than %zu\n", NTESTS); return false; } break; case 'l': - targs->seconds =3D atoi_paranoid(optarg); - if (targs->seconds < 0) { - pr_info("Test length in seconds has to be non-negative\n"); - return false; - } + targs->seconds =3D atoi_non_negative(optarg); break; case 'r': - targs->runs =3D atoi_paranoid(optarg); - if (targs->runs <=3D 0) { - pr_info("Runs per test has to be positive\n"); - return false; - } + targs->runs =3D atoi_positive(optarg); break; } } diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/t= esting/selftests/kvm/set_memory_region_test.c index c366949c8362..e09092110121 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -407,7 +407,7 @@ int main(int argc, char *argv[]) =20 #ifdef __x86_64__ if (argc > 1) - loops =3D atoi_paranoid(argv[1]); + loops =3D atoi_positive(argv[1]); else loops =3D 10; =20 --=20 2.38.1.273.g43a17bfeac-goog From nobody Thu Apr 9 00:18:11 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 F271EFA3741 for ; Mon, 31 Oct 2022 17:38:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231352AbiJaRiy (ORCPT ); Mon, 31 Oct 2022 13:38:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231169AbiJaRiq (ORCPT ); Mon, 31 Oct 2022 13:38:46 -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 AC32E13D00 for ; Mon, 31 Oct 2022 10:38:32 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-36bf9c132f9so108144117b3.8 for ; Mon, 31 Oct 2022 10:38:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2E0KDpSiGS3oLmjRJZCFY9fLJv7/37jpr+PzAS0jGl8=; b=VSKB5tKUCfPCxcxXaH6S6clJ426FNZJ7fk0zuqgVjdsm6Mi9yGHzTY1s/pKrMZSaz5 NW/qhp7/inK4u3aIH7Mx1uKGNQo+AWur4AmcXeRI5rfpg+jRuLlVvwMTV35AjGIzbLZP OZHRRaCr6LIERVLk113A/XZtKL/SL54ET8t+yiQJYZzS+M5e/ip9IqJAAdE9AWn2PjaJ BAeRgywzx4nHBJDF1j0+sjDadLIa5jfWN8167FGD4xKfRM9DMnOkApymu/+faKgJdWmx Aj+yXMpToXf0f5dKzLA0dCeFKgJpm/L0Xt/bUw6zlGITGRznVyKgpCCslRrx3MyCk6o9 KRHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2E0KDpSiGS3oLmjRJZCFY9fLJv7/37jpr+PzAS0jGl8=; b=r3bMk4F4z3kjWu0vz0EyaVdvIPHo2bvv9LXeQRFq4QKsMaOhnEvGWcrkUD//wkxiT5 MGGylLbIka2Z2Mak2gSAkbHZUviK7QJiBKIByQJ18HDPu/zPySjg6RQ8fkB7GcDMqEgX oTIFjZAC8KIL4xrO88shORMr1ybboYDYzoXDce2U5ehR7Ssp5nRkF6C6Rc2gpaE8i42n sgzfBKJeZYXBN+qGVhHCL7J9H7T4X0pjByWPTSBf2lpP/vI+LsU+4jKR1F1rziVBk1zD my3CLMHk4W2h/QhM6Lo43X4RTTKHuvdt1GVjCpwznViQ1RhVdvJQQJMbbGF3Ze84KNcS 3Ahw== X-Gm-Message-State: ACrzQf2rgdY5jm7I+7/+3Gh+bW5B9jtTfZJFnYIkHhxmys09e6ZU6Ten roexIIPmZAqLuTopEtH2TEn1QE6Lwd1a X-Google-Smtp-Source: AMsMyM5n/zwOMk+KkdEOYixOsCR9RR1+5IktxDw0EIRMYXx/sQEUO+vYGbzJTXIB6aukOIk9sSZMbMIsQ7/1 X-Received: from vipin.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:479f]) (user=vipinsh job=sendgmr) by 2002:a81:55c1:0:b0:370:950:10bb with SMTP id j184-20020a8155c1000000b00370095010bbmr14264177ywb.229.1667237911985; Mon, 31 Oct 2022 10:38:31 -0700 (PDT) Date: Mon, 31 Oct 2022 10:38:19 -0700 In-Reply-To: <20221031173819.1035684-1-vipinsh@google.com> Mime-Version: 1.0 References: <20221031173819.1035684-1-vipinsh@google.com> X-Mailer: git-send-email 2.38.1.273.g43a17bfeac-goog Message-ID: <20221031173819.1035684-6-vipinsh@google.com> Subject: [PATCH v7 5/5] KVM: selftests: Allowing running dirty_log_perf_test on specific CPUs From: Vipin Sharma To: seanjc@google.com, pbonzini@redhat.com, dmatlack@google.com Cc: andrew.jones@linux.dev, wei.w.wang@intel.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vipin Sharma 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 a command line option, -c, to pin vCPUs to physical CPUs (pCPUs), i.e. to force vCPUs to run on specific pCPUs. Requirement to implement this feature came in discussion on the patch "Make page tables for eager page splitting NUMA aware" https://lore.kernel.org/lkml/YuhPT2drgqL+osLl@google.com/ This feature is useful as it provides a way to analyze performance based on the vCPUs and dirty log worker locations, like on the different NUMA nodes or on the same NUMA nodes. To keep things simple, implementation is intentionally very limited, either all of the vCPUs will be pinned followed by an optional main thread or nothing will be pinned. Signed-off-by: Vipin Sharma Suggested-by: David Matlack Reviewed-by: Sean Christopherson --- .../selftests/kvm/dirty_log_perf_test.c | 25 ++++++++- .../selftests/kvm/include/kvm_util_base.h | 4 ++ .../selftests/kvm/include/perf_test_util.h | 4 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 54 +++++++++++++++++++ .../selftests/kvm/lib/perf_test_util.c | 8 ++- 5 files changed, 92 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/test= ing/selftests/kvm/dirty_log_perf_test.c index 618598ddd993..a82fc51d57ca 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -353,7 +353,7 @@ static void help(char *name) puts(""); printf("usage: %s [-h] [-i iterations] [-p offset] [-g] " "[-m mode] [-n] [-b vcpu bytes] [-v vcpus] [-o] [-s mem type]" - "[-x memslots]\n", name); + "[-x memslots] [-c physical cpus to run test on]\n", name); puts(""); printf(" -i: specify iteration counts (default: %"PRIu64")\n", TEST_HOST_LOOP_N); @@ -383,6 +383,17 @@ static void help(char *name) backing_src_help("-s"); printf(" -x: Split the memory region into this number of memslots.\n" " (default: 1)\n"); + printf(" -c: Pin tasks to physical CPUs. Takes a list of comma separated= \n" + " values (target pCPU), one for each vCPU, plus an optional\n" + " entry for the main application task (specified via entry\n" + " ). If used, entries must be provided for all\= n" + " vCPUs, i.e. pinning vCPUs is all or nothing.\n\n" + " E.g. to create 3 vCPUs, pin vCPU0=3D>pCPU22, vCPU1=3D>pCPU23= ,\n" + " vCPU2=3D>pCPU24, and pin the application task to pCPU50:\n\n" + " ./dirty_log_perf_test -v 3 -c 22,23,24,50\n\n" + " To leave the application task unpinned, drop the final entry= :\n\n" + " ./dirty_log_perf_test -v 3 -c 22,23,24\n\n" + " (default: no pinning)\n"); puts(""); exit(0); } @@ -390,6 +401,7 @@ static void help(char *name) int main(int argc, char *argv[]) { int max_vcpus =3D kvm_check_cap(KVM_CAP_MAX_VCPUS); + const char *pcpu_list =3D NULL; struct test_params p =3D { .iterations =3D TEST_HOST_LOOP_N, .wr_fract =3D 1, @@ -406,11 +418,14 @@ int main(int argc, char *argv[]) =20 guest_modes_append_default(); =20 - while ((opt =3D getopt(argc, argv, "b:ef:ghi:m:nop:s:v:x:")) !=3D -1) { + while ((opt =3D getopt(argc, argv, "b:c:ef:ghi:m:nop:s:v:x:")) !=3D -1) { switch (opt) { case 'b': guest_percpu_mem_size =3D parse_size(optarg); break; + case 'c': + pcpu_list =3D optarg; + break; case 'e': /* 'e' is for evil. */ run_vcpus_while_disabling_dirty_logging =3D true; @@ -456,6 +471,12 @@ int main(int argc, char *argv[]) } } =20 + if (pcpu_list) { + kvm_parse_vcpu_pinning(pcpu_list, perf_test_args.vcpu_to_pcpu, + nr_vcpus); + perf_test_args.pin_vcpus =3D true; + } + TEST_ASSERT(p.iterations >=3D 2, "The test should have at least two itera= tions"); =20 pr_info("Test iterations: %"PRIu64"\n", p.iterations); diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index e42a09cd24a0..3bf2333ef95d 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -688,6 +688,10 @@ static inline struct kvm_vm *vm_create_with_one_vcpu(s= truct kvm_vcpu **vcpu, =20 struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); =20 +void kvm_pin_this_task_to_pcpu(uint32_t pcpu); +void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcp= u[], + int nr_vcpus); + unsigned long vm_compute_max_gfn(struct kvm_vm *vm); unsigned int vm_calc_num_guest_pages(enum vm_guest_mode mode, size_t size); unsigned int vm_num_host_pages(enum vm_guest_mode mode, unsigned int num_g= uest_pages); diff --git a/tools/testing/selftests/kvm/include/perf_test_util.h b/tools/t= esting/selftests/kvm/include/perf_test_util.h index eaa88df0555a..849c875dd0ff 100644 --- a/tools/testing/selftests/kvm/include/perf_test_util.h +++ b/tools/testing/selftests/kvm/include/perf_test_util.h @@ -39,6 +39,10 @@ struct perf_test_args { =20 /* Run vCPUs in L2 instead of L1, if the architecture supports it. */ bool nested; + /* True if all vCPUs are pinned to pCPUs */ + bool pin_vcpus; + /* The vCPU=3D>pCPU pinning map. Only valid if pin_vcpus is true. */ + uint32_t vcpu_to_pcpu[KVM_MAX_VCPUS]; =20 struct perf_test_vcpu_args vcpu_args[KVM_MAX_VCPUS]; }; diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index f1cb1627161f..8292af9d7660 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -11,6 +11,7 @@ #include "processor.h" =20 #include +#include #include #include #include @@ -443,6 +444,59 @@ struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_= vm *vm) return vm_vcpu_recreate(vm, 0); } =20 +void kvm_pin_this_task_to_pcpu(uint32_t pcpu) +{ + cpu_set_t mask; + int r; + + CPU_ZERO(&mask); + CPU_SET(pcpu, &mask); + r =3D sched_setaffinity(0, sizeof(mask), &mask); + TEST_ASSERT(!r, "sched_setaffinity() failed for pCPU '%u'.\n", pcpu); +} + +static uint32_t parse_pcpu(const char *cpu_str, const cpu_set_t *allowed_m= ask) +{ + uint32_t pcpu =3D atoi_non_negative(cpu_str); + + TEST_ASSERT(CPU_ISSET(pcpu, allowed_mask), + "Not allowed to run on pCPU '%d', check cgroups?\n", pcpu); + return pcpu; +} + +void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcp= u[], + int nr_vcpus) +{ + cpu_set_t allowed_mask; + char *cpu, *cpu_list; + char delim[2] =3D ","; + int i, r; + + cpu_list =3D strdup(pcpus_string); + TEST_ASSERT(cpu_list, "strdup() allocation failed.\n"); + + r =3D sched_getaffinity(0, sizeof(allowed_mask), &allowed_mask); + TEST_ASSERT(!r, "sched_getaffinity() failed"); + + cpu =3D strtok(cpu_list, delim); + + /* 1. Get all pcpus for vcpus. */ + for (i =3D 0; i < nr_vcpus; i++) { + TEST_ASSERT(cpu, "pCPU not provided for vCPU '%d'\n", i); + vcpu_to_pcpu[i] =3D parse_pcpu(cpu, &allowed_mask); + cpu =3D strtok(NULL, delim); + } + + /* 2. Check if the main worker needs to be pinned. */ + if (cpu) { + kvm_pin_this_task_to_pcpu(parse_pcpu(cpu, &allowed_mask)); + cpu =3D strtok(NULL, delim); + } + + TEST_ASSERT(!cpu, "pCPU list contains trailing garbage characters '%s'", = cpu); + free(cpu_list); +} + /* * Userspace Memory Region Find * diff --git a/tools/testing/selftests/kvm/lib/perf_test_util.c b/tools/testi= ng/selftests/kvm/lib/perf_test_util.c index 9618b37c66f7..3a1d0a44419b 100644 --- a/tools/testing/selftests/kvm/lib/perf_test_util.c +++ b/tools/testing/selftests/kvm/lib/perf_test_util.c @@ -2,6 +2,8 @@ /* * Copyright (C) 2020, Google LLC. */ +#define _GNU_SOURCE + #include =20 #include "kvm_util.h" @@ -243,6 +245,10 @@ void __weak perf_test_setup_nested(struct kvm_vm *vm, = int nr_vcpus, struct kvm_v static void *vcpu_thread_main(void *data) { struct vcpu_thread *vcpu =3D data; + int vcpu_idx =3D vcpu->vcpu_idx; + + if (perf_test_args.pin_vcpus) + kvm_pin_this_task_to_pcpu(perf_test_args.vcpu_to_pcpu[vcpu_idx]); =20 WRITE_ONCE(vcpu->running, true); =20 @@ -255,7 +261,7 @@ static void *vcpu_thread_main(void *data) while (!READ_ONCE(all_vcpu_threads_running)) ; =20 - vcpu_thread_fn(&perf_test_args.vcpu_args[vcpu->vcpu_idx]); + vcpu_thread_fn(&perf_test_args.vcpu_args[vcpu_idx]); =20 return NULL; } --=20 2.38.1.273.g43a17bfeac-goog