[PATCH 02/25] KVM: arm64: Add feature checking helpers
Marc Zyngier
maz at kernel.org
Mon Jan 22 12:18:29 PST 2024
In order to make it easier to check whether a particular feature
is exposed to a guest, add a new set of helpers, with kvm_has_feat()
being the most useful.
Follow-up work will make heavy use of these.
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 53 +++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..c0cf9c5f5e8d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1233,4 +1233,57 @@ static inline void kvm_hyp_reserve(void) { }
void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
+#define __expand_field_sign_unsigned(id, fld, val) \
+ ((u64)(id##_##fld##_##val))
+
+#define __expand_field_sign_signed(id, fld, val) \
+ ({ \
+ s64 __val = id##_##fld##_##val; \
+ __val <<= 64 - id##_##fld##_WIDTH; \
+ __val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH; \
+ \
+ __val; \
+ })
+
+#define expand_field_sign(id, fld, val) \
+ (id##_##fld##_SIGNED ? \
+ __expand_field_sign_signed(id, fld, val) : \
+ __expand_field_sign_unsigned(id, fld, val))
+
+#define get_idreg_field_unsigned(kvm, id, fld) \
+ ({ \
+ u64 __val = IDREG(kvm, SYS_##id); \
+ __val &= id##_##fld##_MASK; \
+ __val >>= id##_##fld##_SHIFT; \
+ \
+ __val; \
+ })
+
+#define get_idreg_field_signed(kvm, id, fld) \
+ ({ \
+ s64 __val = IDREG(kvm, SYS_##id); \
+ __val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH; \
+ __val >>= id##_##fld##_SHIFT; \
+ \
+ __val; \
+ })
+
+#define get_idreg_field_enum(kvm, id, fld) \
+ get_idreg_field_unsigned(kvm, id, fld)
+
+#define get_idreg_field(kvm, id, fld) \
+ (id##_##fld##_SIGNED ? \
+ get_idreg_field_signed(kvm, id, fld) : \
+ get_idreg_field_unsigned(kvm, id, fld))
+
+#define kvm_has_feat(kvm, id, fld, limit) \
+ (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
+
+#define kvm_has_feat_enum(kvm, id, fld, limit) \
+ (get_idreg_field_unsigned((kvm), id, fld) == id##_##fld##_##limit)
+
+#define kvm_has_feat_range(kvm, id, fld, min, max) \
+ (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
+ get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+
#endif /* __ARM64_KVM_HOST_H__ */
--
2.39.2
More information about the linux-arm-kernel
mailing list