On Fri  8.Jan'21 at 16:33:22 +0100, Greg Kroah-Hartman wrote:
On Wed, Jan 06, 2021 at 03:50:44PM +0800, shuo.a....@intel.com wrote:
From: Shuo Liu <shuo.a....@intel.com>

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.

Signed-off-by: Shuo Liu <shuo.a....@intel.com>
Reviewed-by: Zhi Wang <zhi.a.w...@intel.com>
Reviewed-by: Reinette Chatre <reinette.cha...@intel.com>
Cc: Zhi Wang <zhi.a.w...@intel.com>
Cc: Zhenyu Wang <zhen...@linux.intel.com>
Cc: Yu Wang <yu1.w...@intel.com>
Cc: Reinette Chatre <reinette.cha...@intel.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/virt/acrn/hsm.c       | 21 ++++++++++-
 drivers/virt/acrn/hypercall.h | 13 +++++++
 include/uapi/linux/acrn.h     | 69 +++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c
index 5fd933471683..2d04ebaa43f8 100644
--- a/drivers/virt/acrn/hsm.c
+++ b/drivers/virt/acrn/hsm.c
@@ -9,6 +9,7 @@
  *     Yakui Zhao <yakui.z...@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,23 @@ 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;
+
+               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;
diff --git a/drivers/virt/acrn/hypercall.h b/drivers/virt/acrn/hypercall.h
index 426b66cadb1f..f29cfae08862 100644
--- a/drivers/virt/acrn/hypercall.h
+++ b/drivers/virt/acrn/hypercall.h
@@ -19,6 +19,7 @@
 #define HC_START_VM                    _HC_ID(HC_ID, HC_ID_VM_BASE + 0x02)
 #define HC_PAUSE_VM                    _HC_ID(HC_ID, HC_ID_VM_BASE + 0x03)
 #define HC_RESET_VM                    _HC_ID(HC_ID, HC_ID_VM_BASE + 0x05)
+#define HC_SET_VCPU_REGS               _HC_ID(HC_ID, HC_ID_VM_BASE + 0x06)

 /**
  * hcall_create_vm() - Create a User VM
@@ -75,4 +76,16 @@ static inline long hcall_reset_vm(u64 vmid)
        return acrn_hypercall1(HC_RESET_VM, vmid);
 }

+/**
+ * hcall_set_vcpu_regs() - Set up registers of virtual CPU of a User VM
+ * @vmid:      User VM ID
+ * @regs_state:        Service VM GPA of registers state
+ *
+ * Return: 0 on success, <0 on failure
+ */
+static inline long hcall_set_vcpu_regs(u64 vmid, u64 regs_state)
+{
+       return acrn_hypercall2(HC_SET_VCPU_REGS, vmid, regs_state);
+}
+
 #endif /* __ACRN_HSM_HYPERCALL_H */
diff --git a/include/uapi/linux/acrn.h b/include/uapi/linux/acrn.h
index e1608b8a50a2..d5d66b93586e 100644
--- a/include/uapi/linux/acrn.h
+++ b/include/uapi/linux/acrn.h
@@ -35,6 +35,73 @@ struct acrn_vm_creation {
        __u64   cpu_affinity;
 };

+struct acrn_gp_regs {
+       __le64  rax;
+       __le64  rcx;
+       __le64  rdx;
+       __le64  rbx;
+       __le64  rsp;
+       __le64  rbp;
+       __le64  rsi;
+       __le64  rdi;
+       __le64  r8;
+       __le64  r9;
+       __le64  r10;
+       __le64  r11;
+       __le64  r12;
+       __le64  r13;
+       __le64  r14;
+       __le64  r15;
+};
+
+struct acrn_descriptor_ptr {
+       __le16  limit;
+       __le64  base;
+       __le16  reserved[3];
+} __attribute__ ((__packed__));
+
+struct acrn_regs {
+       struct acrn_gp_regs             gprs;
+       struct acrn_descriptor_ptr      gdt;
+       struct acrn_descriptor_ptr      idt;
+
+       __le64                          rip;
+       __le64                          cs_base;
+       __le64                          cr0;
+       __le64                          cr4;
+       __le64                          cr3;
+       __le64                          ia32_efer;
+       __le64                          rflags;
+       __le64                          reserved_64[4];
+
+       __le32                          cs_ar;
+       __le32                          cs_limit;
+       __le32                          reserved_32[3];
+
+       __le16                          cs_sel;
+       __le16                          ss_sel;
+       __le16                          ds_sel;
+       __le16                          es_sel;
+       __le16                          fs_sel;
+       __le16                          gs_sel;
+       __le16                          ldt_sel;
+       __le16                          tr_sel;
+};

No documentation of what these variables are anywhere?

I will add the documentation to explain them in this file.


What about the reserved slots, what must they be set to?

Will document they shoud be zero and check them.

Thanks
shuo

Reply via email to