diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index 2fe6f1f0e..33c2eefbf 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -269,6 +269,8 @@ add_cpu(struct vmctx *ctx, int guest_ncpus) mt_vmm_info[i].mt_vcpu = i; } + vm_set_vcpu_regs(ctx, &ctx->bsp_regs); + error = pthread_create(&mt_vmm_info[0].mt_thr, NULL, start_thread, &mt_vmm_info[0]); diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index e732c7151..39580631c 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -612,6 +612,12 @@ vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id) return error; } +int +vm_set_vcpu_regs(struct vmctx *ctx, struct acrn_set_vcpu_regs *vcpu_regs) +{ + return ioctl(ctx->fd, IC_SET_VCPU_REGS, vcpu_regs); +} + int vm_get_device_fd(struct vmctx *ctx) { diff --git a/devicemodel/include/public/acrn_common.h b/devicemodel/include/public/acrn_common.h index 03ead291a..c2a3f706e 100644 --- a/devicemodel/include/public/acrn_common.h +++ b/devicemodel/include/public/acrn_common.h @@ -269,6 +269,77 @@ struct acrn_create_vcpu { uint16_t pcpu_id; } __aligned(8); +struct acrn_gp_regs { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; +}; + +struct acrn_descriptor_ptr { + uint16_t limit; + uint64_t base; + uint16_t reserved[3]; +} __attribute__((packed)); + +struct acrn_vcpu_regs { + struct acrn_gp_regs gprs; + struct acrn_descriptor_ptr gdt; + struct acrn_descriptor_ptr idt; + + uint64_t rip; + uint64_t cs_base; + uint64_t cr0; + uint64_t cr4; + uint64_t cr3; + uint64_t ia32_efer; + uint64_t rflags; + uint64_t reserved_64[4]; + + uint32_t cs_ar; + uint32_t reserved_32[4]; + + /* don't change the order of following sel */ + uint16_t cs_sel; + uint16_t ss_sel; + uint16_t ds_sel; + uint16_t es_sel; + uint16_t fs_sel; + uint16_t gs_sel; + uint16_t ldt_sel; + uint16_t tr_sel; + + uint16_t reserved_16[4]; +}; + +/** + * @brief Info to set vcpu state + * + * the pamameter for HC_SET_VCPU_STATE + */ +struct acrn_set_vcpu_regs { + /** the virtual CPU ID for the VCPU to set state */ + uint16_t vcpu_id; + + /** reserved space to make cpu_state aligned to 8 bytes */ + uint16_t reserved0[3]; + + /** the structure to hold vcpu state */ + struct acrn_vcpu_regs vcpu_regs; +} __attribute__((aligned(8))); + /** * @brief Info to set ioreq buffer for a created VM * diff --git a/devicemodel/include/public/vhm_ioctl_defs.h b/devicemodel/include/public/vhm_ioctl_defs.h index 29a7e166a..1ea8fac39 100644 --- a/devicemodel/include/public/vhm_ioctl_defs.h +++ b/devicemodel/include/public/vhm_ioctl_defs.h @@ -73,6 +73,7 @@ #define IC_PAUSE_VM _IC_ID(IC_ID, IC_ID_VM_BASE + 0x03) #define IC_CREATE_VCPU _IC_ID(IC_ID, IC_ID_VM_BASE + 0x04) #define IC_RESET_VM _IC_ID(IC_ID, IC_ID_VM_BASE + 0x05) +#define IC_SET_VCPU_REGS _IC_ID(IC_ID, IC_ID_VM_BASE + 0x06) /* IRQ and Interrupts */ #define IC_ID_IRQ_BASE 0x20UL diff --git a/devicemodel/include/vmmapi.h b/devicemodel/include/vmmapi.h index 032343097..a72acd910 100644 --- a/devicemodel/include/vmmapi.h +++ b/devicemodel/include/vmmapi.h @@ -64,6 +64,9 @@ struct vmctx { void *vrtc; void *vpit; void *ioc_dev; + + /* BSP state. guest loader needs to fill it */ + struct acrn_set_vcpu_regs bsp_regs; }; /* @@ -148,6 +151,7 @@ int vm_set_ptdev_intx_info(struct vmctx *ctx, uint16_t virt_bdf, int vm_reset_ptdev_intx_info(struct vmctx *ctx, int virt_pin, bool pic_pin); int vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id); +int vm_set_vcpu_regs(struct vmctx *ctx, struct acrn_set_vcpu_regs *cpu_regs); int vm_get_cpu_state(struct vmctx *ctx, void *state_buf); int vm_intr_monitor(struct vmctx *ctx, void *intr_buf);