mirror of
https://github.com/qemu/qemu.git
synced 2024-12-11 20:53:51 +08:00
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
|
||||
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 = {
|
||||
|
6
exec.c
6
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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
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");
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user