Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Mario Limonciello <mario.limonciello@amd.com>
Cc: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>,
	Shuah Khan <shuah@kernel.org>,
	 Shuah Khan <skhan@linuxfoundation.org>,
	linux-kselftest@vger.kernel.org,
	 Hans de Goede <hansg@kernel.org>,
	platform-driver-x86@vger.kernel.org,  Yijun.Shen@Dell.com,
	Sanket.Goswami@amd.com
Subject: Re: [PATCH v3 6/7] platform/x86/amd/pmf: Introduce AMD PMF testing tool for driver metrics and features
Date: Thu, 26 Mar 2026 12:20:53 +0200 (EET)	[thread overview]
Message-ID: <069b8a6b-f166-5d5a-8882-b33c9d2f4e8c@linux.intel.com> (raw)
In-Reply-To: <b750f712-7504-4862-b099-aca70550f10c@amd.com>

[-- Attachment #1: Type: text/plain, Size: 11536 bytes --]

On Wed, 25 Mar 2026, Mario Limonciello wrote:
> On 3/25/26 08:54, Ilpo Järvinen wrote:
> > + Selftest people.
> > 
> > On Sun, 1 Mar 2026, Shyam Sundar S K wrote:
> > 
> > > This tool leverages amd-pmf ioctls exposed via the util layer, allowing
> > > validation of its newly integrated util layer and /dev/amdpmf_interface.
> > > It includes a user-space test application, test_pmf, designed to interact
> > > with the PMF driver and retrieve relevant metrics for the testing and
> > > analysis.
> > > 
> > > It provides definitions for test metrics, feature IDs, and device states,
> > > and includes tests for various AMD PMF metrics such as power source, skin
> > > temperature, battery state, and custom BIOS inputs/outputs. It also
> > > enables the testing of PMF metrics data and feature support reporting.
> > > 
> > > Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
> > > Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
> > > Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
> > > ---
> > >   tools/testing/selftests/Makefile              |   1 +
> > >   .../drivers/platform/x86/amd/pmf/Makefile     |   8 +
> > >   .../drivers/platform/x86/amd/pmf/test_pmf.c   | 243 ++++++++++++++++++
> > >   3 files changed, 252 insertions(+)
> > >   create mode 100644
> > > tools/testing/selftests/drivers/platform/x86/amd/pmf/Makefile
> > >   create mode 100644
> > > tools/testing/selftests/drivers/platform/x86/amd/pmf/test_pmf.c
> > 
> > Please Cc also selftest people in the next version submission! Maube you
> > should also check why your patch sending process did not capture those
> > receipient for you.
> > 
> > To me it looks this "tool" doesn't really perform a selftest the way I've
> > understood "selftests" work. That is, it doesn't have notion of Pass/Fail
> > at all AFAICT. I'm not sure if there are other selftests like this but
> > hopefully the selftest people know.
> 
> For a similar "tool" I have it outside of selftests:
> 
> linux/tools/crypto/ccp
> 
> Ilpo,
> 
> Maybe we want a directory structure like this?
> 
> tools/platform/x86/amd

At least to me it looks better than placing a non-selftest tool under 
selftests/.

-- 
 i.

> > > diff --git a/tools/testing/selftests/Makefile
> > > b/tools/testing/selftests/Makefile
> > > index 450f13ba4cca..d850fb09eeb9 100644
> > > --- a/tools/testing/selftests/Makefile
> > > +++ b/tools/testing/selftests/Makefile
> > > @@ -26,6 +26,7 @@ TARGETS += drivers/net/netconsole
> > >   TARGETS += drivers/net/team
> > >   TARGETS += drivers/net/virtio_net
> > >   TARGETS += drivers/platform/x86/intel/ifs
> > > +TARGETS += drivers/platform/x86/amd/pmf
> > >   TARGETS += dt
> > >   TARGETS += efivarfs
> > >   TARGETS += exec
> > > diff --git a/tools/testing/selftests/drivers/platform/x86/amd/pmf/Makefile
> > > b/tools/testing/selftests/drivers/platform/x86/amd/pmf/Makefile
> > > new file mode 100644
> > > index 000000000000..876424941e83
> > > --- /dev/null
> > > +++ b/tools/testing/selftests/drivers/platform/x86/amd/pmf/Makefile
> > > @@ -0,0 +1,8 @@
> > > +# SPDX-License-Identifier: GPL-2.0-or-later
> > > +CFLAGS += $(KHDR_INCLUDES)
> > > +
> > > +TEST_GEN_PROGS := test_pmf
> > > +
> > > +top_srcdir ?=../../../../..
> > > +
> > > +include ../../../../../lib.mk
> > > diff --git
> > > a/tools/testing/selftests/drivers/platform/x86/amd/pmf/test_pmf.c
> > > b/tools/testing/selftests/drivers/platform/x86/amd/pmf/test_pmf.c
> > > new file mode 100644
> > > index 000000000000..a040ef01ba90
> > > --- /dev/null
> > > +++ b/tools/testing/selftests/drivers/platform/x86/amd/pmf/test_pmf.c
> > > @@ -0,0 +1,243 @@
> > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > +/*
> > > + * AMD Platform Management Framework Test Tool
> > > + *
> > > + * Copyright (c) 2026, Advanced Micro Devices, Inc.
> > > + * All Rights Reserved.
> > > + *
> > > + * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
> > > + *	    Sanket Goswami <Sanket.Goswami@amd.com>
> > > + */
> > > +
> > > +#include <errno.h>
> > > +#include <fcntl.h>
> > > +#include <inttypes.h>
> > > +#include <stdbool.h>
> > > +#include <stdint.h>
> > > +#include <stdio.h>
> > > +#include <string.h>
> > > +#include <sys/ioctl.h>
> > > +#include <unistd.h>
> > > +#include <linux/amd-pmf.h>
> > > +
> > > +#include "../../../../../kselftest.h"
> > > +
> > > +#define DEVICE_NODE		"/dev/amdpmf_interface"
> > > +
> > > +static int pmf_open_device(void)
> > > +{
> > > +	int fd;
> > > +
> > > +	fd = open(DEVICE_NODE, O_RDONLY);
> > > +	if (fd < 0)
> > > +		fprintf(stderr, "opening PMF Device Node failed: %s\n",
> > > strerror(errno));
> > > +
> > > +	return fd;
> > > +}
> > > +
> > > +/* Helper to run IOCTL_PMF_POPULATE_DATA for one control code and return
> > > 0 on success. */
> > 
> > Reflow this comment to 80 chars.
> > 
> > > +static int pmf_get_fd(int fd, enum pmf_ioctl_id code, struct
> > > amd_pmf_ioctl_info *out)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > 
> > = {}; should be enough to initialize to default values.
> > 
> > > +	int ret;
> > > +
> > > +	if (!out)
> > > +		return -EINVAL;
> > > +
> > > +	info.control_code = code;
> > > +
> > > +	ret = ioctl(fd, IOCTL_PMF_POPULATE_DATA, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	*out = info;
> > > +	return 0;
> > > +}
> > > +
> > > +static int pmf_get_data(enum pmf_ioctl_id code, struct amd_pmf_ioctl_info
> > > *out)
> > > +{
> > > +	int fd, ret;
> > > +
> > > +	fd = pmf_open_device();
> > > +	if (fd < 0)
> > > +		return fd;
> > > +
> > > +	ret = pmf_get_fd(fd, code, out);
> > > +
> > > +	close(fd);
> > > +	return ret;
> > > +}
> > > +
> > > +static int pmf_get_feature_status(unsigned int code)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > > +	int ret;
> > > +
> > > +	ret = pmf_get_data(code, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	switch (code) {
> > > +	case IOCTL_FEATURE_AUTO_MODE:
> > > +		printf("Auto Mode: %-24s\n", info.feature_supported ? "Yes" :
> > > "No");
> > > +		break;
> > > +	case IOCTL_FEATURE_STATIC_POWER_SLIDER:
> > > +		printf("Static Power Slider: %-24s\n", info.feature_supported
> > > ? "Yes" : "No");
> > > +		break;
> > > +	case IOCTL_FEATURE_POLICY_BUILDER:
> > > +		printf("Policy Builder: %s\n", info.feature_supported ? "Yes"
> > > : "No");
> > > +		break;
> > > +	case IOCTL_FEATURE_DYNAMIC_POWER_SLIDER_AC:
> > > +		printf("Dynamic Power Slider AC: %s\n", info.feature_supported
> > > ? "Yes" : "No");
> > > +		break;
> > > +	case IOCTL_FEATURE_DYNAMIC_POWER_SLIDER_DC:
> > > +		printf("Dynamic Power Slider DC: %s\n", info.feature_supported
> > > ? "Yes" : "No");
> > > +		break;
> > > +	default:
> > > +		return -1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int pmf_get_device_state(unsigned int code)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > > +	int ret;
> > > +
> > > +	ret = pmf_get_data(code, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	switch (code) {
> > > +	case IOCTL_PLATFORM_TYPE:
> > > +		printf("Platform Type: %s\n", platform_type_as_str(info.val));
> > > +		break;
> > > +	case IOCTL_LAPTOP_PLACEMENT:
> > > +		printf("Laptop placement: %s\n",
> > > laptop_placement_as_str(info.val));
> > > +		break;
> > > +	case IOCTL_LID_STATE:
> > > +		printf("Lid State: %s\n", info.val ? "Close" : "Open");
> > > +		break;
> > > +	case IOCTL_USER_PRESENCE:
> > > +		printf("User Presence: %s\n", info.val ? "Present" : "Away");
> > > +		break;
> > > +	default:
> > > +		return -1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int pmf_get_custom_bios_input(unsigned int code)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > > +	int idx, ret;
> > > +
> > > +	ret = pmf_get_data(code, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	switch (code) {
> > > +	case IOCTL_BIOS_INPUT_1 ... IOCTL_BIOS_INPUT_10:
> > > +		idx = amd_pmf_get_bios_idx(code);
> > > +		printf("Custom BIOS input%u: %lu\n", idx + 1,
> > > (int64_t)info.val);
> > 
> > %lu is for printing unsigned long, not int64_t.
> > 
> > > +		break;
> > > +	default:
> > > +		return -1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int pmf_get_bios_output(unsigned int code)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > > +	int idx, ret;
> > > +
> > > +	ret = pmf_get_data(code, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	switch (code) {
> > > +	case IOCTL_BIOS_OUTPUT_1 ... IOCTL_BIOS_OUTPUT_10:
> > > +		idx = amd_pmf_get_bios_idx(code);
> > > +		printf("BIOS output%u: %lu\n", idx + 1, (int64_t)info.val);
> > > +		break;
> > > +	default:
> > > +		return -1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int pmf_get_misc_info(unsigned int code)
> > > +{
> > > +	struct amd_pmf_ioctl_info info = {0};
> > > +	int ret;
> > > +
> > > +	ret = pmf_get_data(code, &info);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	switch (code) {
> > > +	case IOCTL_POWER_SLIDER_POSITION:
> > > +		printf("Slider Position: %s\n", ta_slider_as_str(info.val));
> > > +		break;
> > > +	case IOCTL_SKIN_TEMP:
> > > +		printf("Skin Temperature: %lu\n", (int64_t)info.val);
> > > +		break;
> > > +	case IOCTL_GFX_WORKLOAD:
> > > +		printf("GFX Busy: %lu\n", (int64_t)info.val);
> > > +		break;
> > > +	case IOCTL_AMBIENT_LIGHT:
> > > +		printf("Ambient Light: %ld\n", (int64_t)info.val);
> > > +		break;
> > > +	case IOCTL_AVG_C0_RES:
> > > +		printf("Avg C0 Residency: %lu\n", (int64_t)info.val);
> > > +		break;
> > > +	case IOCTL_MAX_C0_RES:
> > > +		printf("Max C0 Residency: %lu\n", (int64_t)info.val);
> > > +		break;
> > > +	case IOCTL_SOCKET_POWER:
> > > +		printf("Socket Power: %lu\n", (int64_t)info.val);
> > 
> > Please think the printf formatting strings and types through.
> > 
> > > +		break;
> > > +	default:
> > > +		return -1;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +int main(void)
> > > +{
> > > +	unsigned int idx;
> > > +
> > > +	printf("Feature Name          Supported\n");
> > > +	printf("---------------------------------\n");
> > > +	for (idx = IOCTL_FEATURE_AUTO_MODE; idx <=
> > > IOCTL_FEATURE_DYNAMIC_POWER_SLIDER_DC; idx++)
> > > +		pmf_get_feature_status(idx);
> > > +
> > > +	printf("\nDevice State\n---------------\n");
> > > +	for (idx = IOCTL_PLATFORM_TYPE; idx <= IOCTL_USER_PRESENCE; idx++)
> > > +		pmf_get_device_state(idx);
> > > +
> > > +	printf("\nCustom BIOS Inputs\n-------------------\n");
> > > +	for (idx = IOCTL_BIOS_INPUT_1; idx <= IOCTL_BIOS_INPUT_10; idx++)
> > > +		pmf_get_custom_bios_input(idx);
> > > +
> > > +	printf("\nBIOS Outputs\n--------------\n");
> > > +	for (idx = IOCTL_BIOS_OUTPUT_1; idx <= IOCTL_BIOS_OUTPUT_10; idx++)
> > > +		pmf_get_bios_output(idx);
> > > +
> > > +	printf("\nMisc\n------\n");
> > > +	pmf_get_misc_info(IOCTL_SKIN_TEMP);
> > > +	pmf_get_misc_info(IOCTL_GFX_WORKLOAD);
> > > +	pmf_get_misc_info(IOCTL_AMBIENT_LIGHT);
> > > +	pmf_get_misc_info(IOCTL_AVG_C0_RES);
> > > +	pmf_get_misc_info(IOCTL_MAX_C0_RES);
> > > +	pmf_get_misc_info(IOCTL_SOCKET_POWER);
> > > +	pmf_get_misc_info(IOCTL_POWER_SLIDER_POSITION);
> > > +
> > > +	return 0;
> > > +}
> > > 
> > 
> 

  reply	other threads:[~2026-03-26 10:21 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260301131124.1370565-1-Shyam-sundar.S-k@amd.com>
     [not found] ` <20260301131124.1370565-7-Shyam-sundar.S-k@amd.com>
2026-03-25 13:54   ` [PATCH v3 6/7] platform/x86/amd/pmf: Introduce AMD PMF testing tool for driver metrics and features Ilpo Järvinen
2026-03-25 15:07     ` Mario Limonciello
2026-03-26 10:20       ` Ilpo Järvinen [this message]
2026-03-30 11:42         ` Shyam Sundar S K

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=069b8a6b-f166-5d5a-8882-b33c9d2f4e8c@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=Sanket.Goswami@amd.com \
    --cc=Shyam-sundar.S-k@amd.com \
    --cc=Yijun.Shen@Dell.com \
    --cc=hansg@kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mario.limonciello@amd.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox