Re: [PATCH] hv: release vpid from reset_vcpu()


Eddie Dong
 

I am fine.

-----Original Message-----
From: Chen, Zide
Sent: Friday, April 19, 2019 8:35 AM
To: Dong, Eddie <eddie.dong@...>; acrn-dev@...
Cc: Grandhi, Sainath <sainath.grandhi@...>
Subject: Re: [acrn-dev] [PATCH] hv: release vpid from reset_vcpu()

How about this simple way:

/*
* + 1, because 0 is invalid for vpid
* vpid is 16 bits which should be large enough for ACRN
*/
vpid = vm_id * CONFIG_MAX_VCPUS_PER_VM + vcpu_id + 1;

Thanks,
Zide

On 4/18/19 5:20 PM, Dong, Eddie wrote:
Good catch !

While, moving forward, we are in the style of using static allocated resource,
rather than dynamic resources, due to FuSa reason. Can we change the design
to use static vpid as well?
We may be able to map vm:vcpu to a dedicated vpid.

Comments from others?

Thx Eddie

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...]
On Behalf Of Chen, Zide
Sent: Friday, April 19, 2019 6:53 AM
To: acrn-dev@...
Cc: Chen, Zide <zide.chen@...>; Grandhi, Sainath
<sainath.grandhi@...>
Subject: [acrn-dev] [PATCH] hv: release vpid from reset_vcpu()

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

This patch implements the vpid resource as bitmap other than the
simple incremental allocation, so that it can be freed.

Tracked-On: #2700
Signed-off-by: Zide Chen <zide.chen@...>
Signed-off-by: Sainath Grandhi <sainath.grandhi@...>
---
hypervisor/arch/x86/guest/vcpu.c | 2 ++
hypervisor/arch/x86/mmu.c | 25 +++++++++++++++----------
hypervisor/include/arch/x86/mmu.h | 8 ++++++++
hypervisor/include/arch/x86/vmx.h | 3 ---
4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/hypervisor/arch/x86/guest/vcpu.c
b/hypervisor/arch/x86/guest/vcpu.c
index 81bcc1a75a08..f48ca50d9d12 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -579,6 +579,8 @@ void reset_vcpu(struct acrn_vcpu *vcpu)
}
vcpu->arch.cur_context = NORMAL_WORLD;

+ release_vpid(vcpu->arch.vpid);
+
vlapic = vcpu_vlapic(vcpu);
vlapic_reset(vlapic);

diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c
index 9e3e4701e586..651bc51d472a 100644
--- a/hypervisor/arch/x86/mmu.c
+++ b/hypervisor/arch/x86/mmu.c
@@ -29,6 +29,7 @@

#include <types.h>
#include <atomic.h>
+#include <bits.h>
#include <page.h>
#include <pgtable.h>
#include <cpu_caps.h>
@@ -49,7 +50,9 @@ static uint8_t sanitized_page[PAGE_SIZE]
__aligned(PAGE_SIZE);
* 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 VMX_MAX_NR_VPID (CONFIG_MAX_VM_NUM *
CONFIG_MAX_VCPUS_PER_VM)
+#define VPID_BITMAP_ARRAY_SIZE
INT_DIV_ROUNDUP(VMX_MAX_NR_VPID,
64U)
+static uint64_t vmx_vpid_bitmaps[VPID_BITMAP_ARRAY_SIZE];

#define INVEPT_TYPE_SINGLE_CONTEXT 1UL
#define INVEPT_TYPE_ALL_CONTEXTS 2UL
@@ -121,23 +124,25 @@ 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);
+ uint16_t vpid = (uint16_t)ffz64_ex(vmx_vpid_bitmaps,
VMX_MAX_NR_VPID);

- /* 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;
+ pr_fatal("%s, vpid overflow: 0x%x\n", __func__, vpid);
+
+ /* Should not happen. */
vpid = 0U;
+ } else {
+ bitmap_set_lock((uint16_t)(vpid & 0x3FU), vmx_vpid_bitmaps +
(vpid >>
+6U));
}

return vpid;
}

+void release_vpid(uint16_t vpid)
+{
+ bitmap_clear_lock((vpid & 0x3FU), vmx_vpid_bitmaps + (vpid >> 6U));
+}
+
void flush_vpid_single(uint16_t vpid)
{
if (vpid != 0U) {
diff --git a/hypervisor/include/arch/x86/mmu.h
b/hypervisor/include/arch/x86/mmu.h
index b307e03b274d..0edb205fb1b5 100644
--- a/hypervisor/include/arch/x86/mmu.h
+++ b/hypervisor/include/arch/x86/mmu.h
@@ -143,6 +143,14 @@ void hv_access_memory_region_update(uint64_t
base, uint64_t size);
* @retval >0 the valid VPID
*/
uint16_t allocate_vpid(void);
+/**
+ * @brief VPID release
+ *
+ * @param[in] vpid the VPID to be released
+ *
+ * @return None
+ */
+void release_vpid(uint16_t vpid);
/**
* @brief Specified signle VPID flush
*
diff --git a/hypervisor/include/arch/x86/vmx.h
b/hypervisor/include/arch/x86/vmx.h
index ffb7bb9734ef..f41ec9e9391e 100644
--- a/hypervisor/include/arch/x86/vmx.h
+++ b/hypervisor/include/arch/x86/vmx.h
@@ -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
--
2.17.1


Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.