From d6edb15576643ab348a9f73e115c2e037edf7460 Mon Sep 17 00:00:00 2001 From: Lin Ma Date: Mon, 30 Mar 2015 16:36:28 +0800 Subject: [PATCH 1/5] qom: Add can_be_deleted callback to UserCreatableClass If backends implement the can_be_deleted and it returns false, Then the qmp_object_del won't delete the given backends. Signed-off-by: Lin Ma Message-Id: <1427704589-7688-2-git-send-email-lma@suse.com> Reviewed-by: Igor Mammedov Signed-off-by: Paolo Bonzini --- include/qom/object_interfaces.h | 13 +++++++++++++ qmp.c | 5 +++++ qom/object_interfaces.c | 12 ++++++++++++ 3 files changed, 30 insertions(+) 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 { /* */ 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/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 = { From 36bce5ca5da7a7dbdc5001dc65b40b7439472106 Mon Sep 17 00:00:00 2001 From: Lin Ma Date: Mon, 30 Mar 2015 16:36:29 +0800 Subject: [PATCH 2/5] hostmem: Prevent removing an in-use memory backend showing a memory device whose memdev is removed leads an assert: (qemu) object_add memory-backend-ram,id=ram0,size=128M (qemu) device_add pc-dimm,id=d0,memdev=ram0 (qemu) object_del ram0 (qemu) info memory-devices ** ERROR:qom/object.c:1274:object_get_canonical_path_component:\ assertion failed: (obj->parent != NULL) Aborted The patch prevents removing an in-use mem backend and error out. Signed-off-by: Lin Ma Message-Id: <1427704589-7688-3-git-send-email-lma@suse.com> Reviewed-by: Igor Mammedov Signed-off-by: Paolo Bonzini --- backends/hostmem.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 = { From e65bef6954415b24ee17184b959333d9456bece8 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 30 Mar 2015 14:18:27 +0200 Subject: [PATCH 3/5] pc: acpi: fix pvpanic regression Commit cd61cb2 pc: acpi-build: generate pvpanic device description dynamically introduced regression changing pvpanic device HID from QEMU0001 to QEMU0002. Fix AML generated code so that pvpanic device would keep its original HID. i.e. QEMU0001 Signed-off-by: Igor Mammedov Reported-by: Gal Hammer Message-Id: <1427717907-25027-1-git-send-email-imammedo@redhat.com> Acked-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- hw/i386/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, From a59629fcc6f603e19b516dc08f75334e5c480bd0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 Mar 2015 13:01:05 +0200 Subject: [PATCH 4/5] rcu: do not create thread in pthread_atfork callback If QEMU forks after the CPU threads have been created, qemu_mutex_lock_iothread will not be able to do qemu_cpu_kick_thread. There is no solution other than assuming that forks after the CPU threads have been created will end up in an exec. Forks before the CPU threads have been created (such as -daemonize) have to call rcu_after_fork manually. Notably, the oxygen theme for GTK+ forks and shows a "No such process" error without this patch. This patch can be reverted once the iothread loses the "kick the TCG thread" magic. User-mode emulation does not use the iothread, so it can also call rcu_after_fork. Reported by: Dr. David Alan Gilbert Tested by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- include/qemu/rcu.h | 1 + linux-user/syscall.c | 1 + os-posix.c | 2 ++ util/rcu.c | 7 +++---- 4 files changed, 7 insertions(+), 4 deletions(-) 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/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 @@ -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/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(); } From 4025446f0ac6213335c22ec43f3c3d8362ce7286 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 1 Apr 2015 09:57:45 +0200 Subject: [PATCH 5/5] Revert "exec: Respect as_tranlsate_internal length clamp" This reverts commit c3c1bb99d1c11978d9ce94d1bdcf0705378c1459. It causes problems with boards that declare memory regions shorter than the registers they contain. Reported-by: Zoltan Balaton Signed-off-by: Paolo Bonzini --- exec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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;