summaryrefslogtreecommitdiffstats
path: root/sys/dev/cpuctl/cpuctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cpuctl/cpuctl.c')
-rw-r--r--sys/dev/cpuctl/cpuctl.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c
index f325797..c3a2434 100644
--- a/sys/dev/cpuctl/cpuctl.c
+++ b/sys/dev/cpuctl/cpuctl.c
@@ -158,6 +158,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
case CPUCTL_RDMSR:
ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
break;
+ case CPUCTL_MSRSBIT:
+ case CPUCTL_MSRCBIT:
case CPUCTL_WRMSR:
ret = priv_check(td, PRIV_CPUCTL_WRMSR);
if (ret != 0)
@@ -211,6 +213,7 @@ cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
static int
cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td)
{
+ uint64_t reg;
int is_bound = 0;
int oldcpu;
int ret;
@@ -230,9 +233,22 @@ cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td)
if (cmd == CPUCTL_RDMSR) {
data->data = 0;
ret = rdmsr_safe(data->msr, &data->data);
- } else {
+ } else if (cmd == CPUCTL_WRMSR) {
ret = wrmsr_safe(data->msr, data->data);
- }
+ } else if (cmd == CPUCTL_MSRSBIT) {
+ critical_enter();
+ ret = rdmsr_safe(data->msr, &reg);
+ if (ret == 0)
+ ret = wrmsr_safe(data->msr, reg | data->data);
+ critical_exit();
+ } else if (cmd == CPUCTL_MSRCBIT) {
+ critical_enter();
+ ret = rdmsr_safe(data->msr, &reg);
+ if (ret == 0)
+ ret = wrmsr_safe(data->msr, reg & ~data->data);
+ critical_exit();
+ } else
+ panic("[cpuctl,%d]: unknown operation requested: %lu", __LINE__, cmd);
restore_cpu(oldcpu, is_bound, td);
return (ret);
}
OpenPOWER on IntegriCloud