mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-03 02:26:24 +00:00
hv: add new hypercalls to create and destroy an emulated device in hypervisor
Add HC_CREATE_VDEV and HC_DESTROY_VDEV two hypercalls that are used to create and destroy an emulated device(PCI device or legacy device) in hypervisor v3: 1) change HC_CREATE_DEVICE and HC_DESTROY_DEVICE to HC_CREATE_VDEV and HC_DESTROY_VDEV 2) refine code style v4: 1) remove unnecessary parameter 2) add VM state check for HC_CREATE_VDEV and HC_DESTROY hypercalls Tracked-On: #4853 Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
52bb9d6983
commit
8a34cf03ca
@ -65,6 +65,10 @@ static const struct hc_dispatch hc_dispatch_table[] = {
|
||||
.handler = hcall_assign_mmiodev},
|
||||
[HC_IDX(HC_DEASSIGN_MMIODEV)] = {
|
||||
.handler = hcall_deassign_mmiodev},
|
||||
[HC_IDX(HC_CREATE_VDEV)] = {
|
||||
.handler = hcall_create_vdev},
|
||||
[HC_IDX(HC_DESTROY_VDEV)] = {
|
||||
.handler = hcall_destroy_vdev},
|
||||
[HC_IDX(HC_SET_PTDEV_INTR_INFO)] = {
|
||||
.handler = hcall_set_ptdev_intr_info},
|
||||
[HC_IDX(HC_RESET_PTDEV_INTR_INFO)] = {
|
||||
|
@ -23,6 +23,22 @@
|
||||
|
||||
#define DBG_LEVEL_HYCALL 6U
|
||||
|
||||
typedef int32_t (*emul_dev_op) (struct acrn_vm *vm, struct acrn_emul_dev *dev);
|
||||
struct emul_dev_ops {
|
||||
/*
|
||||
* The low 32 bits represent the vendor id and device id of PCI device,
|
||||
* and the high 32 bits represent the device number of the legacy device
|
||||
*/
|
||||
uint64_t dev_id;
|
||||
emul_dev_op create;
|
||||
emul_dev_op destroy;
|
||||
|
||||
};
|
||||
|
||||
static struct emul_dev_ops emul_dev_ops_tbl[] = {
|
||||
{0, NULL, NULL}, /* implemented in next patch */
|
||||
};
|
||||
|
||||
bool is_hypercall_from_ring0(void)
|
||||
{
|
||||
uint16_t cs_sel;
|
||||
@ -1197,3 +1213,82 @@ int32_t hcall_set_callback_vector(__unused struct acrn_vm *vm, __unused struct a
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @pre dev != NULL
|
||||
*/
|
||||
static struct emul_dev_ops *find_emul_dev_ops(struct acrn_emul_dev *dev)
|
||||
{
|
||||
struct emul_dev_ops *op = NULL;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(emul_dev_ops_tbl); i++) {
|
||||
if (emul_dev_ops_tbl[i].dev_id == dev->dev_id.value) {
|
||||
op = &emul_dev_ops_tbl[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vmid ID of the VM
|
||||
* @param param guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_create_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_emul_dev dev;
|
||||
struct emul_dev_ops *op;
|
||||
|
||||
/* We should only create a device to a post-launched VM at creating time for safety, not runtime or other cases*/
|
||||
if (is_created_vm(target_vm)) {
|
||||
if (copy_from_gpa(vm, &dev, param2, sizeof(dev)) == 0) {
|
||||
op = find_emul_dev_ops(&dev);
|
||||
if ((op != NULL) && (op->create != NULL)) {
|
||||
ret = op->create(target_vm, &dev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("%s, vm[%d] is not a postlaunched VM, or not in CREATED status to create a vdev\n", __func__, target_vm->vm_id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vmid ID of the VM
|
||||
* @param param guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_destroy_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_emul_dev dev;
|
||||
struct emul_dev_ops *op;
|
||||
|
||||
/* We should only destroy a device to a post-launched VM at creating or pausing time for safety, not runtime or other cases*/
|
||||
if (is_created_vm(target_vm) || is_paused_vm(target_vm)) {
|
||||
if (copy_from_gpa(vm, &dev, param2, sizeof(dev)) == 0) {
|
||||
op = find_emul_dev_ops(&dev);
|
||||
if ((op != NULL) && (op->destroy != NULL)) {
|
||||
ret = op->destroy(target_vm, &dev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("%s, vm[%d] is not a postlaunched VM, or not in CREATED/PAUSED status to destroy a vdev\n", __func__, target_vm->vm_id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -333,6 +333,34 @@ int32_t hcall_assign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint
|
||||
*/
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Create an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_create_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Destroy an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_destroy_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Set interrupt mapping info of ptdev.
|
||||
*
|
||||
|
@ -69,6 +69,8 @@
|
||||
#define HC_DEASSIGN_PCIDEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x06UL)
|
||||
#define HC_ASSIGN_MMIODEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x07UL)
|
||||
#define HC_DEASSIGN_MMIODEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x08UL)
|
||||
#define HC_CREATE_VDEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x09UL)
|
||||
#define HC_DESTROY_VDEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x0AUL)
|
||||
|
||||
/* DEBUG */
|
||||
#define HC_ID_DBG_BASE 0x60UL
|
||||
@ -323,6 +325,49 @@ struct acrn_mmiodev {
|
||||
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/**
|
||||
* @brief Info to create or destroy a virtual PCI or legacy device for a VM
|
||||
*
|
||||
* the parameter for HC_CREATE_VDEV or HC_DESTROY_VDEV hypercall
|
||||
*/
|
||||
struct acrn_emul_dev {
|
||||
/*
|
||||
* the identifier of the device, the low 32 bits represent the vendor
|
||||
* id and device id of PCI device and the high 32 bits represent the
|
||||
* device number of the legacy device
|
||||
*/
|
||||
union dev_id_info {
|
||||
uint64_t value;
|
||||
struct fields_info {
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
uint32_t legacy_device_number;
|
||||
} fields;
|
||||
} dev_id;
|
||||
|
||||
/*
|
||||
* the slot of the device, if the device is a PCI device, the slot
|
||||
* represents BDF, otherwise it represents legacy device slot number
|
||||
*/
|
||||
uint32_t slot;
|
||||
|
||||
/** reserved for extension */
|
||||
uint32_t reserved0;
|
||||
|
||||
/** the IO resource address of the device, initialized by ACRN-DM. */
|
||||
uint32_t io_addr[6];
|
||||
|
||||
/** the IO resource size of the device, initialized by ACRN-DM. */
|
||||
uint32_t io_size[6];
|
||||
|
||||
/** the options for the virtual device, initialized by ACRN-DM. */
|
||||
uint8_t args[128];
|
||||
|
||||
/** reserved for extension */
|
||||
uint64_t reserved1[8];
|
||||
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/**
|
||||
* Hypervisor api version info, return it for HC_GET_API_VERSION hypercall
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user