diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f1fd0f8736..9e4695d03f 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -246,26 +246,6 @@ struct PropertyInfo {
     ObjectPropertyRelease *release;
 };
 
-/**
- * GlobalProperty:
- * @user_provided: Set to true if property comes from user-provided config
- * (command-line or config file).
- * @used: Set to true if property was used when initializing a device.
- * @errp: Error destination, used like first argument of error_setg()
- *        in case property setting fails later. If @errp is NULL, we
- *        print warnings instead of ignoring errors silently. For
- *        hotplugged devices, errp is always ignored and warnings are
- *        printed instead.
- */
-typedef struct GlobalProperty {
-    const char *driver;
-    const char *property;
-    const char *value;
-    bool user_provided;
-    bool used;
-    Error **errp;
-} GlobalProperty;
-
 /*** Board API.  This should go away once we have a machine config file.  ***/
 
 DeviceState *qdev_create(BusState *bus, const char *name);
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 3ab9cd2eb6..c8b727f081 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -4,6 +4,7 @@
 #include "qapi/qapi-types-block.h"
 #include "qapi/qapi-types-misc.h"
 #include "hw/qdev-core.h"
+#include "qom/globals.h"
 
 /*** qdev-properties.c ***/
 
@@ -248,9 +249,6 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 /* FIXME: Remove opaque pointer properties.  */
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 
-void qdev_prop_register_global(GlobalProperty *prop);
-int qdev_prop_check_globals(void);
-void qdev_prop_set_globals(DeviceState *dev);
 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
                                     Property *prop, const char *value);
 
diff --git a/include/qom/globals.h b/include/qom/globals.h
new file mode 100644
index 0000000000..28a0390233
--- /dev/null
+++ b/include/qom/globals.h
@@ -0,0 +1,32 @@
+#ifndef QOM_GLOBALS
+#define QOM_GLOBALS
+
+#include "qom/object.h"
+
+/**
+ * GlobalProperty:
+ * @user_provided: Set to true if property comes from user-provided config
+ * (command-line or config file).
+ * @used: Set to true if property was used when initializing a device.
+ * @errp: Error destination, used like first argument of error_setg()
+ *        in case property setting fails later. If @errp is NULL, we
+ *        print warnings instead of ignoring errors silently. For
+ *        hotplugged devices, errp is always ignored and warnings are
+ *        printed instead.
+ */
+typedef struct GlobalProperty {
+    const char *driver;
+    const char *property;
+    const char *value;
+    bool user_provided;
+    bool used;
+    Error **errp;
+} GlobalProperty;
+
+void object_property_register_global(GlobalProperty *prop);
+
+void object_property_set_globals(Object *obj);
+
+int object_property_check_globals(void);
+
+#endif
diff --git a/accel/accel.c b/accel/accel.c
index 3da26eb90f..6916e0d63d 100644
--- a/accel/accel.c
+++ b/accel/accel.c
@@ -127,7 +127,7 @@ void accel_register_compat_props(AccelState *accel)
     for (; prop && prop->driver; prop++) {
         /* Any compat_props must never cause error */
         prop->errp = &error_abort;
-        qdev_prop_register_global(prop);
+        object_property_register_global(prop);
     }
 }
 
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 6b68e1218f..5f532939e4 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -855,7 +855,7 @@ void machine_register_compat_props(MachineState *machine)
         p = g_array_index(mc->compat_props, GlobalProperty *, i);
         /* Machine compat_props must never cause errors: */
         p->errp = &error_abort;
-        qdev_prop_register_global(p);
+        object_property_register_global(p);
     }
 }
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index bd84c4ea4c..4605ca9b78 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1173,73 +1173,6 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
     *ptr = value;
 }
 
