static ssize_t msr_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { const u32 __user *tmp = (const u32 __user *)buf; u32 data[2]; u32 reg = *ppos; int cpu = iminor(file->f_path.dentry->d_inode); int err = 0; ssize_t bytes = 0; if (count % 8) return -EINVAL; /* Invalid chunk size */ for (; count; count -= 8) { if (copy_from_user(&data, tmp, 8)) { err = -EFAULT; break; } err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); if (err) break; tmp += 2; bytes += 8; } return bytes ? bytes : err; }
static ssize_t msr_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { const u32 __user *tmp = (const u32 __user *)buf; u32 curdata[2]; u32 data[2]; u32 reg = *ppos; u64 mask; int cpu = iminor(file_inode(file)); int err = 0; ssize_t bytes = 0; struct msr_session_info *myinfo = file->private_data; if (count % 8) return -EINVAL; /* Invalid chunk size */ mask = myinfo->rawio_allowed ? 0xffffffffffffffff : msr_whitelist_writemask(reg); if (!myinfo->rawio_allowed && mask == 0) return -EACCES; for (; count; count -= 8) { if (copy_from_user(&data, tmp, 8)) { err = -EFAULT; break; } if (mask != 0xffffffffffffffff) { err = rdmsr_safe_on_cpu(cpu, reg, &curdata[0], &curdata[1]); if (err) break; *(u64 *)&curdata[0] &= ~mask; *(u64 *)&data[0] &= mask; *(u64 *)&data[0] |= *(u64 *)&curdata[0]; } err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); if (err) break; tmp += 2; bytes += 8; } return bytes ? bytes : err; }
int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue) { # ifdef SUPDRV_LINUX_HAS_SAFE_MSR_API int rc; if (idCpu == NIL_RTCPUID) rc = wrmsr_safe(uMsr, RT_LODWORD(uValue), RT_HIDWORD(uValue)); else if (RTMpIsCpuOnline(idCpu)) rc = wrmsr_safe_on_cpu(idCpu, uMsr, RT_LODWORD(uValue), RT_HIDWORD(uValue)); else return VERR_CPU_OFFLINE; if (rc == 0) return VINF_SUCCESS; return VERR_ACCESS_DENIED; # else return VERR_NOT_SUPPORTED; # endif }