diff options
Diffstat (limited to 'sys/dev/cpuctl/cpuctl.c')
-rw-r--r-- | sys/dev/cpuctl/cpuctl.c | 20 |
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, ®); + 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, ®); + 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); } |