diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-04-01 11:31:31 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-04-01 11:31:31 +0100 |
commit | b8a86c4ac4d04c106ba38fbd707041cba334a155 (patch) | |
tree | fb3bcf6306d7b1b9ccaa42b2c9e8c1a83c936f81 | |
parent | 033a20359aaf93f4d8aa2be12558901e8e028baa (diff) | |
parent | 4025446f0ac6213335c22ec43f3c3d8362ce7286 (diff) |
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.c | 14 | ||||
-rw-r--r-- | exec.c | 6 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 2 | ||||
-rw-r--r-- | include/qemu/rcu.h | 1 | ||||
-rw-r--r-- | include/qom/object_interfaces.h | 13 | ||||
-rw-r--r-- | linux-user/syscall.c | 1 | ||||
-rw-r--r-- | os-posix.c | 2 | ||||
-rw-r--r-- | qmp.c | 5 | ||||
-rw-r--r-- | qom/object_interfaces.c | 12 | ||||
-rw-r--r-- | util/rcu.c | 7 |
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 = { @@ -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(); } } @@ -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(®istry, 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(); } |