diff options
author | Shuo Liu <shuo.a.liu@intel.com> | 2021-02-07 11:10:29 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-02-09 10:58:19 +0100 |
commit | 2ad2aaee1bc9568d0c146463483d2c926ef20055 (patch) | |
tree | 7dd2b2c147724a3dd4237f7d06b2a9f0774115eb /drivers/virt/acrn/hsm.c | |
parent | 9c5137aedd112f78a968bdd2325de2ea06df46c0 (diff) | |
download | linux-2ad2aaee1bc9568d0c146463483d2c926ef20055.tar.bz2 |
virt: acrn: Introduce an ioctl to set vCPU registers state
A virtual CPU of User VM has different context due to the different
registers state. ACRN userspace needs to set the virtual CPU
registers state (e.g. giving a initial registers state to a virtual
BSP of a User VM).
HSM provides an ioctl ACRN_IOCTL_SET_VCPU_REGS to do the virtual CPU
registers state setting. The ioctl passes the registers state from ACRN
userspace to the hypervisor directly.
Cc: Zhi Wang <zhi.a.wang@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: Yu Wang <yu1.wang@intel.com>
Cc: Reinette Chatre <reinette.chatre@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Shuo Liu <shuo.a.liu@intel.com>
Link: https://lore.kernel.org/r/20210207031040.49576-8-shuo.a.liu@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/virt/acrn/hsm.c')
-rw-r--r-- | drivers/virt/acrn/hsm.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c index 5fd933471683..ee5cc7413239 100644 --- a/drivers/virt/acrn/hsm.c +++ b/drivers/virt/acrn/hsm.c @@ -9,6 +9,7 @@ * Yakui Zhao <yakui.zhao@intel.com> */ +#include <linux/io.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> @@ -46,7 +47,8 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, { struct acrn_vm *vm = filp->private_data; struct acrn_vm_creation *vm_param; - int ret = 0; + struct acrn_vcpu_regs *cpu_regs; + int i, ret = 0; if (vm->vmid == ACRN_INVALID_VMID && cmd != ACRN_IOCTL_CREATE_VM) { dev_dbg(acrn_dev.this_device, @@ -100,6 +102,36 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, case ACRN_IOCTL_DESTROY_VM: ret = acrn_vm_destroy(vm); break; + case ACRN_IOCTL_SET_VCPU_REGS: + cpu_regs = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_vcpu_regs)); + if (IS_ERR(cpu_regs)) + return PTR_ERR(cpu_regs); + + for (i = 0; i < ARRAY_SIZE(cpu_regs->reserved); i++) + if (cpu_regs->reserved[i]) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(cpu_regs->vcpu_regs.reserved_32); i++) + if (cpu_regs->vcpu_regs.reserved_32[i]) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(cpu_regs->vcpu_regs.reserved_64); i++) + if (cpu_regs->vcpu_regs.reserved_64[i]) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(cpu_regs->vcpu_regs.gdt.reserved); i++) + if (cpu_regs->vcpu_regs.gdt.reserved[i] | + cpu_regs->vcpu_regs.idt.reserved[i]) + return -EINVAL; + + ret = hcall_set_vcpu_regs(vm->vmid, virt_to_phys(cpu_regs)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to set regs state of VM%u!\n", + vm->vmid); + kfree(cpu_regs); + break; default: dev_dbg(acrn_dev.this_device, "Unknown IOCTL 0x%x!\n", cmd); ret = -ENOTTY; |