From d9fd51a67551eaf32e204586545e63d1c33d2167 Mon Sep 17 00:00:00 2001 From: Barry Rountree Date: Mon, 23 Sep 2024 09:06:41 -0700 Subject: [PATCH] Toss4 cleanup (#166) * Replaces #define around msr_devnode with _Generic The type of (((struct class *)0)->devnode) has changed at least twice in the mainline kernel. Coding based on mainline kernel versions has repeatedly run into the problem of distros backporting features to older kernels. Solved here using _Generic and multiple function definitions. * Continuing to versionproof use of devnode. * Fixes more nodedev issues. * Last of the devnode issues. * Fixes copyright year and formatting issues. Per Stephanie's comments. * minor code formatting - add new lines between function definitions - use 4 instead of 8 spaces for indents --------- Co-authored-by: Barry Co-authored-by: Stephanie Brink --- msr_allowlist.c | 30 ++++++++++++++++++++---------- msr_batch.c | 29 +++++++++++++++++++---------- msr_entry.c | 35 +++++++++++++++++++++++++---------- msr_version.c | 37 +++++++++++++++++++++++++++---------- 4 files changed, 91 insertions(+), 40 deletions(-) diff --git a/msr_allowlist.c b/msr_allowlist.c index fb5936a..ea1abbc 100644 --- a/msr_allowlist.c +++ b/msr_allowlist.c @@ -361,15 +361,25 @@ static int parse_next_allowlist_entry(char *inbuf, char **nextinbuf, struct allo return *nextinbuf - inbuf; } -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39) -static char *msr_allowlist_nodename(struct device *dev, mode_t *mode) -#else -#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,2,0) -static char *msr_allowlist_nodename(struct device *dev, umode_t *mode) -#else -static char *msr_allowlist_nodename(const struct device *dev, umode_t *mode) -#endif -#endif + +#define msr_allowlist_nodename_selector _Generic(\ + (((struct class *)0)->devnode),\ + char* (*) (struct device *, mode_t *) : msr_allowlist_nodename1,\ + char* (*) (struct device *, umode_t *) : msr_allowlist_nodename2,\ + char* (*) (const struct device *, umode_t *) : msr_allowlist_nodename3 \ + ) + +static char *msr_allowlist_nodename1(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/msr_allowlist"); +} + +static char *msr_allowlist_nodename2(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/msr_allowlist"); +} + +static char *msr_allowlist_nodename3(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cpu/msr_allowlist"); } @@ -429,7 +439,7 @@ int msr_allowlist_init(int *majordev) } cdev_class_created = 1; - cdev_class->devnode = msr_allowlist_nodename; + cdev_class->devnode = msr_allowlist_nodename_selector; dev = device_create(cdev_class, NULL, MKDEV(*majordev, 0), NULL, "msr_allowlist"); if (IS_ERR(dev)) diff --git a/msr_batch.c b/msr_batch.c index dd46c27..3fc4082 100644 --- a/msr_batch.c +++ b/msr_batch.c @@ -179,15 +179,24 @@ void msrbatch_cleanup(int majordev) } } -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39) -static char *msrbatch_nodename(struct device *dev, mode_t *mode) -#else -#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,2,0) -static char *msrbatch_nodename(struct device *dev, umode_t *mode) -#else -static char *msrbatch_nodename(const struct device *dev, umode_t *mode) -#endif -#endif +#define msrbatch_nodename_selector _Generic(\ + (((struct class *)0)->devnode),\ + char* (*) ( struct device *, mode_t *) : msrbatch_nodename1,\ + char* (*) ( struct device *, umode_t *) : msrbatch_nodename2,\ + char* (*) (const struct device *, umode_t *) : msrbatch_nodename3 \ + ) + +static char *msrbatch_nodename1(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/msr_batch"); +} + +static char *msrbatch_nodename2(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/msr_batch"); +} + +static char *msrbatch_nodename3(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cpu/msr_batch"); } @@ -223,7 +232,7 @@ int msrbatch_init(int *majordev) } cdev_class_created = 1; - cdev_class->devnode = msrbatch_nodename; + cdev_class->devnode = msrbatch_nodename_selector; dev = device_create(cdev_class, NULL, MKDEV(*majordev, 0), NULL, "msr_batch"); if (IS_ERR(dev)) diff --git a/msr_entry.c b/msr_entry.c index 9e16803..94e8d86 100644 --- a/msr_entry.c +++ b/msr_entry.c @@ -254,15 +254,30 @@ static struct notifier_block __refdata msr_class_cpu_notifier = }; #endif -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39) -static char *msr_devnode(struct device *dev, mode_t *mode) -#else -#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,2,0) -static char *msr_devnode(struct device *dev, umode_t *mode) -#else -static char *msr_devnode(const struct device *dev, umode_t *mode) -#endif -#endif +/* The type of (((struct class *)0)->devnode) has changed at least + * twice in the mainline linux kernel. Trying to pin these changes + * to specific mainline kernel versions runs into the problem of + * distros backporting features to older kernels. Instead, we are + * now keying off of the change in the parameter types.*/ + +#define msr_devnode_selector _Generic(\ + (((struct class *)0)->devnode),\ + char * (*) (struct device *, mode_t *) : msr_devnode1,\ + char * (*) (struct device *, umode_t *) : msr_devnode2,\ + char * (*) (const struct device *, umode_t *) : msr_devnode3\ + ) + +static char *msr_devnode1(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/%u/msr_safe", MINOR(dev->devt)); +} + +static char *msr_devnode2(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "cpu/%u/msr_safe", MINOR(dev->devt)); +} + +static char *msr_devnode3(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "cpu/%u/msr_safe", MINOR(dev->devt)); } @@ -329,7 +344,7 @@ static int __init msr_init(void) err = PTR_ERR(msr_class); goto out_chrdev; } - msr_class->devnode = msr_devnode; + msr_class->devnode = msr_devnode_selector; #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) i = 0; diff --git a/msr_version.c b/msr_version.c index bee1832..13cc451 100644 --- a/msr_version.c +++ b/msr_version.c @@ -52,15 +52,32 @@ static const struct file_operations fops = .open = open_version }; -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39) -static char *msr_version_nodename(struct device *dev, mode_t *mode) -#else -#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,2,0) -static char *msr_version_nodename(struct device *dev, umode_t *mode) -#else -static char *msr_version_nodename(const struct device *dev, umode_t *mode) -#endif -#endif +#define msr_version_nodename_selector _Generic(\ + (((struct class *)0)->devnode),\ + char * (*) ( struct device *, mode_t *) : msr_version_nodename1,\ + char * (*) ( struct device *, umode_t *) : msr_version_nodename2,\ + char * (*) (const struct device *, umode_t *) : msr_version_nodename3 \ + ) + +static char *msr_version_nodename1(struct device *dev, mode_t *mode) +{ + if (mode) + { + *mode = 0400; // read-only + } + return kasprintf(GFP_KERNEL, "cpu/msr_safe_version"); +} + +static char *msr_version_nodename2(struct device *dev, umode_t *mode) +{ + if (mode) + { + *mode = 0400; // read-only + } + return kasprintf(GFP_KERNEL, "cpu/msr_safe_version"); +} + +static char *msr_version_nodename3(const struct device *dev, umode_t *mode) { if (mode) { @@ -122,7 +139,7 @@ int msr_version_init(int *majordev) } cdev_class_created = 1; - cdev_class->devnode = msr_version_nodename; + cdev_class->devnode = msr_version_nodename_selector; dev = device_create(cdev_class, NULL, MKDEV(*majordev, 0), NULL, "msr_safe_version"); if (IS_ERR(dev))