Flags are great, but flags can also be dangerous: it is easy
to encode a flag that is bigger than its container (unless the
container is a u64), and it is easy to construct a flag value
that doesn't fit in the mask that is associated with it.

Add a couple of build-time sanity checks that ensure we catch
these two cases.

Signed-off-by: Marc Zyngier <m...@kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 4073a33af17c..70931231f0cb 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -420,8 +420,20 @@ struct kvm_vcpu_arch {
        } steal;
 };
 
+#define __build_check_flag(v, flagset, f, m)                   \
+       do {                                                    \
+               typeof(v->arch.flagset) *_fset;                 \
+                                                               \
+               /* Check that the flags fit in the mask */      \
+               BUILD_BUG_ON(HWEIGHT(m) != HWEIGHT((f) | (m))); \
+               /* Check that the flags fit in the type */      \
+               BUILD_BUG_ON((sizeof(*_fset) * 8) <= __fls(m)); \
+       } while (0)
+
 #define __vcpu_get_flag(v, flagset, f, m)                      \
        ({                                                      \
+               __build_check_flag(v, flagset, f, m);           \
+                                                               \
                v->arch.flagset & (m);                          \
        })
 
@@ -429,6 +441,8 @@ struct kvm_vcpu_arch {
        do {                                                    \
                typeof(v->arch.flagset) *fset;                  \
                                                                \
+               __build_check_flag(v, flagset, f, m);           \
+                                                               \
                fset = &v->arch.flagset;                        \
                if (HWEIGHT(m) > 1)                             \
                        *fset &= ~(m);                          \
@@ -439,6 +453,8 @@ struct kvm_vcpu_arch {
        do {                                                    \
                typeof(v->arch.flagset) *fset;                  \
                                                                \
+               __build_check_flag(v, flagset, f, m);           \
+                                                               \
                fset = &v->arch.flagset;                        \
                *fset &= ~(m);                                  \
        } while (0)
-- 
2.34.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to