summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-04-01 11:31:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-04-01 11:31:31 +0100
commitb8a86c4ac4d04c106ba38fbd707041cba334a155 (patch)
treefb3bcf6306d7b1b9ccaa42b2c9e8c1a83c936f81
parent033a20359aaf93f4d8aa2be12558901e8e028baa (diff)
parent4025446f0ac6213335c22ec43f3c3d8362ce7286 (diff)
downloadqemu-b8a86c4ac4d04c106ba38fbd707041cba334a155.tar.gz
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Fix for object_del of in-use memory, pvpanic regression, PPC regression and bogus error message with Oxygen theme. # gpg: Signature made Wed Apr 1 09:08:20 2015 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: Revert "exec: Respect as_tranlsate_internal length clamp" rcu: do not create thread in pthread_atfork callback pc: acpi: fix pvpanic regression hostmem: Prevent removing an in-use memory backend qom: Add can_be_deleted callback to UserCreatableClass Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--backends/hostmem.c14
-rw-r--r--exec.c6
-rw-r--r--hw/i386/acpi-build.c2
-rw-r--r--include/qemu/rcu.h1
-rw-r--r--include/qom/object_interfaces.h13
-rw-r--r--linux-user/syscall.c1
-rw-r--r--os-posix.c2
-rw-r--r--qmp.c5
-rw-r--r--qom/object_interfaces.c12
-rw-r--r--util/rcu.c7
10 files changed, 56 insertions, 7 deletions
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 99e8f99da8..b7b6cf8f4a 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -335,12 +335,26 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
}
}
+static bool
+host_memory_backend_can_be_deleted(UserCreatable *uc, Error **errp)
+{
+ MemoryRegion *mr;
+
+ mr = host_memory_backend_get_memory(MEMORY_BACKEND(uc), errp);
+ if (memory_region_is_mapped(mr)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
static void
host_memory_backend_class_init(ObjectClass *oc, void *data)
{
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
ucc->complete = host_memory_backend_memory_complete;
+ ucc->can_be_deleted = host_memory_backend_can_be_deleted;
}
static const TypeInfo host_memory_backend_info = {
diff --git a/exec.c b/exec.c
index 6d1e1e4c75..874ecfc2c6 100644
--- a/exec.c
+++ b/exec.c
@@ -380,6 +380,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
IOMMUTLBEntry iotlb;
MemoryRegionSection *section;
MemoryRegion *mr;
+ hwaddr len = *plen;
rcu_read_lock();
for (;;) {
@@ -394,7 +395,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
- *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
+ len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) {
mr = &io_mem_unassigned;
break;
@@ -405,9 +406,10 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
- *plen = MIN(page, *plen);
+ len = MIN(page, len);
}
+ *plen = len;
*xlat = addr;
rcu_read_unlock();
return mr;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d0a5c85e10..e761005efa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -788,7 +788,7 @@ build_ssdt(GArray *table_data, GArray *linker,
scope = aml_scope("\\_SB.PCI0.ISA");
dev = aml_device("PEVR");
- aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+ aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));
crs = aml_resource_template();
aml_append(crs,
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 506ab58eaf..7df1e86622 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -117,6 +117,7 @@ extern void synchronize_rcu(void);
*/
extern void rcu_register_thread(void);
extern void rcu_unregister_thread(void);
+extern void rcu_after_fork(void);
struct rcu_head;
typedef void RCUCBFunc(struct rcu_head *head);
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index b7922833e1..283ae0db4d 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -25,6 +25,8 @@ typedef struct UserCreatable {
* UserCreatableClass:
* @parent_class: the base class
* @complete: callback to be called after @obj's properties are set.
+ * @can_be_deleted: callback to be called before an object is removed
+ * to check if @obj can be removed safely.
*
* Interface is designed to work with -object/object-add/object_add
* commands.
@@ -47,6 +49,7 @@ typedef struct UserCreatableClass {
/* <public> */
void (*complete)(UserCreatable *uc, Error **errp);
+ bool (*can_be_deleted)(UserCreatable *uc, Error **errp);
} UserCreatableClass;
/**
@@ -59,4 +62,14 @@ typedef struct UserCreatableClass {
* nothing.
*/
void user_creatable_complete(Object *obj, Error **errp);
+
+/**
+ * user_creatable_can_be_deleted:
+ * @uc: the object whose can_be_deleted() method is called if implemented
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Wrapper to call can_be_deleted() method if one of types it's inherited
+ * from implements USER_CREATABLE interface.
+ */
+bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp);
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4bd954375e..1622ad6490 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4572,6 +4572,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
ret = fork();
if (ret == 0) {
/* Child Process. */
+ rcu_after_fork();
cpu_clone_regs(env, newsp);
fork_end(1);
/* There is a race condition here. The parent process could
diff --git a/os-posix.c b/os-posix.c
index ba091f1530..e4da406f38 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -39,6 +39,7 @@
#include "sysemu/sysemu.h"
#include "net/slirp.h"
#include "qemu-options.h"
+#include "qemu/rcu.h"
#ifdef CONFIG_LINUX
#include <sys/prctl.h>
@@ -247,6 +248,7 @@ void os_daemonize(void)
signal(SIGTSTP, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
+ rcu_after_fork();
}
}
diff --git a/qmp.c b/qmp.c
index c479e7751c..e6c70504df 100644
--- a/qmp.c
+++ b/qmp.c
@@ -711,6 +711,11 @@ void qmp_object_del(const char *id, Error **errp)
error_setg(errp, "object id not found");
return;
}
+
+ if (!user_creatable_can_be_deleted(USER_CREATABLE(obj), errp)) {
+ error_setg(errp, "%s is in use, can not be deleted", id);
+ return;
+ }
object_unparent(obj);
}
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 6360818397..a66cd6026c 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -18,6 +18,18 @@ void user_creatable_complete(Object *obj, Error **errp)
}
}
+bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp)
+{
+
+ UserCreatableClass *ucc = USER_CREATABLE_GET_CLASS(uc);
+
+ if (ucc->can_be_deleted) {
+ return ucc->can_be_deleted(uc, errp);
+ } else {
+ return true;
+ }
+}
+
static void register_types(void)
{
static const TypeInfo uc_interface_info = {
diff --git a/util/rcu.c b/util/rcu.c
index 27802a4bed..7270151bef 100644
--- a/util/rcu.c
+++ b/util/rcu.c
@@ -311,19 +311,18 @@ static void rcu_init_unlock(void)
{
qemu_mutex_unlock(&rcu_gp_lock);
}
+#endif
-static void rcu_init_child(void)
+void rcu_after_fork(void)
{
- qemu_mutex_unlock(&rcu_gp_lock);
memset(&registry, 0, sizeof(registry));
rcu_init_complete();
}
-#endif
static void __attribute__((__constructor__)) rcu_init(void)
{
#ifdef CONFIG_POSIX
- pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_child);
+ pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_unlock);
#endif
rcu_init_complete();
}