Skip to content

Commit

Permalink
Performs version checking.
Browse files Browse the repository at this point in the history
README.md
Describes new error (ENOPROTOOP) that results from a mismatch
between the loaded kernel module and what's in the batch request.

examples/example.c
Updated to use versioning.

msr_batch.c
Checks for correct version as part of batch request parsing.

msr_version.h
Bumped version to 2.0.0.

Tested on serif.
  • Loading branch information
rountree committed Sep 13, 2024
1 parent 2deb36f commit 31b653b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 28 deletions.
44 changes: 25 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ unheard-of.

Starting in version 2.0.0, the __version__ field will be
compared to the version of the loaded kernel module with a mismatch
resulting in an error. Earlier versions do not check this field.
in the major version number resulting in an error.
Earlier versions do not check this field.

Each op is contained in a __struct msr_batch_op__:

Expand Down Expand Up @@ -292,17 +293,11 @@ Requested virtual CPU does not exist or is offline.
### /dev/cpu/msr_batch

### **ioctl(2)**
Verifying the batch request can result in the following errors.

All of the operations in the batch will be executed. Each operation may result
in an __EIO__, __ENXIO__, __EACCES__, or __EROFS__ error, which will be
recorded in the __msr_batch_op__ struct. If any operation caused an error, the
first such error becomes the return value for **ioctl(2)**.

__E2BIG__
Kernel unable to allocate memory to hold the array of operations.

__EACCES__
An individual operation requested an MSR that is not present in the allowlist.
__ENOTTY__
Invalid ioctl command. As of this writing the only ioctl command
supported on this device is __X86_IOC_MSR_BATCH__, defined in __msr_safe.h__.

__EBADF__
The __msr_batch__ file was not opened for reading.
Expand All @@ -311,7 +306,25 @@ __EFAULT__
Kernel **copy_from_user()** or **copy_to_user()** failed.

__EINVAL__
Number of requested batch operations is <=0.
Number of requested batch operations is 0.

__ENOPROTOOPT__
There is a mismatch between the major version number of the currently-loaded
msr-safe kernel module and the version number requested by the batch struct.

__E2BIG__
Kernel unable to allocate memory to hold the array of operations.

__ENOMEM__
Kernel unable to allocate memory to hold the results of __zalloc_cpumask_var()__.

If all is well, all of the operations in the batch will be executed. If an
individual operation results in one of the following errors, the error will
be recorded in its __msr_batch_op__ struct. The first of these errors will
become the return value for **ioctl(2)**.

__EACCES__
An individual operation requested an MSR that is not present in the allowlist.

__EIO__
A general protection fault occurred. On Intel processors this
Expand All @@ -320,13 +333,6 @@ attempting to access a non-existent or reserved MSR address, c) writing 1-bits
to a reserved area of an MSR, d) writing a non-canonical address to MSRs that
take memory addresses, or e) writing to MSR bits that are marked as read-only.

__ENOMEM__
Kernel unable to allocate memory to hold the results of __zalloc_cpumask_var()__.

__ENOTTY__
Invalid ioctl command. As of this writing the only ioctl command
supported on this device is __X86_IOC_MSR_BATCH__, defined in __msr_safe.h__.

__ENXIO__
An individual operation requested a virtual CPU does not exist or is offline.

Expand Down
14 changes: 8 additions & 6 deletions examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
#include <stdlib.h> // exit(3)
#include <sys/ioctl.h> // ioctl(2)

#include "../msr_safe.h" // batch data structs
#include "../msr_safe.h" // batch data structs
#include "../msr_version.h" // MSR_SAFE_VERSION_u32

#define MSR_MPERF 0xE7

char const *const allowlist = "0xE7 0xFFFFFFFFFFFFFFFF\n"; // MPERF

static uint8_t const nCPUs = 32;
static uint8_t const nCPUs = 16;

void set_allowlist()
{
Expand Down Expand Up @@ -74,7 +75,7 @@ void measure_serial_latency()

// Show results
printf("Serial cycles from first write to last read:"
"%"PRIu64" (on %"PRIu8" CPUs)\n",
"%9"PRIu64" (on %"PRIu8" CPUs)\n",
data[nCPUs - 1], nCPUs);
}

Expand All @@ -95,7 +96,8 @@ void measure_batch_latency()
r_ops[i].msr = w_ops[i].msr = MSR_MPERF;
w_ops[i].msrdata = 0;
}
rbatch.numops = wbatch.numops = nCPUs;
rbatch.numops = wbatch.numops = nCPUs;
rbatch.version = wbatch.version = MSR_SAFE_VERSION_u32;
rbatch.ops = r_ops;
wbatch.ops = w_ops;

Expand All @@ -104,8 +106,8 @@ void measure_batch_latency()
rc = ioctl(fd, X86_IOC_MSR_BATCH, &rbatch);
assert(-1 != rc);

printf("Batch cycles from first write to last read:"
"%llu (on %"PRIu8" CPUs)\n",
printf("Batch cycles from first write to last read: "
"%9llu (on %"PRIu8" CPUs)\n",
r_ops[nCPUs - 1].msrdata, nCPUs);
}

Expand Down
11 changes: 10 additions & 1 deletion msr_batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "msr_safe.h"
#include "msr-smp.h"
#include "msr_allowlist.h"
#include "msr_version.h"

static struct class *cdev_class;
static char cdev_created;
Expand Down Expand Up @@ -102,12 +103,20 @@ static long msrbatch_ioctl(struct file *f, unsigned int ioc, unsigned long arg)
return -EFAULT;
}

if (koa.numops <= 0)
if (koa.numops == 0)
{
pr_debug("Invalid # of ops %d\n", koa.numops);
return -EINVAL;
}

if ( ((koa.version >> 16) & 0xff) != MSR_SAFE_VERSION_MAJOR ){
pr_debug("Version mismatch: loaded is %d, requested is %d\n",
MSR_SAFE_VERSION_MAJOR,
(koa.version >> 16) & 0xff
);
return -ENOPROTOOPT;
}

uops = koa.ops;

koa.ops = kmalloc_array(koa.numops, sizeof(*koa.ops), GFP_KERNEL);
Expand Down
4 changes: 2 additions & 2 deletions msr_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ int msr_version_init(int *majordev);

void msr_version_cleanup(int majordev);

#define MSR_SAFE_VERSION_MAJOR 1
#define MSR_SAFE_VERSION_MINOR 8
#define MSR_SAFE_VERSION_MAJOR 2
#define MSR_SAFE_VERSION_MINOR 0
#define MSR_SAFE_VERSION_PATCH 0

#define MSR_SAFE_VERSION_u32 ( \
Expand Down

0 comments on commit 31b653b

Please sign in to comment.