|
42 | 42 | #define HAX_VM_DEVFS_FMT "hax_vm/vm%02d" |
43 | 43 | #define HAX_VCPU_DEVFS_FMT "hax_vm%02d/vcpu%02d" |
44 | 44 |
|
| 45 | +#define load_user_data(dest, src, body_len, body_max, arg_t, body_t) \ |
| 46 | + arg_t __user *from = (arg_t __user *)(*(arg_t **)(src)); \ |
| 47 | + size_t size; \ |
| 48 | + arg_t header; \ |
| 49 | + (dest) = NULL; \ |
| 50 | + if (copy_from_user(&header, from, sizeof(arg_t))) { \ |
| 51 | + hax_log(HAX_LOGE, "%s: argument header read error.\n", __func__); \ |
| 52 | + ret = -EFAULT; \ |
| 53 | + break; \ |
| 54 | + } \ |
| 55 | + if (header.body_len > (body_max)) { \ |
| 56 | + hax_log(HAX_LOGW, "%s: %d exceeds argument body maximum %d.\n", \ |
| 57 | + __func__, header.body_len, (body_max)); \ |
| 58 | + ret = -E2BIG; \ |
| 59 | + break; \ |
| 60 | + } \ |
| 61 | + size = sizeof(arg_t) + header.body_len * sizeof(body_t); \ |
| 62 | + (dest) = hax_vmalloc(size, HAX_MEM_NONPAGE); \ |
| 63 | + if ((dest) == NULL) { \ |
| 64 | + hax_log(HAX_LOGE, "%s: failed to allocate memory.\n", __func__); \ |
| 65 | + ret = -ENOMEM; \ |
| 66 | + break; \ |
| 67 | + } \ |
| 68 | + if (copy_from_user((dest), from, size)) { \ |
| 69 | + hax_log(HAX_LOGE, "%s: argument read error.\n", __func__); \ |
| 70 | + unload_user_data(dest); \ |
| 71 | + ret = -EFAULT; \ |
| 72 | + break; \ |
| 73 | + } |
| 74 | + |
| 75 | +#define unload_user_data(dest) \ |
| 76 | + if ((dest) != NULL) \ |
| 77 | + hax_vfree((dest), size); |
| 78 | + |
45 | 79 | typedef struct hax_vm_linux_t { |
46 | 80 | struct vm_t *cvm; |
47 | 81 | int id; |
@@ -445,6 +479,14 @@ static long hax_vcpu_ioctl(struct file *filp, unsigned int cmd, |
445 | 479 | vcpu_debug(cvcpu, &hax_debug); |
446 | 480 | break; |
447 | 481 | } |
| 482 | + case HAX_VCPU_IOCTL_SET_CPUID: { |
| 483 | + struct hax_cpuid *cpuid; |
| 484 | + load_user_data(cpuid, argp, total, HAX_MAX_CPUID_ENTRIES, hax_cpuid, |
| 485 | + hax_cpuid_entry); |
| 486 | + ret = vcpu_set_cpuid(cvcpu, cpuid); |
| 487 | + unload_user_data(cpuid); |
| 488 | + break; |
| 489 | + } |
448 | 490 | default: |
449 | 491 | // TODO: Print information about the process that sent the ioctl. |
450 | 492 | hax_log(HAX_LOGE, "Unknown VCPU IOCTL 0x%lx\n", cmd); |
|
0 commit comments