lkml.org 
[lkml]   [2020]   [Aug]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 07/17] virt: acrn: Introduce an ioctl to set vCPU registers state
    Date
    From: Shuo Liu <shuo.a.liu@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.liu@intel.com>
    Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
    Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
    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>
    ---
    drivers/virt/acrn/hsm.c | 13 +++++++
    drivers/virt/acrn/hypercall.h | 13 +++++++
    include/uapi/linux/acrn.h | 71 +++++++++++++++++++++++++++++++++++
    3 files changed, 97 insertions(+)

    diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c
    index ed8921a6c68b..31dec2f1aa12 100644
    --- a/drivers/virt/acrn/hsm.c
    +++ b/drivers/virt/acrn/hsm.c
    @@ -11,6 +11,7 @@

    #define pr_fmt(fmt) "acrn: " fmt

    +#include <linux/io.h>
    #include <linux/miscdevice.h>
    #include <linux/mm.h>
    #include <linux/module.h>
    @@ -47,6 +48,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd,
    {
    struct acrn_vm *vm = filp->private_data;
    struct acrn_vm_creation *vm_param;
    + struct acrn_vcpu_regs *cpu_regs;
    int ret = 0;

    if (cmd == ACRN_IOCTL_GET_API_VERSION) {
    @@ -101,6 +103,17 @@ 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);
    +
    + ret = hcall_set_vcpu_regs(vm->vmid, virt_to_phys(cpu_regs));
    + if (ret < 0)
    + pr_err("Failed to set regs state of VM%u!\n", vm->vmid);
    + kfree(cpu_regs);
    + break;
    default:
    pr_warn("Unknown IOCTL 0x%x!\n", cmd);
    ret = -EINVAL;
    diff --git a/drivers/virt/acrn/hypercall.h b/drivers/virt/acrn/hypercall.h
    index 6429e7a06e7e..5cc975db38d9 100644
    --- a/drivers/virt/acrn/hypercall.h
    +++ b/drivers/virt/acrn/hypercall.h
    @@ -22,6 +22,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_get_api_version() - Get API version from hypervisor
    @@ -89,4 +90,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 f8f00b18cd46..392d59a46499 100644
    --- a/include/uapi/linux/acrn.h
    +++ b/include/uapi/linux/acrn.h
    @@ -46,6 +46,75 @@ struct acrn_vm_creation {
    __u8 reserved2[8];
    } __attribute__((aligned(8)));

    +struct acrn_gp_regs {
    + __u64 rax;
    + __u64 rcx;
    + __u64 rdx;
    + __u64 rbx;
    + __u64 rsp;
    + __u64 rbp;
    + __u64 rsi;
    + __u64 rdi;
    + __u64 r8;
    + __u64 r9;
    + __u64 r10;
    + __u64 r11;
    + __u64 r12;
    + __u64 r13;
    + __u64 r14;
    + __u64 r15;
    +};
    +
    +struct acrn_descriptor_ptr {
    + __u16 limit;
    + __u64 base;
    + __u16 reserved[3];
    +} __attribute__ ((__packed__));
    +
    +struct acrn_regs {
    + struct acrn_gp_regs gprs;
    + struct acrn_descriptor_ptr gdt;
    + struct acrn_descriptor_ptr idt;
    +
    + __u64 rip;
    + __u64 cs_base;
    + __u64 cr0;
    + __u64 cr4;
    + __u64 cr3;
    + __u64 ia32_efer;
    + __u64 rflags;
    + __u64 reserved_64[4];
    +
    + __u32 cs_ar;
    + __u32 cs_limit;
    + __u32 reserved_32[3];
    +
    + __u16 cs_sel;
    + __u16 ss_sel;
    + __u16 ds_sel;
    + __u16 es_sel;
    + __u16 fs_sel;
    + __u16 gs_sel;
    + __u16 ldt_sel;
    + __u16 tr_sel;
    +
    + __u16 reserved_16[4];
    +};
    +
    +/**
    + * struct acrn_vcpu_regs - Info of vCPU registers state
    + * @vcpu_id: vCPU ID
    + * @reserved0: Reserved
    + * @vcpu_regs: vCPU registers state
    + *
    + * This structure will be passed to hypervisor directly.
    + */
    +struct acrn_vcpu_regs {
    + __u16 vcpu_id;
    + __u16 reserved0[3];
    + struct acrn_regs vcpu_regs;
    +} __attribute__((aligned(8)));
    +
    /* The ioctl type, documented in ioctl-number.rst */
    #define ACRN_IOCTL_TYPE 0xA2

    @@ -65,5 +134,7 @@ struct acrn_vm_creation {
    _IO(ACRN_IOCTL_TYPE, 0x13)
    #define ACRN_IOCTL_RESET_VM \
    _IO(ACRN_IOCTL_TYPE, 0x15)
    +#define ACRN_IOCTL_SET_VCPU_REGS \
    + _IOW(ACRN_IOCTL_TYPE, 0x16, struct acrn_vcpu_regs)

    #endif /* _UAPI_ACRN_H */
    --
    2.28.0
    \
     
     \ /
      Last update: 2020-08-25 04:51    [W:4.163 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site