HV: add mmiodev resource in acrn_mmiodev data structure

mmiodev can have more than one mmio resource, so mmiores[3] is embedded
into mmiodev

Tracked-On: #6320
Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
This commit is contained in:
Tao Yuhong 2021-06-18 10:16:57 -04:00 committed by Xie, Nanlin
parent c0fb538f07
commit e3a55de27b
6 changed files with 53 additions and 35 deletions

View File

@ -244,7 +244,7 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_
bool is_hpa1 = true;
uint64_t base_hpa = vm_config->memory.start_hpa;
uint64_t remaining_hpa_size = vm_config->memory.size;
uint32_t i;
uint32_t i, j;
for (i = 0U; i < vm->e820_entry_num; i++) {
const struct e820_entry *entry = &(vm->e820_entries[i]);
@ -291,7 +291,9 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_
}
for (i = 0U; i < MAX_MMIO_DEV_NUM; i++) {
(void)assign_mmio_dev(vm, &vm_config->mmiodevs[i]);
for (j = 0; j < MMIODEV_RES_NUM; j++) {
(void)assign_mmio_dev(vm, &vm_config->mmiodevs[i].mmiores[j]);
}
#ifdef P2SB_VGPIO_DM_ENABLED
if ((vm_config->pt_p2sb_bar) && (vm_config->mmiodevs[i].base_hpa == P2SB_BAR_ADDR)) {
@ -380,7 +382,7 @@ static void deny_hv_owned_devices(struct acrn_vm *sos)
static void prepare_sos_vm_memmap(struct acrn_vm *vm)
{
uint16_t vm_id;
uint32_t i;
uint32_t i, j;
uint64_t hv_hpa;
uint64_t sos_high64_max_ram = MEM_4G;
struct acrn_vm_config *vm_config;
@ -437,7 +439,9 @@ static void prepare_sos_vm_memmap(struct acrn_vm *vm)
}
for (i = 0U; i < MAX_MMIO_DEV_NUM; i++) {
(void)deassign_mmio_dev(vm, &vm_config->mmiodevs[i]);
for (j = 0; j < MMIODEV_RES_NUM; j++) {
(void)deassign_mmio_dev(vm, &vm_config->mmiodevs[i].mmiores[j]);
}
}
}

View File

@ -920,16 +920,18 @@ int32_t hcall_assign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
__unused uint64_t param1, uint64_t param2)
{
struct acrn_vm *vm = vcpu->vm;
int32_t ret = -EINVAL;
int32_t i, ret = -EINVAL;
struct acrn_mmiodev mmiodev;
/* 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 (copy_from_gpa(vm, &mmiodev, param2, sizeof(mmiodev)) == 0) {
if (ept_is_valid_mr(vm, mmiodev.base_hpa, mmiodev.size)) {
ret = deassign_mmio_dev(vm, &mmiodev);
if (ret == 0) {
ret = assign_mmio_dev(target_vm, &mmiodev);
for (i = 0; i < MMIODEV_RES_NUM; i++) {
if (ept_is_valid_mr(vm, mmiodev.mmiores[i].base_hpa, mmiodev.mmiores[i].size)) {
ret = deassign_mmio_dev(vm, &mmiodev.mmiores[i]);
if (ret == 0) {
ret = assign_mmio_dev(target_vm, &mmiodev.mmiores[i]);
}
}
}
}
@ -955,16 +957,18 @@ int32_t hcall_deassign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm
__unused uint64_t param1, uint64_t param2)
{
struct acrn_vm *vm = vcpu->vm;
int32_t ret = -EINVAL;
int32_t i, ret = -EINVAL;
struct acrn_mmiodev mmiodev;
/* 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 (copy_from_gpa(vm, &mmiodev, param2, sizeof(mmiodev)) == 0) {
if (ept_is_valid_mr(target_vm, mmiodev.base_gpa, mmiodev.size)) {
ret = deassign_mmio_dev(target_vm, &mmiodev);
if (ret == 0) {
ret = assign_mmio_dev(vm, &mmiodev);
for (i = 0; i < MMIODEV_RES_NUM; i++) {
if (ept_is_valid_mr(target_vm, mmiodev.mmiores[i].base_gpa, mmiodev.mmiores[i].size)) {
ret = deassign_mmio_dev(target_vm, &mmiodev.mmiores[i]);
if (ret == 0) {
ret = assign_mmio_dev(vm, &mmiodev.mmiores[i]);
}
}
}
}

View File

@ -11,31 +11,31 @@
#include <asm/guest/vm.h>
#include <asm/guest/ept.h>
int32_t assign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiodev *mmiodev)
int32_t assign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiores *res)
{
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);
if (mem_aligned_check(res->base_gpa, PAGE_SIZE) &&
mem_aligned_check(res->base_hpa, PAGE_SIZE) &&
mem_aligned_check(res->size, PAGE_SIZE)) {
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, res->base_hpa,
is_sos_vm(vm) ? res->base_hpa : res->base_gpa,
res->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 deassign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiores *res)
{
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)) {
if (mem_aligned_check(res->base_gpa, PAGE_SIZE) &&
mem_aligned_check(res->base_hpa, PAGE_SIZE) &&
mem_aligned_check(res->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);
is_sos_vm(vm) ? res->base_hpa : res->base_gpa, res->size);
ret = 0;
}

View File

@ -7,7 +7,7 @@
#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);
int32_t assign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiores *res);
int32_t deassign_mmio_dev(struct acrn_vm *vm, const struct acrn_mmiores *res);
#endif /* MMIO_DEV_H */

View File

@ -305,23 +305,30 @@ struct acrn_assign_pcidev {
} __attribute__((aligned(8)));
#define MMIODEV_RES_NUM 3
/**
* @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;
char name[8];
struct acrn_mmiores {
/** 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 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;
/** the size of the MMIO region for the MMIO device */
uint64_t size;
uint64_t attr;
} mmiores[MMIODEV_RES_NUM];
/** reserved for extension */
uint64_t reserved[13];
uint64_t reserved[3];
} __attribute__((aligned(8)));

View File

@ -238,10 +238,13 @@
<xsl:value-of select="acrn:ifdef('VM0_PASSTHROUGH_TPM')" />
<xsl:value-of select="acrn:initializer('pt_tpm2', 'true')" />
<xsl:value-of select="acrn:initializer('mmiodevs[0]', '{', true())" />
<xsl:value-of select="acrn:initializer('name', concat($quot, 'tpm2', $quot))" />
<xsl:value-of select="acrn:initializer('mmiores[0]', '{', true())" />
<xsl:value-of select="acrn:initializer('base_gpa', 'VM0_TPM_BUFFER_BASE_ADDR_GPA')" />
<xsl:value-of select="acrn:initializer('base_hpa', 'VM0_TPM_BUFFER_BASE_ADDR')" />
<xsl:value-of select="acrn:initializer('size', 'VM0_TPM_BUFFER_SIZE')" />
<xsl:text>},</xsl:text>
<xsl:text>},</xsl:text>
<xsl:value-of select="$newline" />
<xsl:value-of select="$endif" />
<xsl:value-of select="acrn:ifdef('P2SB_BAR_ADDR')" />