mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-04 18:00:55 +00:00
hv: dm: Use new pci device passthrough management ioctls
IC_ASSIGN_PCIDEV -> ACRN_IOCTL_ASSIGN_PCIDEV IC_DEASSIGN_PCIDEV -> ACRN_IOCTL_DEASSIGN_PCIDEV QUIRK_PTDEV -> ACRN_PTDEV_QUIRK_ASSIGN struct acrn_assign_pcidev -> struct acrn_pcidev Move struct acrn_pcidev into acrn_common.h because it is used by both DM and HV. Tracked-On: #6282 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
This commit is contained in:
parent
9d67745037
commit
3625eb7a99
@ -540,15 +540,15 @@ vm_set_gsi_irq(struct vmctx *ctx, int gsi, uint32_t operation)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vm_assign_pcidev(struct vmctx *ctx, struct acrn_assign_pcidev *pcidev)
|
vm_assign_pcidev(struct vmctx *ctx, struct acrn_pcidev *pcidev)
|
||||||
{
|
{
|
||||||
return ioctl(ctx->fd, IC_ASSIGN_PCIDEV, pcidev);
|
return ioctl(ctx->fd, ACRN_IOCTL_ASSIGN_PCIDEV, pcidev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vm_deassign_pcidev(struct vmctx *ctx, struct acrn_assign_pcidev *pcidev)
|
vm_deassign_pcidev(struct vmctx *ctx, struct acrn_pcidev *pcidev)
|
||||||
{
|
{
|
||||||
return ioctl(ctx->fd, IC_DEASSIGN_PCIDEV, pcidev);
|
return ioctl(ctx->fd, ACRN_IOCTL_DEASSIGN_PCIDEV, pcidev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -429,7 +429,7 @@ get_gpu_rsvmem_size()
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
passthru_gpu_dsm_opregion(struct vmctx *ctx, struct passthru_dev *ptdev,
|
passthru_gpu_dsm_opregion(struct vmctx *ctx, struct passthru_dev *ptdev,
|
||||||
struct acrn_assign_pcidev *pcidev, uint16_t device)
|
struct acrn_pcidev *pcidev, uint16_t device)
|
||||||
{
|
{
|
||||||
uint32_t opregion_phys, dsm_mask_val;
|
uint32_t opregion_phys, dsm_mask_val;
|
||||||
|
|
||||||
@ -510,7 +510,7 @@ passthru_gpu_dsm_opregion(struct vmctx *ctx, struct passthru_dev *ptdev,
|
|||||||
vm_unmap_ptdev_mmio(ctx, 0, 2, 0, gpu_opregion_gpa, GPU_OPREGION_SIZE, gpu_opregion_hpa);
|
vm_unmap_ptdev_mmio(ctx, 0, 2, 0, gpu_opregion_gpa, GPU_OPREGION_SIZE, gpu_opregion_hpa);
|
||||||
vm_map_ptdev_mmio(ctx, 0, 2, 0, gpu_opregion_gpa, GPU_OPREGION_SIZE, gpu_opregion_hpa);
|
vm_map_ptdev_mmio(ctx, 0, 2, 0, gpu_opregion_gpa, GPU_OPREGION_SIZE, gpu_opregion_hpa);
|
||||||
|
|
||||||
pcidev->type = QUIRK_PTDEV;
|
pcidev->type = ACRN_PTDEV_QUIRK_ASSIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -554,7 +554,7 @@ passthru_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
bool enable_ptm = false;
|
bool enable_ptm = false;
|
||||||
int vrp_sec_bus = 0;
|
int vrp_sec_bus = 0;
|
||||||
int vmsix_on_msi_bar_id = -1;
|
int vmsix_on_msi_bar_id = -1;
|
||||||
struct acrn_assign_pcidev pcidev = {};
|
struct acrn_pcidev pcidev = {};
|
||||||
uint16_t vendor = 0, device = 0;
|
uint16_t vendor = 0, device = 0;
|
||||||
|
|
||||||
ptdev = NULL;
|
ptdev = NULL;
|
||||||
@ -740,7 +740,7 @@ passthru_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
{
|
{
|
||||||
struct passthru_dev *ptdev;
|
struct passthru_dev *ptdev;
|
||||||
uint16_t virt_bdf = PCI_BDF(dev->bus, dev->slot, dev->func);
|
uint16_t virt_bdf = PCI_BDF(dev->bus, dev->slot, dev->func);
|
||||||
struct acrn_assign_pcidev pcidev = {};
|
struct acrn_pcidev pcidev = {};
|
||||||
uint16_t phys_bdf = 0;
|
uint16_t phys_bdf = 0;
|
||||||
char reset_path[60];
|
char reset_path[60];
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -117,9 +117,10 @@
|
|||||||
_IOW(ACRN_IOCTL_TYPE, 0x53, struct acrn_ptdev_irq)
|
_IOW(ACRN_IOCTL_TYPE, 0x53, struct acrn_ptdev_irq)
|
||||||
#define ACRN_IOCTL_RESET_PTDEV_INTR \
|
#define ACRN_IOCTL_RESET_PTDEV_INTR \
|
||||||
_IOW(ACRN_IOCTL_TYPE, 0x54, struct acrn_ptdev_irq)
|
_IOW(ACRN_IOCTL_TYPE, 0x54, struct acrn_ptdev_irq)
|
||||||
#define IC_RESET_PTDEV_INTR_INFO _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x04)
|
#define ACRN_IOCTL_ASSIGN_PCIDEV \
|
||||||
#define IC_ASSIGN_PCIDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x05)
|
_IOW(ACRN_IOCTL_TYPE, 0x55, struct acrn_pcidev)
|
||||||
#define IC_DEASSIGN_PCIDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x06)
|
#define ACRN_IOCTL_DEASSIGN_PCIDEV \
|
||||||
|
_IOW(ACRN_IOCTL_TYPE, 0x56, struct acrn_pcidev)
|
||||||
#define IC_ASSIGN_MMIODEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x07)
|
#define IC_ASSIGN_MMIODEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x07)
|
||||||
#define IC_DEASSIGN_MMIODEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x08)
|
#define IC_DEASSIGN_MMIODEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x08)
|
||||||
#define IC_ADD_HV_VDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x09)
|
#define IC_ADD_HV_VDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x09)
|
||||||
@ -179,39 +180,6 @@ struct acrn_vm_memmap {
|
|||||||
__u64 len;
|
__u64 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Info to assign or deassign PCI for a VM
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct acrn_assign_pcidev {
|
|
||||||
#define QUIRK_PTDEV (1 << 0) /* We will only handle general part in HV, others in DM */
|
|
||||||
/** the type of the the pass-through PCI device */
|
|
||||||
uint32_t type;
|
|
||||||
|
|
||||||
/** virtual BDF# of the pass-through PCI device */
|
|
||||||
uint16_t virt_bdf;
|
|
||||||
|
|
||||||
/** physical BDF# of the pass-through PCI device */
|
|
||||||
uint16_t phys_bdf;
|
|
||||||
|
|
||||||
/** the PCI Interrupt Line, initialized by ACRN-DM, which is RO and
|
|
||||||
* ideally not used for pass-through MSI/MSI-x devices.
|
|
||||||
*/
|
|
||||||
uint8_t intr_line;
|
|
||||||
|
|
||||||
/** the PCI Interrupt Pin, initialized by ACRN-DM, which is RO and
|
|
||||||
* ideally not used for pass-through MSI/MSI-x devices.
|
|
||||||
*/
|
|
||||||
uint8_t intr_pin;
|
|
||||||
|
|
||||||
/** the base address of the PCI BAR, initialized by ACRN-DM. */
|
|
||||||
uint32_t bar[6];
|
|
||||||
|
|
||||||
/** reserved for extension */
|
|
||||||
uint32_t rsvd2[6];
|
|
||||||
|
|
||||||
} __attribute__((aligned(8)));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Info to assign or deassign a MMIO device for a VM
|
* @brief Info to assign or deassign a MMIO device for a VM
|
||||||
*/
|
*/
|
||||||
|
@ -125,8 +125,8 @@ int vm_run(struct vmctx *ctx);
|
|||||||
int vm_suspend(struct vmctx *ctx, enum vm_suspend_how how);
|
int vm_suspend(struct vmctx *ctx, enum vm_suspend_how how);
|
||||||
int vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg);
|
int vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg);
|
||||||
int vm_set_gsi_irq(struct vmctx *ctx, int gsi, uint32_t operation);
|
int vm_set_gsi_irq(struct vmctx *ctx, int gsi, uint32_t operation);
|
||||||
int vm_assign_pcidev(struct vmctx *ctx, struct acrn_assign_pcidev *pcidev);
|
int vm_assign_pcidev(struct vmctx *ctx, struct acrn_pcidev *pcidev);
|
||||||
int vm_deassign_pcidev(struct vmctx *ctx, struct acrn_assign_pcidev *pcidev);
|
int vm_deassign_pcidev(struct vmctx *ctx, struct acrn_pcidev *pcidev);
|
||||||
int vm_assign_mmiodev(struct vmctx *ctx, struct acrn_mmiodev *mmiodev);
|
int vm_assign_mmiodev(struct vmctx *ctx, struct acrn_mmiodev *mmiodev);
|
||||||
int vm_deassign_mmiodev(struct vmctx *ctx, struct acrn_mmiodev *mmiodev);
|
int vm_deassign_mmiodev(struct vmctx *ctx, struct acrn_mmiodev *mmiodev);
|
||||||
int vm_map_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
|
int vm_map_ptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
|
||||||
|
@ -850,7 +850,7 @@ int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __un
|
|||||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||||
* @param target_vm Pointer to target VM data structure
|
* @param target_vm Pointer to target VM data structure
|
||||||
* @param param2 guest physical address. This gpa points to data structure of
|
* @param param2 guest physical address. This gpa points to data structure of
|
||||||
* acrn_assign_pcidev including assign PCI device info
|
* acrn_pcidev including assign PCI device info
|
||||||
*
|
*
|
||||||
* @pre is_sos_vm(vcpu->vm)
|
* @pre is_sos_vm(vcpu->vm)
|
||||||
* @return 0 on success, non-zero on error.
|
* @return 0 on success, non-zero on error.
|
||||||
@ -860,7 +860,7 @@ int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
|||||||
{
|
{
|
||||||
struct acrn_vm *vm = vcpu->vm;
|
struct acrn_vm *vm = vcpu->vm;
|
||||||
int32_t ret = -EINVAL;
|
int32_t ret = -EINVAL;
|
||||||
struct acrn_assign_pcidev pcidev;
|
struct acrn_pcidev pcidev;
|
||||||
|
|
||||||
/* We should only assign a device to a post-launched VM at creating time for safety, not runtime or other cases*/
|
/* 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)) {
|
if (is_created_vm(target_vm)) {
|
||||||
@ -880,7 +880,7 @@ int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
|||||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||||
* @param target_vm Pointer to target VM data structure
|
* @param target_vm Pointer to target VM data structure
|
||||||
* @param param2 guest physical address. This gpa points to data structure of
|
* @param param2 guest physical address. This gpa points to data structure of
|
||||||
* acrn_assign_pcidev including deassign PCI device info
|
* acrn_pcidev including deassign PCI device info
|
||||||
*
|
*
|
||||||
* @pre is_sos_vm(vcpu->vm)
|
* @pre is_sos_vm(vcpu->vm)
|
||||||
* @return 0 on success, non-zero on error.
|
* @return 0 on success, non-zero on error.
|
||||||
@ -890,7 +890,7 @@ int32_t hcall_deassign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
|||||||
{
|
{
|
||||||
struct acrn_vm *vm = vcpu->vm;
|
struct acrn_vm *vm = vcpu->vm;
|
||||||
int32_t ret = -EINVAL;
|
int32_t ret = -EINVAL;
|
||||||
struct acrn_assign_pcidev pcidev;
|
struct acrn_pcidev pcidev;
|
||||||
|
|
||||||
/* We should only de-assign a device from a post-launched VM at creating/shutdown/reset time */
|
/* 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))) {
|
if ((is_paused_vm(target_vm) || is_created_vm(target_vm))) {
|
||||||
|
@ -670,7 +670,7 @@ static void vpci_init_vdevs(struct acrn_vm *vm)
|
|||||||
* @pre tgt_vm != NULL
|
* @pre tgt_vm != NULL
|
||||||
* @pre pcidev != NULL
|
* @pre pcidev != NULL
|
||||||
*/
|
*/
|
||||||
int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pcidev)
|
int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev)
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
@ -743,7 +743,7 @@ int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pc
|
|||||||
* @pre tgt_vm != NULL
|
* @pre tgt_vm != NULL
|
||||||
* @pre pcidev != NULL
|
* @pre pcidev != NULL
|
||||||
*/
|
*/
|
||||||
int32_t vpci_deassign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pcidev)
|
int32_t vpci_deassign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev)
|
||||||
{
|
{
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
struct pci_vdev *parent_vdev, *vdev;
|
struct pci_vdev *parent_vdev, *vdev;
|
||||||
|
@ -49,7 +49,7 @@ static inline struct acrn_vm *vpci2vm(const struct acrn_vpci *vpci)
|
|||||||
|
|
||||||
static inline bool is_quirk_ptdev(const struct pci_vdev *vdev)
|
static inline bool is_quirk_ptdev(const struct pci_vdev *vdev)
|
||||||
{
|
{
|
||||||
return ((vdev->flags & QUIRK_PTDEV) != 0U);
|
return ((vdev->flags & ACRN_PTDEV_QUIRK_ASSIGN) != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool in_range(uint32_t value, uint32_t lower, uint32_t len)
|
static inline bool in_range(uint32_t value, uint32_t lower, uint32_t len)
|
||||||
|
@ -284,7 +284,7 @@ int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint
|
|||||||
* @param target_vm Pointer to target VM data structure
|
* @param target_vm Pointer to target VM data structure
|
||||||
* @param param1 not used
|
* @param param1 not used
|
||||||
* @param param2 guest physical address. This gpa points to data structure of
|
* @param param2 guest physical address. This gpa points to data structure of
|
||||||
* acrn_assign_pcidev including assign PCI device info
|
* acrn_pcidev including assign PCI device info
|
||||||
*
|
*
|
||||||
* @pre is_sos_vm(vcpu->vm)
|
* @pre is_sos_vm(vcpu->vm)
|
||||||
* @return 0 on success, non-zero on error.
|
* @return 0 on success, non-zero on error.
|
||||||
@ -298,7 +298,7 @@ int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, u
|
|||||||
* @param target_vm Pointer to target VM data structure
|
* @param target_vm Pointer to target VM data structure
|
||||||
* @param param1 not used
|
* @param param1 not used
|
||||||
* @param param2 guest physical address. This gpa points to data structure of
|
* @param param2 guest physical address. This gpa points to data structure of
|
||||||
* acrn_assign_pcidev including deassign PCI device info
|
* acrn_pcidev including deassign PCI device info
|
||||||
*
|
*
|
||||||
* @pre is_sos_vm(vcpu->vm)
|
* @pre is_sos_vm(vcpu->vm)
|
||||||
* @return 0 on success, non-zero on error.
|
* @return 0 on success, non-zero on error.
|
||||||
|
@ -187,9 +187,9 @@ extern const struct pci_vdev_ops vpci_bridge_ops;
|
|||||||
void init_vpci(struct acrn_vm *vm);
|
void init_vpci(struct acrn_vm *vm);
|
||||||
void deinit_vpci(struct acrn_vm *vm);
|
void deinit_vpci(struct acrn_vm *vm);
|
||||||
struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
|
struct pci_vdev *pci_find_vdev(struct acrn_vpci *vpci, union pci_bdf vbdf);
|
||||||
struct acrn_assign_pcidev;
|
struct acrn_pcidev;
|
||||||
int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pcidev);
|
int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev);
|
||||||
int32_t vpci_deassign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pcidev);
|
int32_t vpci_deassign_pcidev(struct acrn_vm *tgt_vm, struct acrn_pcidev *pcidev);
|
||||||
struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_config *dev_config, struct pci_vdev *parent_pf_vdev);
|
struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_config *dev_config, struct pci_vdev *parent_pf_vdev);
|
||||||
|
|
||||||
static inline bool is_pci_io_bar(struct pci_vbar *vbar)
|
static inline bool is_pci_io_bar(struct pci_vbar *vbar)
|
||||||
|
@ -703,6 +703,38 @@ struct vrp_config
|
|||||||
uint32_t ptm_cap_offset;
|
uint32_t ptm_cap_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Type of PCI device assignment */
|
||||||
|
#define ACRN_PTDEV_QUIRK_ASSIGN (1U << 0)
|
||||||
|
|
||||||
|
#define ACRN_PCI_NUM_BARS 6U
|
||||||
|
/**
|
||||||
|
* @brief Info to assign or deassign PCI for a VM
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct acrn_pcidev {
|
||||||
|
/** the type of the the pass-through PCI device */
|
||||||
|
uint32_t type;
|
||||||
|
|
||||||
|
/** virtual BDF# of the pass-through PCI device */
|
||||||
|
uint16_t virt_bdf;
|
||||||
|
|
||||||
|
/** physical BDF# of the pass-through PCI device */
|
||||||
|
uint16_t phys_bdf;
|
||||||
|
|
||||||
|
/** the PCI Interrupt Line, initialized by ACRN-DM, which is RO and
|
||||||
|
* ideally not used for pass-through MSI/MSI-x devices.
|
||||||
|
*/
|
||||||
|
uint8_t intr_line;
|
||||||
|
|
||||||
|
/** the PCI Interrupt Pin, initialized by ACRN-DM, which is RO and
|
||||||
|
* ideally not used for pass-through MSI/MSI-x devices.
|
||||||
|
*/
|
||||||
|
uint8_t intr_pin;
|
||||||
|
|
||||||
|
/** the base address of the PCI BAR, initialized by ACRN-DM. */
|
||||||
|
uint32_t bar[ACRN_PCI_NUM_BARS];
|
||||||
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
@ -271,40 +271,6 @@ struct hc_ptdev_irq {
|
|||||||
|
|
||||||
} __aligned(8);
|
} __aligned(8);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Info to assign or deassign PCI for a VM
|
|
||||||
*
|
|
||||||
* the parameter for HC_ASSIGN_PCIDEV or HC_DEASSIGN_PCIDEV hypercall
|
|
||||||
*/
|
|
||||||
struct acrn_assign_pcidev {
|
|
||||||
#define QUIRK_PTDEV (1U << 0) /* We will only handle general part in HV, others in DM */
|
|
||||||
/** the type of the the pass-through PCI device */
|
|
||||||
uint32_t type;
|
|
||||||
|
|
||||||
/** virtual BDF# of the pass-through PCI device */
|
|
||||||
uint16_t virt_bdf;
|
|
||||||
|
|
||||||
/** physical BDF# of the pass-through PCI device */
|
|
||||||
uint16_t phys_bdf;
|
|
||||||
|
|
||||||
/** the PCI Interrupt Line, initialized by ACRN-DM, which is RO and
|
|
||||||
* ideally not used for pass-through MSI/MSI-x devices.
|
|
||||||
*/
|
|
||||||
uint8_t intr_line;
|
|
||||||
|
|
||||||
/** the PCI Interrupt Pin, initialized by ACRN-DM, which is RO and
|
|
||||||
* ideally not used for pass-through MSI/MSI-x devices.
|
|
||||||
*/
|
|
||||||
uint8_t intr_pin;
|
|
||||||
|
|
||||||
/** the base address of the PCI BAR, initialized by ACRN-DM. */
|
|
||||||
uint32_t bar[6];
|
|
||||||
|
|
||||||
/** reserved for extension */
|
|
||||||
uint32_t rsvd2[6];
|
|
||||||
|
|
||||||
} __attribute__((aligned(8)));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Info to assign or deassign a MMIO device for a VM
|
* @brief Info to assign or deassign a MMIO device for a VM
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user