hv: mmio_dev: add hypercall to support mmio device pass through
Add two hypercalls to support MMIO device pass through for post-launched VM. And when we support MMIO pass through for pre-launched VM, we could re-use the code in mmio_dev.c Tracked-On: #5053 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
5034087a4f
commit
baf77a79ad
|
@ -306,6 +306,7 @@ VP_DM_C_SRCS += dm/vpci/vmsi.c
|
|||
VP_DM_C_SRCS += dm/vpci/vmsix.c
|
||||
VP_DM_C_SRCS += dm/vpci/vmsix_on_msi.c
|
||||
VP_DM_C_SRCS += dm/vpci/vsriov.c
|
||||
VP_DM_C_SRCS += dm/mmio_dev.c
|
||||
VP_DM_C_SRCS += arch/x86/guest/vlapic.c
|
||||
VP_DM_C_SRCS += arch/x86/guest/pm.c
|
||||
VP_DM_C_SRCS += arch/x86/guest/assign.c
|
||||
|
|
|
@ -160,6 +160,20 @@ static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu)
|
|||
}
|
||||
break;
|
||||
|
||||
case HC_ASSIGN_MMIODEV:
|
||||
/* param1: relative vmid to sos, vm_id: absolute vmid */
|
||||
if (vmid_is_valid) {
|
||||
ret = hcall_assign_mmiodev(sos_vm, vm_id, param2);
|
||||
}
|
||||
break;
|
||||
|
||||
case HC_DEASSIGN_MMIODEV:
|
||||
/* param1: relative vmid to sos, vm_id: absolute vmid */
|
||||
if (vmid_is_valid) {
|
||||
ret = hcall_deassign_mmiodev(sos_vm, vm_id, param2);
|
||||
}
|
||||
break;
|
||||
|
||||
case HC_SET_PTDEV_INTR_INFO:
|
||||
/* param1: relative vmid to sos, vm_id: absolute vmid */
|
||||
if (vmid_is_valid) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <errno.h>
|
||||
#include <logmsg.h>
|
||||
#include <ioapic.h>
|
||||
#include <mmio_dev.h>
|
||||
|
||||
#define DBG_LEVEL_HYCALL 6U
|
||||
|
||||
|
@ -893,6 +894,70 @@ int32_t hcall_deassign_pcidev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assign one MMIO dev to a VM.
|
||||
*
|
||||
* @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_mmiodev including assign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_mmiodev mmiodev;
|
||||
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
|
||||
|
||||
/* We should only assign a device to a post-launched VM at creating time for safety, not runtime or other cases*/
|
||||
if (is_created_vm(target_vm) && is_postlaunched_vm(target_vm)) {
|
||||
if (copy_from_gpa(vm, &mmiodev, param, sizeof(mmiodev)) == 0) {
|
||||
ret = deassign_mmio_dev(vm, &mmiodev);
|
||||
if (ret == 0) {
|
||||
ret = assign_mmio_dev(target_vm, &mmiodev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("vm[%d] %s failed!\n",target_vm->vm_id, __func__);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deassign one MMIO dev from a VM.
|
||||
*
|
||||
* @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_mmiodev including deassign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_mmiodev mmiodev;
|
||||
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
|
||||
|
||||
/* We should only de-assign a device from a post-launched VM at creating/shutdown/reset time */
|
||||
if ((is_paused_vm(target_vm) || is_created_vm(target_vm)) && is_postlaunched_vm(target_vm)) {
|
||||
if (copy_from_gpa(vm, &mmiodev, param, sizeof(mmiodev)) == 0) {
|
||||
ret = deassign_mmio_dev(target_vm, &mmiodev);
|
||||
if (ret == 0) {
|
||||
ret = assign_mmio_dev(vm, &mmiodev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("vm[%d] %s failed!\n",target_vm->vm_id, __func__);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set interrupt mapping info of ptdev.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <util.h>
|
||||
#include <acrn_hv_defs.h>
|
||||
#include <pgtable.h>
|
||||
#include <vm.h>
|
||||
#include <ept.h>
|
||||
|
||||
int32_t assign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiodev *mmiodev)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
|
||||
if (mem_aligned_check(mmiodev->base_gpa, PAGE_SIZE) &&
|
||||
mem_aligned_check(mmiodev->base_hpa, PAGE_SIZE) &&
|
||||
mem_aligned_check(mmiodev->size, PAGE_SIZE)) {
|
||||
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, mmiodev->base_hpa,
|
||||
is_sos_vm(vm) ? mmiodev->base_hpa : mmiodev->base_gpa,
|
||||
mmiodev->size, EPT_RWX | EPT_UNCACHED);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t deassign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiodev *mmiodev)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
|
||||
if (mem_aligned_check(mmiodev->base_gpa, PAGE_SIZE) &&
|
||||
mem_aligned_check(mmiodev->base_hpa, PAGE_SIZE) &&
|
||||
mem_aligned_check(mmiodev->size, PAGE_SIZE)) {
|
||||
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
||||
is_sos_vm(vm) ? mmiodev->base_hpa : mmiodev->base_gpa, mmiodev->size);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -274,6 +274,32 @@ int32_t hcall_assign_pcidev(struct acrn_vm *vm, uint16_t vmid, uint64_t param);
|
|||
*/
|
||||
int32_t hcall_deassign_pcidev(struct acrn_vm *vm, uint16_t vmid, uint64_t param);
|
||||
|
||||
/**
|
||||
* @brief Assign one MMIO dev to VM.
|
||||
*
|
||||
* @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_mmiodev including assign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vm *vm, uint16_t vmid, uint64_t param);
|
||||
|
||||
/**
|
||||
* @brief Deassign one MMIO dev to VM.
|
||||
*
|
||||
* @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_mmiodev including deassign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, uint16_t vmid, uint64_t param);
|
||||
|
||||
/**
|
||||
* @brief Set interrupt mapping info of ptdev.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MMIO_DEV_H
|
||||
#define MMIO_DEV_H
|
||||
|
||||
int32_t assign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiodev *mmiodev);
|
||||
int32_t deassign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiodev *mmiodev);
|
||||
|
||||
#endif /* MMIO_DEV_H */
|
|
@ -66,6 +66,8 @@
|
|||
#define HC_RESET_PTDEV_INTR_INFO BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x04UL)
|
||||
#define HC_ASSIGN_PCIDEV BASE_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x05UL)
|
||||
#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)
|
||||
|
||||
/* DEBUG */
|
||||
#define HC_ID_DBG_BASE 0x60UL
|
||||
|
@ -300,6 +302,26 @@ struct acrn_assign_pcidev {
|
|||
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/**
|
||||
* @brief Info to assign or deassign a MMIO device for a VM
|
||||
*
|
||||
* the parameter for HC_ASSIGN_MMIODEV or HC_DEASSIGN_MMIODEV hypercall
|
||||
*/
|
||||
struct acrn_mmiodev {
|
||||
/** the gpa of the MMIO region for the MMIO device */
|
||||
uint64_t base_gpa;
|
||||
|
||||
/** the hpa of the MMIO region for the MMIO device */
|
||||
uint64_t base_hpa;
|
||||
|
||||
/** the size of the MMIO region for the MMIO device */
|
||||
uint64_t size;
|
||||
|
||||
/** reserved for extension */
|
||||
uint64_t reserved[13];
|
||||
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/**
|
||||
* Hypervisor api version info, return it for HC_GET_API_VERSION hypercall
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue