HV:treewide:Add 16-bit atomic operations and update vpid type

There are some integer type conversions reported by static
analysis tool for vcpu id, number of created vcpus, and
vpid, to reduce these type conversions, redesign vcpu id,
number of created vcpus, and vpid type as uint16_t as per
their usage, related 16-bit atomic operations shall be
added in HV.
MISRA C requires that all unsigned constants should have the suffix 'U'
(e.g. 0xffU), but the assembler may not accept such C-style constants.

Add 16-bit atomic add/dec/store operations;
Update temporary variables type and parameters type of
related caller;
Update vpid type as uint16_t;
Replace Macro with constant value for CPU_PAGE_SIZE.

Note: According to SDM A.10, there are some bits defined
in the IA32_VMX_EPT_VPID_CAP MSR to support the INVVPID
instruction, these bits don't mean actual VPID, so
the vpid field in the data struct vmx_capability doesn't
be updated.

V1--V2:
	update comments for assembly code as per coding style;

Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com>
This commit is contained in:
Xiangyang Wu
2018-07-11 11:09:10 +08:00
committed by Jack Ren
parent a23549aa91
commit 4dc39fdb8e
11 changed files with 40 additions and 28 deletions

View File

@@ -127,7 +127,8 @@ primary_start_long_mode:
/* Initialize temporary stack pointer */
lea _ld_bss_end(%rip), %rsp
add $CPU_PAGE_SIZE,%rsp
/*0x1000 = CPU_PAGE_SIZE*/
add $0x1000,%rsp
/* 16 = CPU_STACK_ALIGN */
and $(~(16 - 1)),%rsp
@@ -213,20 +214,24 @@ cpu_primary32_gdt_ptr:
.quad cpu_primary32_gdt
/* PML4, PDPT, and PD tables initialized to map first 4 GBytes of memory */
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
.global cpu_boot32_page_tables_start
cpu_boot32_page_tables_start:
/* 0x3 = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT) */
.quad cpu_primary32_pdpt_addr + 0x3
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
cpu_primary32_pdpt_addr:
address = 0
.rept 4
/* 0x3 = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT) */
.quad cpu_primary32_pdt_addr + address + 0x3
address = address + CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
address = address + 0x1000
.endr
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
cpu_primary32_pdt_addr:
address = 0
.rept 2048

View File

@@ -63,7 +63,7 @@ int create_vcpu(uint16_t pcpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle)
* vcpu->vcpu_id = vm->hw.created_vcpus;
* vm->hw.created_vcpus++;
*/
vcpu->vcpu_id = atomic_xadd(&vm->hw.created_vcpus, 1);
vcpu->vcpu_id = atomic_xadd16(&vm->hw.created_vcpus, 1U);
/* vm->hw.vcpu_array[vcpu->vcpu_id] = vcpu; */
atomic_store64(
(long *)&vm->hw.vcpu_array[vcpu->vcpu_id],
@@ -246,7 +246,7 @@ void destroy_vcpu(struct vcpu *vcpu)
(long *)&vcpu->vm->hw.vcpu_array[vcpu->vcpu_id],
(long)NULL);
atomic_dec(&vcpu->vm->hw.created_vcpus);
atomic_dec16(&vcpu->vm->hw.created_vcpus);
vlapic_free(vcpu);
free(vcpu->arch_vcpu.vmcs);

View File

@@ -104,7 +104,7 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
vm->attr.id = id;
vm->attr.boot_idx = id;
atomic_store(&vm->hw.created_vcpus, 0);
atomic_store16(&vm->hw.created_vcpus, 0U);
/* gpa_lowtop are used for system start up */
vm->hw.gpa_lowtop = 0UL;

View File

@@ -52,7 +52,7 @@ static struct vmx_capability {
* is the value of the VPID VM-execution control field in the VMCS.
* (VM entry ensures that this value is never 0000H).
*/
static int vmx_vpid_nr = VMX_MIN_NR_VPID;
static uint16_t vmx_vpid_nr = VMX_MIN_NR_VPID;
#define INVEPT_TYPE_SINGLE_CONTEXT 1UL
#define INVEPT_TYPE_ALL_CONTEXTS 2UL
@@ -71,7 +71,7 @@ struct invept_desc {
uint64_t _res;
};
static inline void _invvpid(uint64_t type, int vpid, uint64_t gva)
static inline void _invvpid(uint64_t type, uint16_t vpid, uint64_t gva)
{
int error = 0;
@@ -142,28 +142,28 @@ int check_vmx_mmu_cap(void)
return 0;
}
int allocate_vpid(void)
uint16_t allocate_vpid(void)
{
int vpid = atomic_xadd(&vmx_vpid_nr, 1);
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_xadd will always large than
* since next atomic_xadd16 will always large than
* VMX_MAX_NR_VPID.
*/
vmx_vpid_nr = VMX_MAX_NR_VPID;
vpid = 0;
vpid = 0U;
}
return vpid;
}
void flush_vpid_single(int vpid)
void flush_vpid_single(uint16_t vpid)
{
if (vpid == 0)
if (vpid == 0U)
return;
_invvpid(VMX_VPID_TYPE_SINGLE_CONTEXT, vpid, 0UL);
@@ -171,7 +171,7 @@ void flush_vpid_single(int vpid)
void flush_vpid_global(void)
{
_invvpid(VMX_VPID_TYPE_ALL_CONTEXT, 0, 0UL);
_invvpid(VMX_VPID_TYPE_ALL_CONTEXT, 0U, 0UL);
}
void invept(struct vcpu *vcpu)

View File

@@ -198,21 +198,25 @@ trampoline_gdt_ptr:
CPU_Boot_Page_Tables_ptr:
.long CPU_Boot_Page_Tables_Start
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
.global CPU_Boot_Page_Tables_Start
CPU_Boot_Page_Tables_Start:
/* 0x3 = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT) */
.quad trampoline_pdpt_addr + 0x3
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
.global trampoline_pdpt_addr
trampoline_pdpt_addr:
address = 0
.rept 4
/* 0x3 = (IA32E_COMM_P_BIT | IA32E_COMM_RW_BIT) */
.quad trampoline_pdt_addr + address + 0x3
address = address + CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
address = address + 0x1000
.endr
.align CPU_PAGE_SIZE
/*0x1000 = CPU_PAGE_SIZE*/
.align 0x1000
trampoline_pdt_addr:
address = 0
.rept 2048

View File

@@ -1239,7 +1239,7 @@ static void init_exec_ctrl(struct vcpu *vcpu)
VMX_PROCBASED_CTLS2_RDTSCP |
VMX_PROCBASED_CTLS2_UNRESTRICT);
if (vcpu->arch_vcpu.vpid != 0)
if (vcpu->arch_vcpu.vpid != 0U)
value32 |= VMX_PROCBASED_CTLS2_VPID;
else
value32 &= ~VMX_PROCBASED_CTLS2_VPID;