149 lines · 3.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <linux/limits.h> #include <libvfio.h> #define readlink_safe(_path, _buf) ({					\	int __ret;							\									\	_Static_assert(!__builtin_types_compatible_p(			\		__typeof__(_buf), char *),				\	    "readlink_safe: _buf must be an array, not a pointer");	\									\	__ret = readlink(_path, _buf, sizeof(_buf) - 1);		\	if (__ret != -1)						\		_buf[__ret] = 0;					\	__ret;								\}) static void readlink_base(const char *path, const char *data_fmt, void *out_data){	char rl_path[PATH_MAX];	int ret; 	ret = readlink_safe(path, rl_path);	VFIO_ASSERT_NE(ret, -1); 	ret = sscanf(basename(rl_path), data_fmt, out_data);	VFIO_ASSERT_EQ(ret, 1);} static int sysfs_val_get_int(const char *component, const char *name,			     const char *file){	char path[PATH_MAX];	char buf[32];	int ret;	int fd; 	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file);	fd = open(path, O_RDONLY);	if (fd < 0)		return fd; 	VFIO_ASSERT_GT(read(fd, buf, ARRAY_SIZE(buf)), 0);	VFIO_ASSERT_EQ(close(fd), 0); 	errno = 0;	ret = strtol(buf, NULL, 0);	VFIO_ASSERT_EQ(errno, 0, "sysfs path \"%s\" is not an integer: \"%s\"\n", path, buf); 	return ret;} static void sysfs_val_set(const char *component, const char *name,			  const char *file, const char *val){	char path[PATH_MAX];	int fd; 	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file);	VFIO_ASSERT_GT(fd = open(path, O_WRONLY), 0); 	VFIO_ASSERT_EQ(write(fd, val, strlen(val)), strlen(val));	VFIO_ASSERT_EQ(close(fd), 0);} static int sysfs_device_val_get(const char *bdf, const char *file){	return sysfs_val_get_int("devices", bdf, file);} static void sysfs_device_val_set(const char *bdf, const char *file, const char *val){	sysfs_val_set("devices", bdf, file, val);} static void sysfs_device_val_set_int(const char *bdf, const char *file, int val){	char val_str[32]; 	snprintf_assert(val_str, sizeof(val_str), "%d", val);	sysfs_device_val_set(bdf, file, val_str);} int sysfs_sriov_totalvfs_get(const char *bdf){	return sysfs_device_val_get(bdf, "sriov_totalvfs");} int sysfs_sriov_numvfs_get(const char *bdf){	return sysfs_device_val_get(bdf, "sriov_numvfs");} void sysfs_sriov_numvfs_set(const char *bdf, int numvfs){	sysfs_device_val_set_int(bdf, "sriov_numvfs", numvfs);} char *sysfs_sriov_vf_bdf_get(const char *pf_bdf, int i){	char path[PATH_MAX];	char *out_vf_bdf; 	/* Fit "0000:00:00.0" */	out_vf_bdf = calloc_assert(16, sizeof(char)); 	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/virtfn%d", pf_bdf, i);	readlink_base(path, "%s", out_vf_bdf); 	return out_vf_bdf;} int sysfs_iommu_group_get(const char *bdf){	char path[PATH_MAX];	int group; 	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/iommu_group", bdf);	readlink_base(path, "%d", &group); 	return group;} char *sysfs_driver_get(const char *bdf){	char driver_path[PATH_MAX];	char path[PATH_MAX];	char *out_driver;	int ret; 	snprintf_assert(path, PATH_MAX, "/sys/bus/pci/devices/%s/driver", bdf);	ret = readlink_safe(path, driver_path);	if (ret == -1) {		if (errno == ENOENT)			return NULL; 		VFIO_FAIL("Failed to read %s\n", path);	} 	out_driver = strdup(basename(driver_path));	VFIO_ASSERT_NOT_NULL(out_driver); 	return out_driver;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t