hv: allocate vpid based on vm_id and vcpu_id mapping

Currently vpid is not released in reset_vcpu() hence the vpid resource
could be exhausted easily if guests are re-launched.

This patch assigns vpid according to the fixed mapping of runtime vm_id
and vcpu_id to guarantee the uniqueness of vpid.

Tracked-On: #2700
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Zide Chen 2019-04-18 11:20:54 -07:00 committed by wenlingz
parent 9673f3dad4
commit a3207b2bc2
6 changed files with 13 additions and 41 deletions

View File

@ -477,9 +477,6 @@ Virtual MTRR
VPID
----
.. doxygenfunction:: allocate_vpid
:project: Project ACRN
.. doxygenfunction:: flush_vpid_single
:project: Project ACRN

View File

@ -380,7 +380,14 @@ int32_t create_vcpu(uint16_t pcpu_id, struct acrn_vm *vm, struct acrn_vcpu **rtn
vcpu->pcpu_id, vcpu->vm->vm_id, vcpu->vcpu_id,
is_vcpu_bsp(vcpu) ? "PRIMARY" : "SECONDARY");
vcpu->arch.vpid = allocate_vpid();
/*
* If the logical processor is in VMX non-root operation and
* the "enable VPID" VM-execution control is 1, the current VPID
* is the value of the VPID VM-execution control field in the VMCS.
*
* This assignment guarantees a unique non-zero per vcpu vpid in runtime.
*/
vcpu->arch.vpid = 1U + (vm->vm_id * CONFIG_MAX_VCPUS_PER_VM) + vcpu->vcpu_id;
/* Initialize exception field in VCPU context */
vcpu->arch.exception_info.exception = VECTOR_INVALID;

View File

@ -43,14 +43,6 @@
static void *ppt_mmu_pml4_addr;
static uint8_t sanitized_page[PAGE_SIZE] __aligned(PAGE_SIZE);
/*
* If the logical processor is in VMX non-root operation and
* the "enable VPID" VM-execution control is 1, the current VPID
* is the value of the VPID VM-execution control field in the VMCS.
* (VM entry ensures that this value is never 0000H).
*/
static uint16_t vmx_vpid_nr = VMX_MIN_NR_VPID;
#define INVEPT_TYPE_SINGLE_CONTEXT 1UL
#define INVEPT_TYPE_ALL_CONTEXTS 2UL
#define VMFAIL_INVALID_EPT_VPID \
@ -119,25 +111,6 @@ static inline void local_invept(uint64_t type, struct invept_desc desc)
}
}
uint16_t allocate_vpid(void)
{
uint16_t vpid = atomic_xadd16(&vmx_vpid_nr, 1U);
/* TODO: vpid overflow */
if (vpid >= VMX_MAX_NR_VPID) {
pr_err("%s, vpid overflow\n", __func__);
/*
* set vmx_vpid_nr to VMX_MAX_NR_VPID to disable vpid
* since next atomic_xadd16 will always large than
* VMX_MAX_NR_VPID.
*/
vmx_vpid_nr = VMX_MAX_NR_VPID;
vpid = 0U;
}
return vpid;
}
void flush_vpid_single(uint16_t vpid)
{
if (vpid != 0U) {

View File

@ -16,6 +16,11 @@
#define CTASSERT(expr) \
typedef int32_t CAT_(CTA_DummyType,__LINE__)[(expr) ? 1 : -1]
/* This is to make sure the 16 bits vpid won't overflow */
#if ((CONFIG_MAX_VM_NUM * CONFIG_MAX_VCPUS_PER_VM) > 0xffffU)
#error "VM number or VCPU number are too big"
#endif
/* Build time sanity checks to make sure hard-coded offset
* is matching the actual offset!
*/

View File

@ -136,13 +136,6 @@ void mmu_modify_or_del(uint64_t *pml4_page, uint64_t vaddr_base, uint64_t size,
uint64_t prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type);
void hv_access_memory_region_update(uint64_t base, uint64_t size);
/**
* @brief VPID allocation
*
* @retval 0 VPID overflow
* @retval >0 the valid VPID
*/
uint16_t allocate_vpid(void);
/**
* @brief Specified signle VPID flush
*

View File

@ -325,9 +325,6 @@
#define VMX_EPT_INVEPT_SINGLE_CONTEXT (1U << 25U)
#define VMX_EPT_INVEPT_GLOBAL_CONTEXT (1U << 26U)
#define VMX_MIN_NR_VPID 1U
#define VMX_MAX_NR_VPID (1U << 5U)
#define VMX_VPID_TYPE_INDIVIDUAL_ADDR 0UL
#define VMX_VPID_TYPE_SINGLE_CONTEXT 1UL
#define VMX_VPID_TYPE_ALL_CONTEXT 2UL