The new generic DEFINE_PROP_BITMASK_UINT64 could be used to ensure that a user-provided property value complies with its bitmask rule and the default value is recommended to be set in instance_init().
Signed-off-by: Like Xu <like...@linux.intel.com> --- hw/core/qdev-properties.c | 19 +++++++++++++++++++ include/hw/qdev-properties.h | 12 ++++++++++++ include/qapi/qmp/qerror.h | 3 +++ 3 files changed, 34 insertions(+) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 50f40949f5..3784d3b30d 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -428,6 +428,25 @@ const PropertyInfo qdev_prop_int64 = { .set_default_value = qdev_propinfo_set_default_value_int, }; +static void set_bitmask_uint64(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + Property *prop = opaque; + uint64_t *ptr = object_field_prop_ptr(obj, prop); + + visit_type_uint64(v, name, ptr, errp); + + if (*ptr & ~prop->bitmask) { + error_setg(errp, QERR_INVALID_BITMASK_VALUE, name, prop->bitmask); + } +} + +const PropertyInfo qdev_prop_bitmask_uint64 = { + .name = "int64", + .get = get_uint64, + .set = set_bitmask_uint64, +}; + /* --- string --- */ static void release_string(Object *obj, const char *name, void *opaque) diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 0ef97d60ce..42f0112e14 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -17,6 +17,7 @@ struct Property { const PropertyInfo *info; ptrdiff_t offset; uint8_t bitnr; + uint64_t bitmask; bool set_default; union { int64_t i; @@ -53,6 +54,7 @@ extern const PropertyInfo qdev_prop_uint16; extern const PropertyInfo qdev_prop_uint32; extern const PropertyInfo qdev_prop_int32; extern const PropertyInfo qdev_prop_uint64; +extern const PropertyInfo qdev_prop_bitmask_uint64; extern const PropertyInfo qdev_prop_int64; extern const PropertyInfo qdev_prop_size; extern const PropertyInfo qdev_prop_string; @@ -102,6 +104,16 @@ extern const PropertyInfo qdev_prop_link; .set_default = true, \ .defval.u = (bool)_defval) +/** + * The DEFINE_PROP_BITMASK_UINT64 could be used to ensure that + * a user-provided value complies with certain bitmask rule and + * the default value is recommended to be set in instance_init(). + */ +#define DEFINE_PROP_BITMASK_UINT64(_name, _state, _field, _bitmask) \ + DEFINE_PROP(_name, _state, _field, qdev_prop_bitmask_uint64, uint64_t, \ + .bitmask = (_bitmask), \ + .set_default = false) + #define PROP_ARRAY_LEN_PREFIX "len-" /** diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h index 596fce0c54..aab7902760 100644 --- a/include/qapi/qmp/qerror.h +++ b/include/qapi/qmp/qerror.h @@ -68,4 +68,7 @@ #define QERR_UNSUPPORTED \ "this feature or command is not currently supported" +#define QERR_INVALID_BITMASK_VALUE \ + "the requested value for '%s' violates its bitmask '0x%lx'" + #endif /* QERROR_H */ -- 2.30.2