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:
Peter Maydell 2015-04-01 11:31:31 +01:00
commit b8a86c4ac4
10 changed files with 56 additions and 7 deletions

View File

@ -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
View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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);
}

View File

@ -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 = {

View File

@ -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();
}