struct kvm_fw_reg_info {
uint64_t reg; /* Register definition */
uint64_t max_feat_bit; /* Bit that represents the upper limit of the feature-map */
uint64_t reset_val; /* Reset value for the register */
};
/* Feed false hypercall info to test the KVM behavior */ staticconststruct test_hvc_info false_hvc_info[] = { /* Feature support check against a different family of hypercalls */
TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID),
TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_TRNG_RND64),
TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_TRNG_RND64),
};
for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) { conststruct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
uint64_t set_val;
/* First 'read' should be the reset value for the reg */
val = vcpu_get_reg(vcpu, reg_info->reg);
TEST_ASSERT(val == reg_info->reset_val, "Unexpected reset value for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
reg_info->reg, reg_info->reset_val, val);
if (reg_info->reset_val)
set_val = 0; else
set_val = FW_REG_ULIMIT_VAL(reg_info->max_feat_bit);
ret = __vcpu_set_reg(vcpu, reg_info->reg, set_val);
TEST_ASSERT(ret == 0, "Failed to %s all the features of reg: 0x%lx; ret: %d",
(set_val ? "set" : "clear"), reg_info->reg, errno);
val = vcpu_get_reg(vcpu, reg_info->reg);
TEST_ASSERT(val == set_val, "Expected all the features to be %s for reg: 0x%lx",
(set_val ? "set" : "cleared"), reg_info->reg);
/* *Ifthereghasbeenset,clearitastest_fw_regs_after_vm_start() *expectsittobecleared.
*/ if (set_val) {
ret = __vcpu_set_reg(vcpu, reg_info->reg, 0);
TEST_ASSERT(ret == 0, "Failed to clear all the features of reg: 0x%lx; ret: %d",
reg_info->reg, errno);
}
/* *Testenablingafeaturethat'snotsupported. *Avoidthischeckifallthebitsareoccupied.
*/ if (reg_info->max_feat_bit < 63) {
ret = __vcpu_set_reg(vcpu, reg_info->reg, BIT(reg_info->max_feat_bit + 1));
TEST_ASSERT(ret != 0 && errno == EINVAL, "Unexpected behavior or return value (%d) while setting an unsupported feature for reg: 0x%lx",
errno, reg_info->reg);
}
}
}
for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) { conststruct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
/* *BeforestartingtheVM,thetestclearsallthebits. *Checkifthat'sstillthecase.
*/
val = vcpu_get_reg(vcpu, reg_info->reg);
TEST_ASSERT(val == 0, "Expected all the features to be cleared for reg: 0x%lx",
reg_info->reg);
/* *SincetheVMhasrunatleastonce,KVMshouldn'tallowmodificationof *theregistersandshouldreturnEBUSY.Settheregistersandcheckfor *theexpectederrno.
*/
ret = __vcpu_set_reg(vcpu, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit));
TEST_ASSERT(ret != 0 && errno == EBUSY, "Unexpected behavior or return value (%d) while setting a feature while VM is running for reg: 0x%lx",
errno, reg_info->reg);
}
}
/* Sync the stage early, the VM might be freed below. */
stage++;
sync_global_to_guest(*vm, stage);
switch (prev_stage) { case TEST_STAGE_REG_IFACE:
test_fw_regs_after_vm_start(*vcpu); break; case TEST_STAGE_HVC_IFACE_FEAT_DISABLED: /* Start a new VM so that all the features are now enabled by default */
kvm_vm_free(*vm);
*vm = test_vm_create(vcpu); break; case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: case TEST_STAGE_HVC_IFACE_FALSE_INFO: break; default:
TEST_FAIL("Unknown test stage: %d", prev_stage);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.