-static GList *global_props;
-
-void qdev_prop_register_global(GlobalProperty *prop)
-{
-    global_props = g_list_append(global_props, prop);
-}
-
-int qdev_prop_check_globals(void)
-{
-    GList *l;
-    int ret = 0;
-
-    for (l = global_props; l; l = l->next) {
-        GlobalProperty *prop = l->data;
-        ObjectClass *oc;
-        DeviceClass *dc;
-        if (prop->used) {
-            continue;
-        }
-        if (!prop->user_provided) {
-            continue;
-        }
-        oc = object_class_by_name(prop->driver);
-        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
-        if (!oc) {
-            warn_report("global %s.%s has invalid class name",
-                        prop->driver, prop->property);
-            ret = 1;
-            continue;
-        }
-        dc = DEVICE_CLASS(oc);
-        if (!dc->hotpluggable && !prop->used) {
-            warn_report("global %s.%s=%s not used",
-                        prop->driver, prop->property, prop->value);
-            ret = 1;
-            continue;
-        }
-    }
-    return ret;
-}
-
-void qdev_prop_set_globals(DeviceState *dev)
-{
-    GList *l;
-
-    for (l = global_props; l; l = l->next) {
-        GlobalProperty *prop = l->data;
-        Error *err = NULL;
-
-        if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
-            continue;
-        }
-        prop->used = true;
-        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
-        if (err != NULL) {
-            error_prepend(&err, "can't apply global %s.%s=%s: ",
-                          prop->driver, prop->property, prop->value);
-            if (!dev->hotplugged && prop->errp) {
-                error_propagate(prop->errp, err);
-            } else {
-                assert(prop->user_provided);
-                warn_report_err(err);
-            }
-        }
-    }
-}
-
 /* --- 64bit unsigned int 'size' type --- */
 
 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 529b82de18..473060b551 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -976,7 +976,7 @@ static void device_initfn(Object *obj)
 
 static void device_post_init(Object *obj)
 {
-    qdev_prop_set_globals(DEVICE(obj));
+    object_property_set_globals(obj);
 }
 
 /* Unlink device from bus and free the structure.  */
diff --git a/qom/cpu.c b/qom/cpu.c
index 92599f3541..aaabe67648 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -314,7 +314,7 @@ static void cpu_common_parse_features(const char *typename, char *features,
             prop->property = g_strdup(featurestr);
             prop->value = g_strdup(val);
             prop->errp = &error_fatal;
-            qdev_prop_register_global(prop);
+            object_property_register_global(prop);
         } else {
             error_setg(errp, "Expected key=value format, found %s.",
                        featurestr);
diff --git a/qom/globals.c b/qom/globals.c
new file mode 100644
index 0000000000..587f4a1b5c
--- /dev/null
+++ b/qom/globals.c
@@ -0,0 +1,75 @@
+#include "qemu/osdep.h"
+
+#include "hw/qdev.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qom/globals.h"
+#include "qom/object_interfaces.h"
+
+static GList *global_props;
+
+void object_property_register_global(GlobalProperty *prop)
+{
+    global_props = g_list_append(global_props, prop);
+}
+
+void object_property_set_globals(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    GList *l;
+
+    for (l = global_props; l; l = l->next) {
+        GlobalProperty *prop = l->data;
+        Error *err = NULL;
+
+        if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
+            continue;
+        }
+        prop->used = true;
+        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
+        if (err != NULL) {
+            error_prepend(&err, "can't apply global %s.%s=%s: ",
+                          prop->driver, prop->property, prop->value);
+            if (!dev->hotplugged && prop->errp) {
+                error_propagate(prop->errp, err);
+            } else {
+                assert(prop->user_provided);
+                warn_report_err(err);
+            }
+        }
+    }
+}
+
+int object_property_check_globals(void)
+{
+    GList *l;
+    int ret = 0;
+
+    for (l = global_props; l; l = l->next) {
+        GlobalProperty *prop = l->data;
+        ObjectClass *oc;
+        DeviceClass *dc;
+        if (prop->used) {
+            continue;
+        }
+        if (!prop->user_provided) {
+            continue;
+        }
+        oc = object_class_by_name(prop->driver);
+        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
+        if (!oc) {
+            warn_report("global %s.%s has invalid class name",
+                        prop->driver, prop->property);
+            ret = 1;
+            continue;
+        }
+        dc = DEVICE_CLASS(oc);
+        if (!dc->hotpluggable && !prop->used) {
+            warn_report("global %s.%s=%s not used",
+                        prop->driver, prop->property, prop->value);
+            ret = 1;
+            continue;
+        }
+    }
+    return ret;
+}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f24295e6e4..ead1f67805 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3414,7 +3414,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
         prop->property = g_strdup(name);
         prop->value = g_strdup(val);
         prop->errp = &error_fatal;
-        qdev_prop_register_global(prop);
+        object_property_register_global(prop);
     }
 
     if (ambiguous) {
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 0f090ece54..3fde246d0d 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -112,7 +112,7 @@ cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
     prop->property = g_strdup(name);
     prop->value = g_strdup(val);
     prop->errp = &error_fatal;
-    qdev_prop_register_global(prop);
+    object_property_register_global(prop);
 }
 
 /* Parse "+feature,-feature,feature=foo" CPU feature string */
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index d8596e6637..9dffdf336d 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -94,7 +94,7 @@ static void register_global_list(GlobalProperty *props)
     int i;
 
     for (i = 0; props[i].driver != NULL; i++) {
-        qdev_prop_register_global(props + i);
+        object_property_register_global(props + i);
     }
 }
 
@@ -233,7 +233,7 @@ static void test_dynamic_globalprop_subprocess(void)
 
     g_assert_cmpuint(mt->prop1, ==, 101);
     g_assert_cmpuint(mt->prop2, ==, 102);
-    all_used = qdev_prop_check_globals();
+    all_used = object_property_check_globals();
     g_assert_cmpuint(all_used, ==, 1);
     g_assert(props[0].used);
     g_assert(props[1].used);
@@ -278,7 +278,7 @@ static void test_dynamic_globalprop_nouser_subprocess(void)
 
     g_assert_cmpuint(mt->prop1, ==, 101);
     g_assert_cmpuint(mt->prop2, ==, 102);
-    all_used = qdev_prop_check_globals();
+    all_used = object_property_check_globals();
     g_assert_cmpuint(all_used, ==, 0);
     g_assert(props[0].used);
     g_assert(props[1].used);
diff --git a/vl.c b/vl.c
index 5ba06adf78..03b8bda0ac 100644
--- a/vl.c
+++ b/vl.c
@@ -903,7 +903,7 @@ static void configure_rtc(QemuOpts *opts)
                 .value    = "slew",
             };
 
-            qdev_prop_register_global(&slew_lost_ticks);
+            object_property_register_global(&slew_lost_ticks);
         } else if (!strcmp(value, "none")) {
             /* discard is default */
         } else {
@@ -2872,7 +2872,7 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
     g->value    = qemu_opt_get(opts, "value");
     g->user_provided = true;
     g->errp = &error_fatal;
-    qdev_prop_register_global(g);
+    object_property_register_global(g);
     return 0;
 }
 
@@ -3564,7 +3564,7 @@ int main(int argc, char **argv, char **envp)
                     .value    = "slew",
                 };
 
-                qdev_prop_register_global(&slew_lost_ticks);
+                object_property_register_global(&slew_lost_ticks);
                 warn_report("This option is deprecated, "
                             "use '-rtc driftfix=slew' instead.");
                 break;
@@ -4623,7 +4623,7 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
-    qdev_prop_check_globals();
+    object_property_check_globals();
     if (vmstate_dump_file) {
         /* dump and exit */
         dump_vmstate_json_to_file(vmstate_dump_file);
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 516349eec3..723851ff28 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,4 @@
 qom-obj-y = object.o container.o qom-qobject.o
-qom-obj-y += object_interfaces.o
+qom-obj-y += object_interfaces.o globals.o
 
 common-obj-y = cpu.o
