]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2
authorShameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Fri, 21 Feb 2025 14:02:29 +0000 (14:02 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Wed, 26 Feb 2025 21:30:37 +0000 (13:30 -0800)
One difference here with other pseudo-firmware bitmap registers
is that the default/reset value for the supported hypercall
function-ids is 0 at present. Hence, modify the test accordingly.

Reviewed-by: Sebastian Ott <sebott@redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20250221140229.12588-7-shameerali.kolothum.thodi@huawei.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
tools/arch/arm64/include/uapi/asm/kvm.h
tools/testing/selftests/kvm/arm64/get-reg-list.c
tools/testing/selftests/kvm/arm64/hypercalls.c

index 66736ff04011e0fa9fcfb74154d5613bf4ee89f7..6d44f8c8a18fd98e9ea353ce8a2ca3ff875103bf 100644 (file)
@@ -374,6 +374,7 @@ enum {
 #endif
 };
 
+/* Vendor hyper call function numbers 0-63 */
 #define KVM_REG_ARM_VENDOR_HYP_BMAP            KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
 
 enum {
@@ -384,6 +385,17 @@ enum {
 #endif
 };
 
+/* Vendor hyper call function numbers 64-127 */
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2          KVM_REG_ARM_FW_FEAT_BMAP_REG(3)
+
+enum {
+       KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER    = 0,
+       KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS   = 1,
+#ifdef __KERNEL__
+       KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT,
+#endif
+};
+
 /* Device Control API on vm fd */
 #define KVM_ARM_VM_SMCCC_CTRL          0
 #define   KVM_ARM_VM_SMCCC_FILTER      0
index d43fb3f49050ba3de950d19d56b45beefec9dbeb..d01798b6b3b47fa9193fb6d65a41d6ac224d4c5f 100644 (file)
@@ -332,6 +332,7 @@ static __u64 base_regs[] = {
        KVM_REG_ARM_FW_FEAT_BMAP_REG(0),        /* KVM_REG_ARM_STD_BMAP */
        KVM_REG_ARM_FW_FEAT_BMAP_REG(1),        /* KVM_REG_ARM_STD_HYP_BMAP */
        KVM_REG_ARM_FW_FEAT_BMAP_REG(2),        /* KVM_REG_ARM_VENDOR_HYP_BMAP */
+       KVM_REG_ARM_FW_FEAT_BMAP_REG(3),        /* KVM_REG_ARM_VENDOR_HYP_BMAP_2 */
        ARM64_SYS_REG(3, 3, 14, 3, 1),  /* CNTV_CTL_EL0 */
        ARM64_SYS_REG(3, 3, 14, 3, 2),  /* CNTV_CVAL_EL0 */
        ARM64_SYS_REG(3, 3, 14, 0, 2),
index ec54ec7726e9c53fa22cb79718f59d7decd10160..44cfcf8a7f46766649aa3f1188ae4577b70c9fac 100644 (file)
 #define KVM_REG_ARM_STD_BMAP_BIT_MAX           0
 #define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX       0
 #define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX    1
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_MAX   1
+
+#define KVM_REG_ARM_STD_BMAP_RESET_VAL         FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_BMAP_BIT_MAX)
+#define KVM_REG_ARM_STD_HYP_BMAP_RESET_VAL     FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX)
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_RESET_VAL  FW_REG_ULIMIT_VAL(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX)
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_RESET_VAL 0
 
 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 */
 };
 
 #define FW_REG_INFO(r)                 \
        {                                       \
                .reg = r,                       \
                .max_feat_bit = r##_BIT_MAX,    \
+               .reset_val = r##_RESET_VAL      \
        }
 
 static const struct kvm_fw_reg_info fw_reg_info[] = {
        FW_REG_INFO(KVM_REG_ARM_STD_BMAP),
        FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP),
        FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP),
+       FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP_2),
 };
 
 enum test_stage {
@@ -171,22 +180,39 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
 
        for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
                const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
+               uint64_t set_val;
 
-               /* First 'read' should be an upper limit of the features supported */
+               /* First 'read' should be the reset value for the reg  */
                val = vcpu_get_reg(vcpu, reg_info->reg);
-               TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
-                       "Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
-                       reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
+               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);
 
-               /* Test a 'write' by disabling all the features of the register map */
-               ret = __vcpu_set_reg(vcpu, reg_info->reg, 0);
+               ret = __vcpu_set_reg(vcpu, reg_info->reg, set_val);
                TEST_ASSERT(ret == 0,
-                       "Failed to clear all the features of reg: 0x%lx; ret: %d",
-                       reg_info->reg, errno);
+                       "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 == 0,
-                       "Expected all the features to be cleared for reg: 0x%lx", 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);
+
+               /*
+                * If the reg has been set, clear it as test_fw_regs_after_vm_start()
+                * expects it to be cleared.
+                */
+               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);
+               }
 
                /*
                 * Test enabling a feature that's not supported.