Fix for smp-opts in configuration file.
Update Coverity model to what's currently uploaded. -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmEHw7EUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroPIHwf+OOr857Wkn70dckPGG5MOejR+eATn WXdkb6J9mo953fhiEH3/7tgyAEwh3qHHxCKwJQdY5beTXu2h5fC2WyNadqTBi2ol PnT9T05beFAqyq0SsmMH/0hHNVOO/rPp2FjFce7+8FinW+oqvI9NVkJtjiBdReQw K8ychTJet0UxvQgL755ujT3CcB7q4W3fbPg/a86K14hQndRsjyHiqYb96oNOnHgo vkfI1kA0ljX2A59+nkUzQZwZ00P/6bpk/tXVgLcHWQQHUS+QLMHu+HdvdySeK5mt 7fjEZnELF640YnIHtF8QKgXf1MS0wE4VGL9AmHjCV1zsm7JPiI8sdp2AzQ== =ScAY -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging Fix for smp-opts in configuration file. Update Coverity model to what's currently uploaded. # gpg: Signature made Mon 02 Aug 2021 11:06:41 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # 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-gitlab/tags/for-upstream: coverity-model: write models fully for non-array allocation functions coverity-model: constrain g_malloc/g_malloc0/g_realloc as never returning NULL coverity-model: clean up the models for array allocation functions coverity-model: remove model for more allocation functions coverity-model: make g_free a synonym of free coverity-model: update address_space_read/write models vl: stop recording -smp in QemuOpts vl: introduce machine_merge_property Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7f1cab9c62
@ -45,9 +45,10 @@ typedef struct va_list_str *va_list;
|
|||||||
/* exec.c */
|
/* exec.c */
|
||||||
|
|
||||||
typedef struct AddressSpace AddressSpace;
|
typedef struct AddressSpace AddressSpace;
|
||||||
|
typedef struct MemoryRegionCache MemoryRegionCache;
|
||||||
typedef uint64_t hwaddr;
|
typedef uint64_t hwaddr;
|
||||||
typedef uint32_t MemTxResult;
|
typedef uint32_t MemTxResult;
|
||||||
typedef uint64_t MemTxAttrs;
|
typedef struct MemTxAttrs {} MemTxAttrs;
|
||||||
|
|
||||||
static void __bufwrite(uint8_t *buf, ssize_t len)
|
static void __bufwrite(uint8_t *buf, ssize_t len)
|
||||||
{
|
{
|
||||||
@ -67,9 +68,40 @@ static void __bufread(uint8_t *buf, ssize_t len)
|
|||||||
int last = buf[len-1];
|
int last = buf[len-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||||
|
MemTxAttrs attrs,
|
||||||
|
void *buf, int len)
|
||||||
|
{
|
||||||
|
MemTxResult result;
|
||||||
|
// TODO: investigate impact of treating reads as producing
|
||||||
|
// tainted data, with __coverity_tainted_data_argument__(buf).
|
||||||
|
__bufwrite(buf, len);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||||
|
MemTxAttrs attrs,
|
||||||
|
const void *buf, int len)
|
||||||
|
{
|
||||||
|
MemTxResult result;
|
||||||
|
__bufread(buf, len);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_rw_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||||
|
MemTxAttrs attrs,
|
||||||
|
void *buf, int len, bool is_write)
|
||||||
|
{
|
||||||
|
if (is_write) {
|
||||||
|
return address_space_write_cached(cache, addr, attrs, buf, len);
|
||||||
|
} else {
|
||||||
|
return address_space_read_cached(cache, addr, attrs, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
||||||
MemTxAttrs attrs,
|
MemTxAttrs attrs,
|
||||||
uint8_t *buf, int len)
|
void *buf, int len)
|
||||||
{
|
{
|
||||||
MemTxResult result;
|
MemTxResult result;
|
||||||
// TODO: investigate impact of treating reads as producing
|
// TODO: investigate impact of treating reads as producing
|
||||||
@ -80,13 +112,23 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
|||||||
|
|
||||||
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
|
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
|
||||||
MemTxAttrs attrs,
|
MemTxAttrs attrs,
|
||||||
const uint8_t *buf, int len)
|
const void *buf, int len)
|
||||||
{
|
{
|
||||||
MemTxResult result;
|
MemTxResult result;
|
||||||
__bufread(buf, len);
|
__bufread(buf, len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
|
||||||
|
MemTxAttrs attrs,
|
||||||
|
void *buf, int len, bool is_write)
|
||||||
|
{
|
||||||
|
if (is_write) {
|
||||||
|
return address_space_write(as, addr, attrs, buf, len);
|
||||||
|
} else {
|
||||||
|
return address_space_read(as, addr, attrs, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tainting */
|
/* Tainting */
|
||||||
|
|
||||||
@ -136,54 +178,56 @@ uint8_t replay_get_byte(void)
|
|||||||
|
|
||||||
void *g_malloc_n(size_t nmemb, size_t size)
|
void *g_malloc_n(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
size_t sz;
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
__coverity_negative_sink__(nmemb);
|
__coverity_negative_sink__(nmemb);
|
||||||
__coverity_negative_sink__(size);
|
__coverity_negative_sink__(size);
|
||||||
sz = nmemb * size;
|
ptr = __coverity_alloc__(nmemb * size);
|
||||||
ptr = __coverity_alloc__(sz);
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
__coverity_mark_as_uninitialized_buffer__(ptr);
|
__coverity_mark_as_uninitialized_buffer__(ptr);
|
||||||
__coverity_mark_as_afm_allocated__(ptr, "g_free");
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_malloc0_n(size_t nmemb, size_t size)
|
void *g_malloc0_n(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
size_t sz;
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
__coverity_negative_sink__(nmemb);
|
__coverity_negative_sink__(nmemb);
|
||||||
__coverity_negative_sink__(size);
|
__coverity_negative_sink__(size);
|
||||||
sz = nmemb * size;
|
ptr = __coverity_alloc__(nmemb * size);
|
||||||
ptr = __coverity_alloc__(sz);
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
__coverity_writeall0__(ptr);
|
__coverity_writeall0__(ptr);
|
||||||
__coverity_mark_as_afm_allocated__(ptr, "g_free");
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
|
void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
size_t sz;
|
|
||||||
|
|
||||||
__coverity_negative_sink__(nmemb);
|
__coverity_negative_sink__(nmemb);
|
||||||
__coverity_negative_sink__(size);
|
__coverity_negative_sink__(size);
|
||||||
sz = nmemb * size;
|
|
||||||
__coverity_escape__(ptr);
|
__coverity_escape__(ptr);
|
||||||
ptr = __coverity_alloc__(sz);
|
ptr = __coverity_alloc__(nmemb * size);
|
||||||
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Memory beyond the old size isn't actually initialized. Can't
|
* Memory beyond the old size isn't actually initialized. Can't
|
||||||
* model that. See Coverity's realloc() model
|
* model that. See Coverity's realloc() model
|
||||||
*/
|
*/
|
||||||
__coverity_writeall__(ptr);
|
__coverity_writeall__(ptr);
|
||||||
__coverity_mark_as_afm_allocated__(ptr, "g_free");
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_free(void *ptr)
|
void g_free(void *ptr)
|
||||||
{
|
{
|
||||||
__coverity_free__(ptr);
|
__coverity_free__(ptr);
|
||||||
__coverity_mark_as_afm_freed__(ptr, "g_free");
|
__coverity_mark_as_afm_freed__(ptr, AFM_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -221,140 +265,81 @@ void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
|
|||||||
return g_realloc_n(ptr, nmemb, size);
|
return g_realloc_n(ptr, nmemb, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trivially derive the g_FOO() from the g_FOO_n() */
|
/* Derive the g_FOO() from the g_FOO_n() */
|
||||||
|
|
||||||
void *g_malloc(size_t size)
|
void *g_malloc(size_t size)
|
||||||
{
|
{
|
||||||
return g_malloc_n(1, size);
|
void *ptr;
|
||||||
|
|
||||||
|
__coverity_negative_sink__(size);
|
||||||
|
ptr = __coverity_alloc__(size);
|
||||||
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
|
__coverity_mark_as_uninitialized_buffer__(ptr);
|
||||||
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_malloc0(size_t size)
|
void *g_malloc0(size_t size)
|
||||||
{
|
{
|
||||||
return g_malloc0_n(1, size);
|
void *ptr;
|
||||||
|
|
||||||
|
__coverity_negative_sink__(size);
|
||||||
|
ptr = __coverity_alloc__(size);
|
||||||
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
|
__coverity_writeall0__(ptr);
|
||||||
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_realloc(void *ptr, size_t size)
|
void *g_realloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
return g_realloc_n(ptr, 1, size);
|
__coverity_negative_sink__(size);
|
||||||
|
__coverity_escape__(ptr);
|
||||||
|
ptr = __coverity_alloc__(size);
|
||||||
|
if (!ptr) {
|
||||||
|
__coverity_panic__();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Memory beyond the old size isn't actually initialized. Can't
|
||||||
|
* model that. See Coverity's realloc() model
|
||||||
|
*/
|
||||||
|
__coverity_writeall__(ptr);
|
||||||
|
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_try_malloc(size_t size)
|
void *g_try_malloc(size_t size)
|
||||||
{
|
{
|
||||||
return g_try_malloc_n(1, size);
|
int nomem;
|
||||||
|
|
||||||
|
if (nomem) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return g_malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_try_malloc0(size_t size)
|
void *g_try_malloc0(size_t size)
|
||||||
{
|
{
|
||||||
return g_try_malloc0_n(1, size);
|
int nomem;
|
||||||
|
|
||||||
|
if (nomem) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return g_malloc0(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *g_try_realloc(void *ptr, size_t size)
|
void *g_try_realloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
return g_try_realloc_n(ptr, 1, size);
|
int nomem;
|
||||||
}
|
|
||||||
|
|
||||||
/* Other memory allocation functions */
|
if (nomem) {
|
||||||
|
|
||||||
void *g_memdup(const void *ptr, unsigned size)
|
|
||||||
{
|
|
||||||
unsigned char *dup;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if (!ptr) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return g_realloc(ptr, size);
|
||||||
dup = g_malloc(size);
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
dup[i] = ((unsigned char *)ptr)[i];
|
|
||||||
return dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GLib string allocation functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *g_strdup(const char *s)
|
|
||||||
{
|
|
||||||
char *dup;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!s) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
__coverity_string_null_sink__(s);
|
|
||||||
__coverity_string_size_sink__(s);
|
|
||||||
dup = __coverity_alloc_nosize__();
|
|
||||||
__coverity_mark_as_afm_allocated__(dup, "g_free");
|
|
||||||
for (i = 0; (dup[i] = s[i]); i++) ;
|
|
||||||
return dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *g_strndup(const char *s, size_t n)
|
|
||||||
{
|
|
||||||
char *dup;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
__coverity_negative_sink__(n);
|
|
||||||
|
|
||||||
if (!s) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dup = g_malloc(n + 1);
|
|
||||||
for (i = 0; i < n && (dup[i] = s[i]); i++) ;
|
|
||||||
dup[i] = 0;
|
|
||||||
return dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *g_strdup_printf(const char *format, ...)
|
|
||||||
{
|
|
||||||
char ch, *s;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
__coverity_string_null_sink__(format);
|
|
||||||
__coverity_string_size_sink__(format);
|
|
||||||
|
|
||||||
ch = *format;
|
|
||||||
|
|
||||||
s = __coverity_alloc_nosize__();
|
|
||||||
__coverity_writeall__(s);
|
|
||||||
__coverity_mark_as_afm_allocated__(s, "g_free");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *g_strdup_vprintf(const char *format, va_list ap)
|
|
||||||
{
|
|
||||||
char ch, *s;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
__coverity_string_null_sink__(format);
|
|
||||||
__coverity_string_size_sink__(format);
|
|
||||||
|
|
||||||
ch = *format;
|
|
||||||
ch = *(char *)ap;
|
|
||||||
|
|
||||||
s = __coverity_alloc_nosize__();
|
|
||||||
__coverity_writeall__(s);
|
|
||||||
__coverity_mark_as_afm_allocated__(s, "g_free");
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *g_strconcat(const char *s, ...)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Can't model: last argument must be null, the others
|
|
||||||
* null-terminated strings
|
|
||||||
*/
|
|
||||||
|
|
||||||
s = __coverity_alloc_nosize__();
|
|
||||||
__coverity_writeall__(s);
|
|
||||||
__coverity_mark_as_afm_allocated__(s, "g_free");
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other glib functions */
|
/* Other glib functions */
|
||||||
|
47
softmmu/vl.c
47
softmmu/vl.c
@ -31,6 +31,7 @@
|
|||||||
#include "qapi/compat-policy.h"
|
#include "qapi/compat-policy.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qemu-version.h"
|
#include "qemu-version.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
@ -1534,23 +1535,36 @@ static void machine_help_func(const QDict *qdict)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
machine_merge_property(const char *propname, QDict *prop, Error **errp)
|
||||||
|
{
|
||||||
|
QDict *opts;
|
||||||
|
|
||||||
|
opts = qdict_new();
|
||||||
|
/* Preserve the caller's reference to prop. */
|
||||||
|
qobject_ref(prop);
|
||||||
|
qdict_put(opts, propname, prop);
|
||||||
|
keyval_merge(machine_opts_dict, opts, errp);
|
||||||
|
qobject_unref(opts);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
machine_parse_property_opt(QemuOptsList *opts_list, const char *propname,
|
machine_parse_property_opt(QemuOptsList *opts_list, const char *propname,
|
||||||
const char *arg, Error **errp)
|
const char *arg, Error **errp)
|
||||||
{
|
{
|
||||||
QDict *opts, *prop;
|
QDict *prop = NULL;
|
||||||
bool help = false;
|
bool help = false;
|
||||||
ERRP_GUARD();
|
|
||||||
|
|
||||||
prop = keyval_parse(arg, opts_list->implied_opt_name, &help, errp);
|
prop = keyval_parse(arg, opts_list->implied_opt_name, &help, errp);
|
||||||
if (help) {
|
if (help) {
|
||||||
qemu_opts_print_help(opts_list, true);
|
qemu_opts_print_help(opts_list, true);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
opts = qdict_new();
|
if (!prop) {
|
||||||
qdict_put(opts, propname, prop);
|
return;
|
||||||
keyval_merge(machine_opts_dict, opts, errp);
|
}
|
||||||
qobject_unref(opts);
|
machine_merge_property(propname, prop, errp);
|
||||||
|
qobject_unref(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *pid_file;
|
static const char *pid_file;
|
||||||
@ -2153,7 +2167,8 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
static bool is_qemuopts_group(const char *group)
|
static bool is_qemuopts_group(const char *group)
|
||||||
{
|
{
|
||||||
if (g_str_equal(group, "object") ||
|
if (g_str_equal(group, "object") ||
|
||||||
g_str_equal(group, "machine")) {
|
g_str_equal(group, "machine") ||
|
||||||
|
g_str_equal(group, "smp-opts")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -2173,6 +2188,8 @@ static void qemu_record_config_group(const char *group, QDict *dict,
|
|||||||
*/
|
*/
|
||||||
assert(!from_json);
|
assert(!from_json);
|
||||||
keyval_merge(machine_opts_dict, dict, errp);
|
keyval_merge(machine_opts_dict, dict, errp);
|
||||||
|
} else if (g_str_equal(group, "smp-opts")) {
|
||||||
|
machine_merge_property("smp", dict, &error_fatal);
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -2439,13 +2456,15 @@ static void qemu_validate_options(const QDict *machine_opts)
|
|||||||
static void qemu_process_sugar_options(void)
|
static void qemu_process_sugar_options(void)
|
||||||
{
|
{
|
||||||
if (mem_prealloc) {
|
if (mem_prealloc) {
|
||||||
char *val;
|
QObject *smp = qdict_get(machine_opts_dict, "smp");
|
||||||
|
if (smp && qobject_type(smp) == QTYPE_QDICT) {
|
||||||
val = g_strdup_printf("%d",
|
QObject *cpus = qdict_get(qobject_to(QDict, smp), "cpus");
|
||||||
(uint32_t) qemu_opt_get_number(qemu_find_opts_singleton("smp-opts"), "cpus", 1));
|
if (cpus && qobject_type(cpus) == QTYPE_QSTRING) {
|
||||||
object_register_sugar_prop("memory-backend", "prealloc-threads", val,
|
const char *val = qstring_get_str(qobject_to(QString, cpus));
|
||||||
false);
|
object_register_sugar_prop("memory-backend", "prealloc-threads",
|
||||||
g_free(val);
|
val, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
object_register_sugar_prop("memory-backend", "prealloc", "on", false);
|
object_register_sugar_prop("memory-backend", "prealloc", "on", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user