Fix for object_del of in-use memory, pvpanic
regression, PPC regression and bogus error message with Oxygen theme. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJVG6d0AAoJEL/70l94x66DRl4H/jruVMg0HXtQsjIdOvLd8GPk CrK+DCxRw1P6ysY0sRocki2MNm+eiI3sn0q+8AI4jNEr6jdRPvxJA5aOPlhOJLAy WoJTShprwOtgMtZTnueCpE342D+1NeRWAiXnk+zQB/bhvoYZn95mxuDTpWw+tCcX 0mt7rg/zlzIvq4weXsT/c6ZGDaUymp5PheI3fEHcDJLOnU0+aZBtil6I/E6CgM3I r1mPjtv6SwCKTMcz6li9SBFp92AK80sOgLBzFY5AfTrMskKPha32R1r9z5q9MaYK Zm3Yf3Yi7MyrzO3dLmxNP6y2DR46X+YQv0uJAcHn8QRGXWLJ5H6TAZCNxsBctBk= =qZ9K -----END PGP SIGNATURE----- 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>
This commit is contained in:
		
						commit
						b8a86c4ac4
					
				@ -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
 | 
					static void
 | 
				
			||||||
host_memory_backend_class_init(ObjectClass *oc, void *data)
 | 
					host_memory_backend_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
 | 
					    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ucc->complete = host_memory_backend_memory_complete;
 | 
					    ucc->complete = host_memory_backend_memory_complete;
 | 
				
			||||||
 | 
					    ucc->can_be_deleted = host_memory_backend_can_be_deleted;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const TypeInfo host_memory_backend_info = {
 | 
					static const TypeInfo host_memory_backend_info = {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								exec.c
									
									
									
									
									
								
							@ -380,6 +380,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
 | 
				
			|||||||
    IOMMUTLBEntry iotlb;
 | 
					    IOMMUTLBEntry iotlb;
 | 
				
			||||||
    MemoryRegionSection *section;
 | 
					    MemoryRegionSection *section;
 | 
				
			||||||
    MemoryRegion *mr;
 | 
					    MemoryRegion *mr;
 | 
				
			||||||
 | 
					    hwaddr len = *plen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rcu_read_lock();
 | 
					    rcu_read_lock();
 | 
				
			||||||
    for (;;) {
 | 
					    for (;;) {
 | 
				
			||||||
@ -394,7 +395,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
 | 
				
			|||||||
        iotlb = mr->iommu_ops->translate(mr, addr, is_write);
 | 
					        iotlb = mr->iommu_ops->translate(mr, addr, is_write);
 | 
				
			||||||
        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
 | 
					        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
 | 
				
			||||||
                | (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))) {
 | 
					        if (!(iotlb.perm & (1 << is_write))) {
 | 
				
			||||||
            mr = &io_mem_unassigned;
 | 
					            mr = &io_mem_unassigned;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -405,9 +406,10 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
 | 
					    if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
 | 
				
			||||||
        hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
 | 
					        hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
 | 
				
			||||||
        *plen = MIN(page, *plen);
 | 
					        len = MIN(page, len);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *plen = len;
 | 
				
			||||||
    *xlat = addr;
 | 
					    *xlat = addr;
 | 
				
			||||||
    rcu_read_unlock();
 | 
					    rcu_read_unlock();
 | 
				
			||||||
    return mr;
 | 
					    return mr;
 | 
				
			||||||
 | 
				
			|||||||
@ -788,7 +788,7 @@ build_ssdt(GArray *table_data, GArray *linker,
 | 
				
			|||||||
        scope = aml_scope("\\_SB.PCI0.ISA");
 | 
					        scope = aml_scope("\\_SB.PCI0.ISA");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dev = aml_device("PEVR");
 | 
					        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();
 | 
					        crs = aml_resource_template();
 | 
				
			||||||
        aml_append(crs,
 | 
					        aml_append(crs,
 | 
				
			||||||
 | 
				
			|||||||
@ -117,6 +117,7 @@ extern void synchronize_rcu(void);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
extern void rcu_register_thread(void);
 | 
					extern void rcu_register_thread(void);
 | 
				
			||||||
extern void rcu_unregister_thread(void);
 | 
					extern void rcu_unregister_thread(void);
 | 
				
			||||||
 | 
					extern void rcu_after_fork(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rcu_head;
 | 
					struct rcu_head;
 | 
				
			||||||
typedef void RCUCBFunc(struct rcu_head *head);
 | 
					typedef void RCUCBFunc(struct rcu_head *head);
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,8 @@ typedef struct UserCreatable {
 | 
				
			|||||||
 * UserCreatableClass:
 | 
					 * UserCreatableClass:
 | 
				
			||||||
 * @parent_class: the base class
 | 
					 * @parent_class: the base class
 | 
				
			||||||
 * @complete: callback to be called after @obj's properties are set.
 | 
					 * @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
 | 
					 * Interface is designed to work with -object/object-add/object_add
 | 
				
			||||||
 * commands.
 | 
					 * commands.
 | 
				
			||||||
@ -47,6 +49,7 @@ typedef struct UserCreatableClass {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* <public> */
 | 
					    /* <public> */
 | 
				
			||||||
    void (*complete)(UserCreatable *uc, Error **errp);
 | 
					    void (*complete)(UserCreatable *uc, Error **errp);
 | 
				
			||||||
 | 
					    bool (*can_be_deleted)(UserCreatable *uc, Error **errp);
 | 
				
			||||||
} UserCreatableClass;
 | 
					} UserCreatableClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -59,4 +62,14 @@ typedef struct UserCreatableClass {
 | 
				
			|||||||
 * nothing.
 | 
					 * nothing.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void user_creatable_complete(Object *obj, Error **errp);
 | 
					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
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -4572,6 +4572,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
 | 
				
			|||||||
        ret = fork();
 | 
					        ret = fork();
 | 
				
			||||||
        if (ret == 0) {
 | 
					        if (ret == 0) {
 | 
				
			||||||
            /* Child Process.  */
 | 
					            /* Child Process.  */
 | 
				
			||||||
 | 
					            rcu_after_fork();
 | 
				
			||||||
            cpu_clone_regs(env, newsp);
 | 
					            cpu_clone_regs(env, newsp);
 | 
				
			||||||
            fork_end(1);
 | 
					            fork_end(1);
 | 
				
			||||||
            /* There is a race condition here.  The parent process could
 | 
					            /* There is a race condition here.  The parent process could
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@
 | 
				
			|||||||
#include "sysemu/sysemu.h"
 | 
					#include "sysemu/sysemu.h"
 | 
				
			||||||
#include "net/slirp.h"
 | 
					#include "net/slirp.h"
 | 
				
			||||||
#include "qemu-options.h"
 | 
					#include "qemu-options.h"
 | 
				
			||||||
 | 
					#include "qemu/rcu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_LINUX
 | 
					#ifdef CONFIG_LINUX
 | 
				
			||||||
#include <sys/prctl.h>
 | 
					#include <sys/prctl.h>
 | 
				
			||||||
@ -247,6 +248,7 @@ void os_daemonize(void)
 | 
				
			|||||||
        signal(SIGTSTP, SIG_IGN);
 | 
					        signal(SIGTSTP, SIG_IGN);
 | 
				
			||||||
        signal(SIGTTOU, SIG_IGN);
 | 
					        signal(SIGTTOU, SIG_IGN);
 | 
				
			||||||
        signal(SIGTTIN, SIG_IGN);
 | 
					        signal(SIGTTIN, SIG_IGN);
 | 
				
			||||||
 | 
					        rcu_after_fork();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								qmp.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								qmp.c
									
									
									
									
									
								
							@ -711,6 +711,11 @@ void qmp_object_del(const char *id, Error **errp)
 | 
				
			|||||||
        error_setg(errp, "object id not found");
 | 
					        error_setg(errp, "object id not found");
 | 
				
			||||||
        return;
 | 
					        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);
 | 
					    object_unparent(obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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 void register_types(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static const TypeInfo uc_interface_info = {
 | 
					    static const TypeInfo uc_interface_info = {
 | 
				
			||||||
 | 
				
			|||||||
@ -311,19 +311,18 @@ static void rcu_init_unlock(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    qemu_mutex_unlock(&rcu_gp_lock);
 | 
					    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));
 | 
					    memset(®istry, 0, sizeof(registry));
 | 
				
			||||||
    rcu_init_complete();
 | 
					    rcu_init_complete();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __attribute__((__constructor__)) rcu_init(void)
 | 
					static void __attribute__((__constructor__)) rcu_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_POSIX
 | 
					#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
 | 
					#endif
 | 
				
			||||||
    rcu_init_complete();
 | 
					    rcu_init_complete();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user