x86 and machine queue, 2017-01-17
Includes i386, CPU, NUMA, and memory backends changes. i386: target/i386: Fix bad patch application to translate.c CPU: qmp: Report QOM type name on query-cpu-definitions NUMA: numa: make -numa parser dynamically allocate CPUs masks Memory backends: qom: remove unused header monitor: reuse user_creatable_add_opts() instead of user_creatable_add() monitor: fix qmp/hmp query-memdev not reporting IDs of memory backends -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJYd8KHAAoJECgHk2+YTcWmHL4QALOeGD9hts4xw+1Q/kIzZYKt 4fDdhGxyZ5faOiSUL8F2bOMXcOCsH+oNgvapxyKsZw1z79VbdEHgSUJtgv89Dz58 sZ6UA1YAg2cWVaKFbRm98qGOImHmPEyNS/C7EpkejB41TXWAXM6Oh4PYeYgaibi3 HxHW+oi7/4ugAs0dnIihaE/kMQmO4qWTtuDGosTPkTl4XuwWeMbC2BXaYIyZKAS5 F2MgEXbxph889PcsNMeE5xy5hw3CA34gpq+Xs+ai+Box7AjIGemZVgqHdYcSjMSI pmaLO8R1ciyzPfjgwojOkVzFIft1A5XyoAiWUTmR0o3KQLs0gmG7XkKpjId2UzTk Xl2mxQjWAxZNlbfOoNYRf6UhwAIjpKYrjYyr0nrrumXB+9YH1d/0ix+3UjtZLU+e Qgg+sSgv11MPpdc9t1gcvXVzB+h+eqp7WLYH3j5vdYJZwLVVJJusXJxmyy72BrdK 2AdL14RziPYvVvlQZ4fM5wp1HtTMUe96VLhHxwOpBDcdcdZIk1E8SxZXde1fUk41 OS+egry27xgoJ6pJMZlB8t4TKqcSj8x5dNLi9+qjtfDSRonPAROCBus4jugUd6Ds xeW06s7Hbm0BxGYn/3s860RPTJrJPX3+MjLtFbIdXSbwHWM6jsy4U9qQdLRlneR9 oTCyWo0AeuDFe0bQ110m =KII3 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging x86 and machine queue, 2017-01-17 Includes i386, CPU, NUMA, and memory backends changes. i386: target/i386: Fix bad patch application to translate.c CPU: qmp: Report QOM type name on query-cpu-definitions NUMA: numa: make -numa parser dynamically allocate CPUs masks Memory backends: qom: remove unused header monitor: reuse user_creatable_add_opts() instead of user_creatable_add() monitor: fix qmp/hmp query-memdev not reporting IDs of memory backends # gpg: Signature made Thu 12 Jan 2017 17:53:11 GMT # gpg: using RSA key 0x2807936F984DC5A6 # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/x86-and-machine-pull-request: qmp: Report QOM type name on query-cpu-definitions numa: make -numa parser dynamically allocate CPUs masks target/i386: Fix bad patch application to translate.c monitor: fix qmp/hmp query-memdev not reporting IDs of memory backends monitor: reuse user_creatable_add_opts() instead of user_creatable_add() qom: remove unused header Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
b6af8ea602
@ -348,6 +348,24 @@ host_memory_backend_can_be_deleted(UserCreatable *uc, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_id(Object *o, Error **errp)
|
||||
{
|
||||
HostMemoryBackend *backend = MEMORY_BACKEND(o);
|
||||
|
||||
return g_strdup(backend->id);
|
||||
}
|
||||
|
||||
static void set_id(Object *o, const char *str, Error **errp)
|
||||
{
|
||||
HostMemoryBackend *backend = MEMORY_BACKEND(o);
|
||||
|
||||
if (backend->id) {
|
||||
error_setg(errp, "cannot change property value");
|
||||
return;
|
||||
}
|
||||
backend->id = g_strdup(str);
|
||||
}
|
||||
|
||||
static void
|
||||
host_memory_backend_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
@ -377,6 +395,13 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
|
||||
HostMemPolicy_lookup,
|
||||
host_memory_backend_get_policy,
|
||||
host_memory_backend_set_policy, &error_abort);
|
||||
object_class_property_add_str(oc, "id", get_id, set_id, &error_abort);
|
||||
}
|
||||
|
||||
static void host_memory_backend_finalize(Object *o)
|
||||
{
|
||||
HostMemoryBackend *backend = MEMORY_BACKEND(o);
|
||||
g_free(backend->id);
|
||||
}
|
||||
|
||||
static const TypeInfo host_memory_backend_info = {
|
||||
@ -387,6 +412,7 @@ static const TypeInfo host_memory_backend_info = {
|
||||
.class_init = host_memory_backend_class_init,
|
||||
.instance_size = sizeof(HostMemoryBackend),
|
||||
.instance_init = host_memory_backend_init,
|
||||
.instance_finalize = host_memory_backend_finalize,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_USER_CREATABLE },
|
||||
{ }
|
||||
|
@ -3529,6 +3529,7 @@ Example (1):
|
||||
"policy": "bind"
|
||||
},
|
||||
{
|
||||
"id": "mem1",
|
||||
"size": 536870912,
|
||||
"merge": false,
|
||||
"dump": true,
|
||||
|
10
hmp.c
10
hmp.c
@ -1808,7 +1808,6 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *err = NULL;
|
||||
QemuOpts *opts;
|
||||
Visitor *v;
|
||||
Object *obj = NULL;
|
||||
|
||||
opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
|
||||
@ -1817,9 +1816,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
|
||||
return;
|
||||
}
|
||||
|
||||
v = opts_visitor_new(opts);
|
||||
obj = user_creatable_add(qdict, v, &err);
|
||||
visit_free(v);
|
||||
obj = user_creatable_add_opts(opts, &err);
|
||||
qemu_opts_del(opts);
|
||||
|
||||
if (err) {
|
||||
@ -2081,13 +2078,11 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
|
||||
MemdevList *m = memdev_list;
|
||||
Visitor *v;
|
||||
char *str;
|
||||
int i = 0;
|
||||
|
||||
|
||||
while (m) {
|
||||
v = string_output_visitor_new(false, &str);
|
||||
visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL);
|
||||
monitor_printf(mon, "memory backend: %d\n", i);
|
||||
monitor_printf(mon, "memory backend: %s\n", m->value->id);
|
||||
monitor_printf(mon, " size: %" PRId64 "\n", m->value->size);
|
||||
monitor_printf(mon, " merge: %s\n",
|
||||
m->value->merge ? "true" : "false");
|
||||
@ -2103,7 +2098,6 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
|
||||
g_free(str);
|
||||
visit_free(v);
|
||||
m = m->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
monitor_printf(mon, "\n");
|
||||
|
@ -75,23 +75,6 @@ void user_creatable_complete(Object *obj, Error **errp);
|
||||
*/
|
||||
bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add:
|
||||
* @qdict: the object definition
|
||||
* @v: the visitor
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* Create an instance of the user creatable object whose type
|
||||
* is defined in @qdict by the 'qom-type' field, placing it
|
||||
* in the object composition tree with name provided by the
|
||||
* 'id' field. The remaining fields in @qdict are used to
|
||||
* initialize the object properties.
|
||||
*
|
||||
* Returns: the newly created object or NULL on error
|
||||
*/
|
||||
Object *user_creatable_add(const QDict *qdict,
|
||||
Visitor *v, Error **errp);
|
||||
|
||||
/**
|
||||
* user_creatable_add_type:
|
||||
* @type: the object type name
|
||||
|
@ -52,6 +52,7 @@ struct HostMemoryBackend {
|
||||
Object parent;
|
||||
|
||||
/* protected */
|
||||
char *id;
|
||||
uint64_t size;
|
||||
bool merge, dump;
|
||||
bool prealloc, force_prealloc, is_mapped;
|
||||
|
@ -17,7 +17,7 @@ struct numa_addr_range {
|
||||
|
||||
typedef struct node_info {
|
||||
uint64_t node_mem;
|
||||
DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
|
||||
unsigned long *node_cpu;
|
||||
struct HostMemoryBackend *node_memdev;
|
||||
bool present;
|
||||
QLIST_HEAD(, numa_addr_range) addr; /* List to store address ranges */
|
||||
|
@ -168,13 +168,6 @@ extern int mem_prealloc;
|
||||
#define MAX_NODES 128
|
||||
#define NUMA_NODE_UNASSIGNED MAX_NODES
|
||||
|
||||
/* The following shall be true for all CPUs:
|
||||
* cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS
|
||||
*
|
||||
* Note that cpu->get_arch_id() may be larger than MAX_CPUMASK_BITS.
|
||||
*/
|
||||
#define MAX_CPUMASK_BITS 288
|
||||
|
||||
#define MAX_OPTION_ROMS 16
|
||||
typedef struct QEMUOptionRom {
|
||||
const char *name;
|
||||
|
24
numa.c
24
numa.c
@ -266,20 +266,19 @@ static char *enumerate_cpus(unsigned long *cpus, int max_cpus)
|
||||
static void validate_numa_cpus(void)
|
||||
{
|
||||
int i;
|
||||
DECLARE_BITMAP(seen_cpus, MAX_CPUMASK_BITS);
|
||||
unsigned long *seen_cpus = bitmap_new(max_cpus);
|
||||
|
||||
bitmap_zero(seen_cpus, MAX_CPUMASK_BITS);
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
if (bitmap_intersects(seen_cpus, numa_info[i].node_cpu,
|
||||
MAX_CPUMASK_BITS)) {
|
||||
if (bitmap_intersects(seen_cpus, numa_info[i].node_cpu, max_cpus)) {
|
||||
bitmap_and(seen_cpus, seen_cpus,
|
||||
numa_info[i].node_cpu, MAX_CPUMASK_BITS);
|
||||
numa_info[i].node_cpu, max_cpus);
|
||||
error_report("CPU(s) present in multiple NUMA nodes: %s",
|
||||
enumerate_cpus(seen_cpus, max_cpus));
|
||||
g_free(seen_cpus);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
bitmap_or(seen_cpus, seen_cpus,
|
||||
numa_info[i].node_cpu, MAX_CPUMASK_BITS);
|
||||
numa_info[i].node_cpu, max_cpus);
|
||||
}
|
||||
|
||||
if (!bitmap_full(seen_cpus, max_cpus)) {
|
||||
@ -291,12 +290,17 @@ static void validate_numa_cpus(void)
|
||||
"in NUMA config");
|
||||
g_free(msg);
|
||||
}
|
||||
g_free(seen_cpus);
|
||||
}
|
||||
|
||||
void parse_numa_opts(MachineClass *mc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_NODES; i++) {
|
||||
numa_info[i].node_cpu = bitmap_new(max_cpus);
|
||||
}
|
||||
|
||||
if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, NULL, NULL)) {
|
||||
exit(1);
|
||||
}
|
||||
@ -362,7 +366,7 @@ void parse_numa_opts(MachineClass *mc)
|
||||
numa_set_mem_ranges();
|
||||
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
if (!bitmap_empty(numa_info[i].node_cpu, MAX_CPUMASK_BITS)) {
|
||||
if (!bitmap_empty(numa_info[i].node_cpu, max_cpus)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -397,6 +401,7 @@ void numa_post_machine_init(void)
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
assert(cpu->cpu_index < max_cpus);
|
||||
if (test_bit(cpu->cpu_index, numa_info[i].node_cpu)) {
|
||||
cpu->numa_node = i;
|
||||
}
|
||||
@ -518,6 +523,9 @@ static int query_memdev(Object *obj, void *opaque)
|
||||
|
||||
m->value = g_malloc0(sizeof(*m->value));
|
||||
|
||||
m->value->id = object_property_get_str(obj, "id", NULL);
|
||||
m->value->has_id = !!m->value->id;
|
||||
|
||||
m->value->size = object_property_get_int(obj, "size",
|
||||
&error_abort);
|
||||
m->value->merge = object_property_get_bool(obj, "merge",
|
||||
@ -555,6 +563,8 @@ int numa_get_node_for_cpu(int idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(idx < max_cpus);
|
||||
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
if (test_bit(idx, numa_info[i].node_cpu)) {
|
||||
break;
|
||||
|
@ -3221,6 +3221,9 @@
|
||||
# @unavailable-features: #optional List of properties that prevent
|
||||
# the CPU model from running in the current
|
||||
# host. (since 2.8)
|
||||
# @typename: Type name that can be used as argument to @device-list-properties,
|
||||
# to introspect properties configurable using -cpu or -global.
|
||||
# (since 2.9)
|
||||
#
|
||||
# @unavailable-features is a list of QOM property names that
|
||||
# represent CPU model attributes that prevent the CPU from running.
|
||||
@ -3242,7 +3245,7 @@
|
||||
##
|
||||
{ 'struct': 'CpuDefinitionInfo',
|
||||
'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool',
|
||||
'*unavailable-features': [ 'str' ] } }
|
||||
'*unavailable-features': [ 'str' ], 'typename': 'str' } }
|
||||
|
||||
##
|
||||
# @query-cpu-definitions:
|
||||
@ -4457,6 +4460,8 @@
|
||||
#
|
||||
# Information about memory backend
|
||||
#
|
||||
# @id: #optional backend's ID if backend has 'id' property (since 2.9)
|
||||
#
|
||||
# @size: memory backend size
|
||||
#
|
||||
# @merge: enables or disables memory merge support
|
||||
@ -4473,6 +4478,7 @@
|
||||
##
|
||||
{ 'struct': 'Memdev',
|
||||
'data': {
|
||||
'*id': 'str',
|
||||
'size': 'size',
|
||||
'merge': 'bool',
|
||||
'dump': 'bool',
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi-visit.h"
|
||||
#include "qapi/qobject-output-visitor.h"
|
||||
#include "qapi/opts-visitor.h"
|
||||
|
||||
void user_creatable_complete(Object *obj, Error **errp)
|
||||
@ -35,57 +34,6 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object *user_creatable_add(const QDict *qdict,
|
||||
Visitor *v, Error **errp)
|
||||
{
|
||||
char *type = NULL;
|
||||
char *id = NULL;
|
||||
Object *obj = NULL;
|
||||
Error *local_err = NULL;
|
||||
QDict *pdict;
|
||||
|
||||
pdict = qdict_clone_shallow(qdict);
|
||||
|
||||
visit_start_struct(v, NULL, NULL, 0, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
qdict_del(pdict, "qom-type");
|
||||
visit_type_str(v, "qom-type", &type, &local_err);
|
||||
if (local_err) {
|
||||
goto out_visit;
|
||||
}
|
||||
|
||||
qdict_del(pdict, "id");
|
||||
visit_type_str(v, "id", &id, &local_err);
|
||||
if (local_err) {
|
||||
goto out_visit;
|
||||
}
|
||||
visit_check_struct(v, &local_err);
|
||||
if (local_err) {
|
||||
goto out_visit;
|
||||
}
|
||||
|
||||
obj = user_creatable_add_type(type, id, pdict, v, &local_err);
|
||||
|
||||
out_visit:
|
||||
visit_end_struct(v, NULL);
|
||||
|
||||
out:
|
||||
QDECREF(pdict);
|
||||
g_free(id);
|
||||
g_free(type);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
object_unref(obj);
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Object *user_creatable_add_type(const char *type, const char *id,
|
||||
const QDict *qdict,
|
||||
Visitor *v, Error **errp)
|
||||
@ -114,6 +62,12 @@ Object *user_creatable_add_type(const char *type, const char *id,
|
||||
|
||||
assert(qdict);
|
||||
obj = object_new(type);
|
||||
if (object_property_find(obj, "id", NULL)) {
|
||||
object_property_set_str(obj, id, "id", &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
visit_start_struct(v, NULL, NULL, 0, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
@ -158,13 +112,27 @@ Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
|
||||
{
|
||||
Visitor *v;
|
||||
QDict *pdict;
|
||||
Object *obj = NULL;
|
||||
Object *obj;
|
||||
const char *id = qemu_opts_id(opts);
|
||||
const char *type = qemu_opt_get(opts, "qom-type");
|
||||
|
||||
if (!type) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
|
||||
return NULL;
|
||||
}
|
||||
if (!id) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, "id");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdict = qemu_opts_to_qdict(opts, NULL);
|
||||
qdict_del(pdict, "qom-type");
|
||||
qdict_del(pdict, "id");
|
||||
|
||||
v = opts_visitor_new(opts);
|
||||
pdict = qemu_opts_to_qdict(opts, NULL);
|
||||
|
||||
obj = user_creatable_add(pdict, v, errp);
|
||||
obj = user_creatable_add_type(type, id, pdict, v, errp);
|
||||
visit_free(v);
|
||||
|
||||
QDECREF(pdict);
|
||||
return obj;
|
||||
}
|
||||
|
@ -5214,6 +5214,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->name = g_strndup(typename,
|
||||
strlen(typename) - strlen("-" TYPE_ARM_CPU));
|
||||
info->q_typename = g_strdup(typename);
|
||||
|
||||
entry = g_malloc0(sizeof(*entry));
|
||||
entry->value = info;
|
||||
|
@ -2235,6 +2235,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
|
||||
info->name = x86_cpu_class_get_model_name(cc);
|
||||
x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
|
||||
info->has_unavailable_features = true;
|
||||
info->q_typename = g_strdup(object_class_get_name(oc));
|
||||
|
||||
entry = g_malloc0(sizeof(*entry));
|
||||
entry->value = info;
|
||||
|
@ -6443,10 +6443,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||
tcg_const_i32(s->pc - s->cs_base));
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
/* TF handling for the syscall insn is different. The TF bit is checked
|
||||
after the syscall insn completes. This allows #DB to not be
|
||||
generated after one has entered CPL0 if TF is set in FMASK. */
|
||||
gen_eob_worker(s, false, true);
|
||||
gen_eob(s);
|
||||
break;
|
||||
case 0xe8: /* call im */
|
||||
{
|
||||
@ -7124,7 +7121,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||
gen_update_cc_op(s);
|
||||
gen_jmp_im(pc_start - s->cs_base);
|
||||
gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
|
||||
gen_eob(s);
|
||||
/* TF handling for the syscall insn is different. The TF bit is checked
|
||||
after the syscall insn completes. This allows #DB to not be
|
||||
generated after one has entered CPL0 if TF is set in FMASK. */
|
||||
gen_eob_worker(s, false, true);
|
||||
break;
|
||||
case 0x107: /* sysret */
|
||||
if (!s->pe) {
|
||||
|
@ -10305,6 +10305,7 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
||||
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->name = g_strdup(alias->alias);
|
||||
info->q_typename = g_strdup(object_class_get_name(oc));
|
||||
|
||||
entry = g_malloc0(sizeof(*entry));
|
||||
entry->value = info;
|
||||
|
@ -290,6 +290,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
|
||||
info->has_migration_safe = true;
|
||||
info->migration_safe = scc->is_migration_safe;
|
||||
info->q_static = scc->is_static;
|
||||
info->q_typename = g_strdup(object_class_get_name(klass));
|
||||
|
||||
|
||||
entry = g_malloc0(sizeof(*entry));
|
||||
|
5
vl.c
5
vl.c
@ -1277,11 +1277,6 @@ static void smp_parse(QemuOpts *opts)
|
||||
|
||||
max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
|
||||
|
||||
if (max_cpus > MAX_CPUMASK_BITS) {
|
||||
error_report("unsupported number of maxcpus");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (max_cpus < cpus) {
|
||||
error_report("maxcpus must be equal to or greater than smp");
|
||||
exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user