Received: by 2002:a05:7412:1e0b:b0:fc:a2b0:25d7 with SMTP id kr11csp516385rdb; Thu, 15 Feb 2024 07:09:34 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUZIDH3cQDi9dDKBxD+AgnFuki4eze1eH5/ebaxDmLDWOM/W9BZ7V6QZ3LAjH1jrkV40R3lVhIses5n1U4kRFro6DU5ezFd4tcP0jI7yA== X-Google-Smtp-Source: AGHT+IFYNFwoIMtAasuBV9SJk9G3tciEj9t6jiaeK7hgM/QinBPDmqV1MU3Z6HlHaoWcaI7f8Yl6 X-Received: by 2002:a05:6a20:438d:b0:19e:a1b5:e765 with SMTP id i13-20020a056a20438d00b0019ea1b5e765mr2978177pzl.9.1708009774700; Thu, 15 Feb 2024 07:09:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708009774; cv=pass; d=google.com; s=arc-20160816; b=oLVP7XSPNi/sKmCotksXmPawKz4OrM/KjdJUhwRGC2VvkSKInN761IWkwtr/wJ7DNH db+kWbI47VOzOyUK33kgiPrFWS+jcEsMZGW8BVFQWHMg8M6pufC8i0k9wuAlOJ6ABcWl NaqY3paGZnnN8PrVaom/Z9xXEvZfTOH9WrcE5BmacXmvm9ilmBGxySjE1qiCxuJfsntk bs8thhXoUg0zjLSRPTBqSzYCkfCpph7YFI09U/5nqerUTloKgc16qK8W7RvmqmOGpyKv 33urgg4SDMQELGwHTSIhPONIWHOG+Whp1pF+6uI+FSttv+rNLBvjg9Orjf0kJU7dKqPE DL4Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature; bh=DU/I58QZ3iymbaVm/jdmROBBRbIzgpeEc0Gm3Gdul0M=; fh=PunKXji5J7SXfVHLltS5CLWOR3pYmNjgJn2nS3xQrrE=; b=Ii7RANyvVYCHoXTX2F1yeRXZ79A8bva4GhIPBHqPJ7wjmab48V41mD5qFRaTVGQvJD 03gRmgjLMlRFlCFKdDEDYwdaSE0JPQulXdG4YcMM+KHEZhOMOIPtIoWfvy91KkEYhTgC 6sQ1ahYzWU85tS6Abs4bMUcSNjvwnuYGPvzhXuJmaNtuGuJqDDVcMBd1fSLrjmIhqF/M 9n862P+/sS1rXTdc5eDvjQBkPzVFbwWLIhtLPyKgVOkF4feFladt96SzIKmudfrfeAZu njO61cQAUNSXw1j9LRm/aBdhYwt4jLZl4opVszMUxayBvmSp1IOALMz2AVX+nU/wt3ga kQMA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ZjHd0ltX; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-67092-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-67092-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id m20-20020a63f614000000b005d59eb08d15si1291320pgh.383.2024.02.15.07.09.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Feb 2024 07:09:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-67092-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ZjHd0ltX; arc=pass (i=1 spf=pass spfdomain=redhat.com dkim=pass dkdomain=redhat.com dmarc=pass fromdomain=redhat.com); spf=pass (google.com: domain of linux-kernel+bounces-67092-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-67092-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id D22E0B25FC9 for ; Thu, 15 Feb 2024 14:42:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5C993132C1C; Thu, 15 Feb 2024 14:42:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZjHd0ltX" Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A552B132494 for ; Thu, 15 Feb 2024 14:42:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708008137; cv=none; b=LNe6rZunMNBaR3rQ0aOKtfaYWa4QJBcD3abTYCAMp/Sp0xumkiMJKPOdy+wrmQV8CJRxXAy97NTbKLeSeIuBCb/SAU6EMDGZSmb0pUvjzFb4/m8ziJd103bk28vi5UYzAQgR9lhsD9A3O81+EjPuBqeH9KfZBVTZf6EUI/5fGTI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708008137; c=relaxed/simple; bh=KVQXyddDCqFOkaQkPG/3aBE9fjuhRZsKr40SbrA8X64=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=Wy1BPeeOIOLGGQfCv/pjBy4i269sEPe3EhKV+G5mTN6l/oPJJ3aQ3xKCPf2EsXrG/KGhFYwUKnzJKLO7fwKU/1AvXXsLOt93jPu8QE67paeyJnC6k5lwahv3aBwzu1VVJYQOvaI7paWgV0+FPIiF54FJttLWiP88nW/S2/K3rWk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZjHd0ltX; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1708008131; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DU/I58QZ3iymbaVm/jdmROBBRbIzgpeEc0Gm3Gdul0M=; b=ZjHd0ltXAz6JknKtesqoCXtJ4AUY7477St8W1zc1QgSr6AUDlQvPGmpArioT/2IEVX03RO ttxjkfuHcOLmb39Ry7koGN7Ajzq4MxtLLX7SLyAoKuO1gHID4x1IvRicnLyui02ZKC4C8D y6AjKHLSt7v4cGAsTzNoNQzblTx7lfI= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-643-h-R2R_ftMFC2WWaPlyPJaw-1; Thu, 15 Feb 2024 09:42:10 -0500 X-MC-Unique: h-R2R_ftMFC2WWaPlyPJaw-1 Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-7817253831cso118536285a.0 for ; Thu, 15 Feb 2024 06:42:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708008130; x=1708612930; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DU/I58QZ3iymbaVm/jdmROBBRbIzgpeEc0Gm3Gdul0M=; b=a3xx6IAkgG5JYBDePX7MF13zwCbKBIZ3JFzzytfgnEaixTG4PIQs1DKzFadrxMk7EX BGLcOYmye0/BG3bE+1LcfSttlam+o4uXNy5gy5wEc8V3Mpf6xp1dcAflSM1g7M8Mfr1w lDsUxLh0vQY2nbfWh3V7xVxRWmPT/KRdS9DmcyT8lmCwpvKI7SOTFfFB5HllY1saXHr4 jLlDkZT2jN4JkuBwFuyrgYbB8OncAuxwONesML1xio9RZFAN8y9vf4ZT3ryajbvTWrHh 1UNhy7xKfL7odHm98ckm0TWHYVFnV8snZOqhQHLnEV7mIWoZ+U6qKvjzMUJKJaRVsAwz KNtw== X-Forwarded-Encrypted: i=1; AJvYcCWC7MnFhxtRLq7EOswwDEyv/0FlZXk+hMjShd0qPazVxD85d0VUt/v8l0rDX4DMy/HT3nZP8u3mDE8+bpy6XGKtaCuoyvDvC+ttSjde X-Gm-Message-State: AOJu0Yy3KV7QkCXUU9ZpONOlxyPBYKa5ySw2PqfHiLELphz1nLRb3PDK RyX8u2hysx7MdnxXqDVjbuUcXdO0mOmBCBN31WXL1rYy+CFOmlVJzx3EEPlWj8KFBWDz58QyUfI SrgNPC8mBdqxVUaceMpqbq139rGpIkivCO3KeZRY/B8xJzV3I75f1dUQIIUbEiA== X-Received: by 2002:a05:620a:13e4:b0:785:c28b:d86c with SMTP id h4-20020a05620a13e400b00785c28bd86cmr2100294qkl.66.1708008129716; Thu, 15 Feb 2024 06:42:09 -0800 (PST) X-Received: by 2002:a05:620a:13e4:b0:785:c28b:d86c with SMTP id h4-20020a05620a13e400b00785c28bd86cmr2100269qkl.66.1708008129385; Thu, 15 Feb 2024 06:42:09 -0800 (PST) Received: from ?IPV6:2a01:e0a:59e:9d80:527b:9dff:feef:3874? ([2a01:e0a:59e:9d80:527b:9dff:feef:3874]) by smtp.gmail.com with ESMTPSA id p21-20020a05620a113500b00783f77b968fsm636620qkk.109.2024.02.15.06.42.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Feb 2024 06:42:08 -0800 (PST) Message-ID: Date: Thu, 15 Feb 2024 15:42:05 +0100 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v4 4/5] KVM: selftests: aarch64: Introduce pmu_event_filter_test Content-Language: en-US To: Oliver Upton , Shaoqin Huang Cc: Marc Zyngier , kvmarm@lists.linux.dev, Paolo Bonzini , Shuah Khan , James Morse , Suzuki K Poulose , Zenghui Yu , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-arm-kernel@lists.infradead.org References: <20240202025659.5065-1-shahuang@redhat.com> <20240202025659.5065-5-shahuang@redhat.com> From: Eric Auger In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Hi Shaoqin, On 2/2/24 09:34, Oliver Upton wrote: > On Thu, Feb 01, 2024 at 09:56:53PM -0500, Shaoqin Huang wrote: >> Introduce pmu_event_filter_test for arm64 platforms. The test configures >> PMUv3 for a vCPU, and sets different pmu event filters for the vCPU, and >> check if the guest can see those events which user allow and can't use >> those events which use deny. >> >> This test refactor the create_vpmu_vm() and make it a wrapper for >> __create_vpmu_vm(), which allows some extra init code before >> KVM_ARM_VCPU_PMU_V3_INIT. >> >> And this test use the KVM_ARM_VCPU_PMU_V3_FILTER attribute to set the >> pmu event filter in KVM. And choose to filter two common event >> branches_retired and instructions_retired, and let the guest to check if >> it see the right pmceid register. >> >> Signed-off-by: Shaoqin Huang >> --- >> tools/testing/selftests/kvm/Makefile | 1 + >> .../kvm/aarch64/pmu_event_filter_test.c | 219 ++++++++++++++++++ >> .../selftests/kvm/include/aarch64/vpmu.h | 4 + >> .../testing/selftests/kvm/lib/aarch64/vpmu.c | 14 +- >> 4 files changed, 236 insertions(+), 2 deletions(-) >> create mode 100644 tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c >> >> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile >> index 709a70b31ca2..733ec86a3385 100644 >> --- a/tools/testing/selftests/kvm/Makefile >> +++ b/tools/testing/selftests/kvm/Makefile >> @@ -148,6 +148,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer >> TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions >> TEST_GEN_PROGS_aarch64 += aarch64/hypercalls >> TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test >> +TEST_GEN_PROGS_aarch64 += aarch64/pmu_event_filter_test >> TEST_GEN_PROGS_aarch64 += aarch64/psci_test >> TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs >> TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter >> diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c >> new file mode 100644 >> index 000000000000..d280382f362f >> --- /dev/null >> +++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c >> @@ -0,0 +1,219 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * pmu_event_filter_test - Test user limit pmu event for guest. >> + * >> + * Copyright (c) 2023 Red Hat, Inc. >> + * >> + * This test checks if the guest only see the limited pmu event that userspace >> + * sets, if the guest can use those events which user allow, and if the guest >> + * can't use those events which user deny. >> + * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER >> + * is supported on the host. >> + */ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +struct pmce{ > > Missing whitespace before curly brace. > > Also -- pmce is an odd name. Maybe common_event_ids or pmu_id_regs. > >> + uint64_t pmceid0; >> + uint64_t pmceid1; >> +} supported_pmce, guest_pmce; > > maybe "max_*" and "expected_*". It took me a bit to understand that > guest_pmce feeds in your expected PMCEID values. > >> +static struct vpmu_vm *vpmu_vm; >> + >> +#define FILTER_NR 10 >> + >> +struct test_desc { >> + const char *name; >> + struct kvm_pmu_event_filter filter[FILTER_NR]; >> +}; >> + >> +#define __DEFINE_FILTER(base, num, act) \ >> + ((struct kvm_pmu_event_filter) { \ >> + .base_event = base, \ >> + .nevents = num, \ >> + .action = act, \ >> + }) >> + >> +#define DEFINE_FILTER(base, act) __DEFINE_FILTER(base, 1, act) >> + >> +#define EMPTY_FILTER { 0 } >> + >> +#define SW_INCR 0x0 >> +#define INST_RETIRED 0x8 >> +#define BR_RETIRED 0x21 > > These event numbers are already defined in tools/include/perf/arm_pmuv3.h, > use those instead. > >> +static void guest_code(void) >> +{ >> + uint64_t pmceid0 = read_sysreg(pmceid0_el0); >> + uint64_t pmceid1 = read_sysreg(pmceid1_el0); >> + >> + GUEST_ASSERT_EQ(guest_pmce.pmceid0, pmceid0); >> + GUEST_ASSERT_EQ(guest_pmce.pmceid1, pmceid1); >> + >> + GUEST_DONE(); >> +} >> + >> +static void guest_get_pmceid(void) >> +{ >> + supported_pmce.pmceid0 = read_sysreg(pmceid0_el0); >> + supported_pmce.pmceid1 = read_sysreg(pmceid1_el0); >> + >> + GUEST_DONE(); >> +} >> + >> +static void pmu_event_filter_init(struct vpmu_vm *vm, void *arg) > > Why are you obfuscating the pointer to the filter array? > >> +{ >> + struct kvm_device_attr attr = { >> + .group = KVM_ARM_VCPU_PMU_V3_CTRL, >> + .attr = KVM_ARM_VCPU_PMU_V3_FILTER, >> + }; >> + struct kvm_pmu_event_filter *filter = (struct kvm_pmu_event_filter *)arg; >> + >> + while (filter && filter->nevents != 0) { >> + attr.addr = (uint64_t)filter; >> + vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr); > > Again, kvm_device_attr_set() the right helper to use. > >> +static void set_pmce(struct pmce *pmce, int action, int event) >> +{ >> + int base = 0; >> + uint64_t *pmceid = NULL; >> + >> + if (event >= 0x4000) { >> + event -= 0x4000; >> + base = 32; >> + } >> + >> + if (event >= 0 && event <= 0x1F) { >> + pmceid = &pmce->pmceid0; >> + } else if (event >= 0x20 && event <= 0x3F) { >> + event -= 0x20; >> + pmceid = &pmce->pmceid1; >> + } else { >> + return; >> + } >> + >> + event += base; >> + if (action == KVM_PMU_EVENT_ALLOW) >> + *pmceid |= BIT(event); >> + else >> + *pmceid &= ~BIT(event); >> +} >> + >> +static void prepare_guest_pmce(struct kvm_pmu_event_filter *filter) >> +{ >> + struct pmce pmce_mask = { ~0, ~0 }; >> + bool first_filter = true; >> + >> + while (filter && filter->nevents != 0) { >> + if (first_filter) { >> + if (filter->action == KVM_PMU_EVENT_ALLOW) >> + memset(&pmce_mask, 0, sizeof(pmce_mask)); >> + first_filter = false; >> + } >> + >> + set_pmce(&pmce_mask, filter->action, filter->base_event); >> + filter++; >> + } >> + >> + guest_pmce.pmceid0 = supported_pmce.pmceid0 & pmce_mask.pmceid0; >> + guest_pmce.pmceid1 = supported_pmce.pmceid1 & pmce_mask.pmceid1; >> +} > > Why do you need to do this? Can't you tell the guests what events to > expect and have it make sense of the PMCEID values it sees? > > You could, for example, pass in a pointer to the test descriptor as an > argument. > >> +static void run_test(struct test_desc *t) >> +{ >> + pr_debug("Test: %s\n", t->name); > > You may as well just pr_info() this thing. > >> + create_vpmu_vm_with_filter(guest_code, t->filter); >> + prepare_guest_pmce(t->filter); >> + sync_global_to_guest(vpmu_vm->vm, guest_pmce); >> + >> + run_vcpu(vpmu_vm->vcpu); >> + >> + destroy_vpmu_vm(vpmu_vm); >> +} >> + >> +static struct test_desc tests[] = { >> + {"without_filter", { EMPTY_FILTER }}, >> + {"member_allow_filter", >> + {DEFINE_FILTER(SW_INCR, 0), DEFINE_FILTER(INST_RETIRED, 0), >> + DEFINE_FILTER(BR_RETIRED, 0), EMPTY_FILTER}}, >> + {"member_deny_filter", >> + {DEFINE_FILTER(SW_INCR, 1), DEFINE_FILTER(INST_RETIRED, 1), >> + DEFINE_FILTER(BR_RETIRED, 1), EMPTY_FILTER}}, >> + {"not_member_deny_filter", >> + {DEFINE_FILTER(SW_INCR, 1), EMPTY_FILTER}}, >> + {"not_member_allow_filter", >> + {DEFINE_FILTER(SW_INCR, 0), EMPTY_FILTER}}, from a strict uapi testing you are not testing - "Cancelling" a filter by registering the opposite action for the same range doesn't change the default action. - Event 0 (SW_INCR) - Filtering event 0x1E (CHAIN) has no effect either - Filtering the cycle counter is possible using event 0x11 (CPU_CYCLES). Documentation/virt/kvm/devices/vcpu.rst Then it obviously depends on how much coverage of the API you want/can afford to reach. Eric > > Why is the filter array special enough to get its own sentinel macro > but... > >> + { 0 } > > ... the test descriptor array is okay to use a 'raw' initialization. My > vote is to drop the macro, zero-initializing a struct in an array is an > extremely common pattern in the kernel. > > Also, these descriptors are dense and hard to read. Working with an > example: > > { > .name = "member_allow_filter", > .filter = { > DEFINE_FILTER(SW_INCR, 0), > DEFINE_FILTER(INST_RETIRED, 0), > DEFINE_FILTER(BR_RETIRED, 0), > { 0 } > }, > } > > See how much more readable that is? > >> +}; >> + >> +static void for_each_test(void) >> +{ >> + struct test_desc *t; >> + >> + for (t = &tests[0]; t->name; t++) >> + run_test(t); >> +} > > for_each_test() sounds like an iterator, but this is not. Call it > run_tests() > >> +static bool kvm_supports_pmu_event_filter(void) >> +{ >> + int r; >> + >> + vpmu_vm = create_vpmu_vm(guest_code); >> + >> + r = __kvm_has_device_attr(vpmu_vm->vcpu->fd, KVM_ARM_VCPU_PMU_V3_CTRL, >> + KVM_ARM_VCPU_PMU_V3_FILTER); >> + >> + destroy_vpmu_vm(vpmu_vm); >> + return !r; >> +} > > TBH, I don't really care much about the test probing for the event > filter UAPI. It has been upstream for a while, and if folks are trying > to run selftests at HEAD on an old kernel then that's their business. > > The other prerequisites make more sense since they actually check if HW > features are present. > >> +static bool host_pmu_supports_events(void) >> +{ >> + vpmu_vm = create_vpmu_vm(guest_get_pmceid); >> + >> + memset(&supported_pmce, 0, sizeof(supported_pmce)); >> + sync_global_to_guest(vpmu_vm->vm, supported_pmce); >> + run_vcpu(vpmu_vm->vcpu); >> + sync_global_from_guest(vpmu_vm->vm, supported_pmce); >> + destroy_vpmu_vm(vpmu_vm); >> + >> + return supported_pmce.pmceid0 & (BR_RETIRED | INST_RETIRED); >> +} > > This helper says its probing the host PMU, but you're actually firing up a > VM to do it. > > The events supported by a particular PMU instance are readily available > in sysfs. Furthermore, you can tell KVM to select the exact host PMU > instance you probe. > >> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c >> index b3de8fdc555e..76ea03d607f1 100644 >> --- a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c >> +++ b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c >> @@ -7,8 +7,9 @@ >> #include >> #include >> >> -/* Create a VM that has one vCPU with PMUv3 configured. */ >> -struct vpmu_vm *create_vpmu_vm(void *guest_code) >> +struct vpmu_vm *__create_vpmu_vm(void *guest_code, >> + void (*init_pmu)(struct vpmu_vm *vm, void *arg), >> + void *arg) >> { >> struct kvm_vcpu_init init; >> uint8_t pmuver; >> @@ -50,12 +51,21 @@ struct vpmu_vm *create_vpmu_vm(void *guest_code) >> "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver); >> >> /* Initialize vPMU */ >> + if (init_pmu) >> + init_pmu(vpmu_vm, arg); >> + >> vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr); >> vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr); >> >> return vpmu_vm; >> } >> >> +/* Create a VM that has one vCPU with PMUv3 configured. */ >> +struct vpmu_vm *create_vpmu_vm(void *guest_code) >> +{ >> + return __create_vpmu_vm(guest_code, NULL, NULL); >> +} >> + > > Ok. This completely proves my point in the other patch. You already need > to refactor this helper to cram in what you're trying to do. Think of > ways to move the code that is actually common into libraries and leave > the rest to the tests themselves. > > Some slight code duplication isn't the end of the world if it avoids > churning libraries every time someone wants to add a widget. > Eric