* Don't silently truncate extremely long words in the command line

* dtc configure fixes
 * MemoryRegionCache second try
 * Deprecated option removal
 * add support for Hyper-V reenlightenment MSRs
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJa9Y2qAAoJEL/70l94x66Df8EIAI4pi+zf1mTlH0Koi+oqOg+d
 geBC6N9IA+n1p90XERnPbuiT19NjON2R1Z907SbzDkijxdNRoYUoQf7Z+ZBTENjn
 dYsVvgLYzajGLWWtJetPPaNFAqeF2z8B3lbVQnGVLzH5pQQ2NS1NJsvXQA2LslLs
 2ll1CJ2EEBhayoBSbHK+0cY85f+DUgK/T1imIV2T/rwcef9Rw218nvPfGhPBSoL6
 tI2xIOxz8bBOvZNg2wdxpaoPuDipBFu6koVVbaGSgXORg8k5CEcKNxInztufdELW
 KZK5ORa3T0uqu5T/GGPAfm/NbYVQ4aTB5mddshsXtKbBhnbSfRYvpVsR4kQB/Hc=
 =oC1r
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* Don't silently truncate extremely long words in the command line
* dtc configure fixes
* MemoryRegionCache second try
* Deprecated option removal
* add support for Hyper-V reenlightenment MSRs

# gpg: Signature made Fri 11 May 2018 13:33:46 BST
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# 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: (29 commits)
  rename included C files to foo.inc.c, remove osdep.h
  pc-dimm: fix error messages if no slots were defined
  build: Silence dtc directory creation
  shippable: Remove Debian 8 libfdt kludge
  configure: Display if libfdt is from system or git
  configure: Really use local libfdt if the system one is too old
  i386/kvm: add support for Hyper-V reenlightenment MSRs
  qemu-doc: provide details of supported build platforms
  qemu-options: Remove deprecated -no-kvm-irqchip
  qemu-options: Remove deprecated -no-kvm-pit-reinjection
  qemu-options: Bail out on unsupported options instead of silently ignoring them
  qemu-options: Remove remainders of the -tdf option
  qemu-options: Mark -virtioconsole as deprecated
  target/i386: sev: fix memory leaks
  opts: don't silently truncate long option values
  opts: don't silently truncate long parameter keys
  accel: use g_strsplit for parsing accelerator names
  update-linux-headers: drop hyperv.h
  qemu-thread: always keep the posix wrapper layer
  exec: reintroduce MemoryRegion caching
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-05-14 09:55:08 +01:00
commit 9ba1733a76
51 changed files with 1025 additions and 617 deletions

View File

@ -35,13 +35,5 @@ build:
options: "-e HOME=/root"
ci:
- unset CC
# some targets require newer up to date packages, for example TARGET_LIST matching
# aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
# see the configure script:
# error_exit "DTC (libfdt) version >= 1.4.2 not present. Your options:"
# " (1) Preferred: Install the DTC (libfdt) devel package"
# " (2) Fetch the DTC submodule, using:"
# " git submodule update --init dtc"
- dpkg --compare-versions `dpkg-query --showformat='${Version}' --show libfdt-dev` ge 1.4.2 || git submodule update --init dtc
- ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST}
- make -j$(($(getconf _NPROCESSORS_ONLN) + 1))

View File

@ -485,7 +485,7 @@ subdir-dtc: .git-submodule-status dtc/libfdt dtc/tests
$(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt/libfdt.a,)
dtc/%: .git-submodule-status
mkdir -p $@
@mkdir -p $@
# Overriding CFLAGS causes us to lose defines added in the sub-makefile.
# Not overriding CFLAGS leads to mis-matches between compilation modes.

View File

@ -70,8 +70,8 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
void configure_accelerator(MachineState *ms)
{
const char *accel, *p;
char buf[10];
const char *accel;
char **accel_list, **tmp;
int ret;
bool accel_initialised = false;
bool init_failed = false;
@ -83,13 +83,10 @@ void configure_accelerator(MachineState *ms)
accel = "tcg";
}
p = accel;
while (!accel_initialised && *p != '\0') {
if (*p == ':') {
p++;
}
p = get_opt_name(buf, sizeof(buf), p, ':');
acc = accel_find(buf);
accel_list = g_strsplit(accel, ":", 0);
for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) {
acc = accel_find(*tmp);
if (!acc) {
continue;
}
@ -107,6 +104,7 @@ void configure_accelerator(MachineState *ms)
accel_initialised = true;
}
}
g_strfreev(accel_list);
if (!accel_initialised) {
if (!init_failed) {

View File

@ -369,24 +369,6 @@ host_memory_backend_can_be_deleted(UserCreatable *uc)
}
}
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 bool host_memory_backend_get_share(Object *o, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(o);
@ -434,18 +416,11 @@ 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);
object_class_property_add_bool(oc, "share",
host_memory_backend_get_share, host_memory_backend_set_share,
&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 = {
.name = TYPE_MEMORY_BACKEND,
.parent = TYPE_OBJECT,
@ -454,7 +429,6 @@ 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 },
{ }

17
configure vendored
View File

@ -964,6 +964,8 @@ for opt do
;;
--firmwarepath=*) firmwarepath="$optarg"
;;
--host=*|--build=*|\
--disable-dependency-tracking|\
--sbindir=*|--sharedstatedir=*|\
--oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
--htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
@ -3787,22 +3789,22 @@ int main(void) { fdt_first_subnode(0, 0); return 0; }
EOF
if compile_prog "" "$fdt_libs" ; then
# system DTC is good - use it
fdt=yes
fdt=system
else
# have GIT checkout, so activate dtc submodule
if test -e "${source_path}/.git" ; then
git_submodules="${git_submodules} dtc"
fi
if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then
fdt=yes
dtc_internal="yes"
fdt=git
mkdir -p dtc
if [ "$pwd_is_source_path" != "y" ] ; then
symlink "$source_path/dtc/Makefile" "dtc/Makefile"
symlink "$source_path/dtc/scripts" "dtc/scripts"
fi
fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt"
fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs"
fdt_ldflags="-L\$(BUILD_DIR)/dtc/libfdt"
fdt_libs="$fdt_libs"
elif test "$fdt" = "yes" ; then
# Not a git build & no libfdt found, prompt for system install
error_exit "DTC (libfdt) version >= 1.4.2 not present." \
@ -5744,6 +5746,7 @@ echo_version() {
# prepend pixman and ftd flags after all config tests are done
QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
QEMU_LDFLAGS="$fdt_ldflags $QEMU_LDFLAGS"
libs_softmmu="$pixman_libs $libs_softmmu"
echo "Install prefix $prefix"
@ -5774,6 +5777,7 @@ echo "ARFLAGS $ARFLAGS"
echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS"
echo "LDFLAGS $LDFLAGS"
echo "QEMU_LDFLAGS $QEMU_LDFLAGS"
echo "make $make"
echo "install $install"
echo "python $python"
@ -6333,7 +6337,7 @@ fi
if test "$preadv" = "yes" ; then
echo "CONFIG_PREADV=y" >> $config_host_mak
fi
if test "$fdt" = "yes" ; then
if test "$fdt" != "no" ; then
echo "CONFIG_FDT=y" >> $config_host_mak
fi
if test "$membarrier" = "yes" ; then
@ -6708,6 +6712,7 @@ else
fi
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
echo "LIBS+=$LIBS" >> $config_host_mak
@ -7134,7 +7139,7 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
done # for target in $targets
if [ "$dtc_internal" = "yes" ]; then
if [ "$fdt" = "git" ]; then
echo "config-host.h: subdir-dtc" >> $config_host_mak
fi
if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then

18
cpus.c
View File

@ -1648,7 +1648,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* process any pending work */
cpu->exit_request = 1;
while (1) {
do {
if (cpu_can_run(cpu)) {
int r;
qemu_mutex_unlock_iothread();
@ -2043,7 +2043,6 @@ int vm_stop(RunState state)
int vm_prepare_start(void)
{
RunState requested;
int res = 0;
qemu_vmstop_requested(&requested);
if (runstate_is_running() && requested == RUN_STATE__MAX) {
@ -2057,17 +2056,18 @@ int vm_prepare_start(void)
*/
if (runstate_is_running()) {
qapi_event_send_stop(&error_abort);
res = -1;
} else {
replay_enable_events();
cpu_enable_ticks();
runstate_set(RUN_STATE_RUNNING);
vm_state_notify(1, RUN_STATE_RUNNING);
qapi_event_send_resume(&error_abort);
return -1;
}
/* We are sending this now, but the CPUs will be resumed shortly later */
qapi_event_send_resume(&error_abort);
return res;
replay_enable_events();
cpu_enable_ticks();
runstate_set(RUN_STATE_RUNNING);
vm_state_notify(1, RUN_STATE_RUNNING);
return 0;
}
void vm_start(void)

242
exec.c
View File

@ -461,6 +461,70 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
return section;
}
/**
* address_space_translate_iommu - translate an address through an IOMMU
* memory region and then through the target address space.
*
* @iommu_mr: the IOMMU memory region that we start the translation from
* @addr: the address to be translated through the MMU
* @xlat: the translated address offset within the destination memory region.
* It cannot be %NULL.
* @plen_out: valid read/write length of the translated address. It
* cannot be %NULL.
* @page_mask_out: page mask for the translated address. This
* should only be meaningful for IOMMU translated
* addresses, since there may be huge pages that this bit
* would tell. It can be %NULL if we don't care about it.
* @is_write: whether the translation operation is for write
* @is_mmio: whether this can be MMIO, set true if it can
* @target_as: the address space targeted by the IOMMU
*
* This function is called from RCU critical section. It is the common
* part of flatview_do_translate and address_space_translate_cached.
*/
static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iommu_mr,
hwaddr *xlat,
hwaddr *plen_out,
hwaddr *page_mask_out,
bool is_write,
bool is_mmio,
AddressSpace **target_as)
{
MemoryRegionSection *section;
hwaddr page_mask = (hwaddr)-1;
do {
hwaddr addr = *xlat;
IOMMUMemoryRegionClass *imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
IOMMUTLBEntry iotlb = imrc->translate(iommu_mr, addr, is_write ?
IOMMU_WO : IOMMU_RO);
if (!(iotlb.perm & (1 << is_write))) {
goto unassigned;
}
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
page_mask &= iotlb.addr_mask;
*plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1);
*target_as = iotlb.target_as;
section = address_space_translate_internal(
address_space_to_dispatch(iotlb.target_as), addr, xlat,
plen_out, is_mmio);
iommu_mr = memory_region_get_iommu(section->mr);
} while (unlikely(iommu_mr));
if (page_mask_out) {
*page_mask_out = page_mask;
}
return *section;
unassigned:
return (MemoryRegionSection) { .mr = &io_mem_unassigned };
}
/**
* flatview_do_translate - translate an address in FlatView
*
@ -476,6 +540,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
* would tell. It can be @NULL if we don't care about it.
* @is_write: whether the translation operation is for write
* @is_mmio: whether this can be MMIO, set true if it can
* @target_as: the address space targeted by the IOMMU
*
* This function is called from RCU critical section
*/
@ -488,61 +553,31 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
bool is_mmio,
AddressSpace **target_as)
{
IOMMUTLBEntry iotlb;
MemoryRegionSection *section;
IOMMUMemoryRegion *iommu_mr;
IOMMUMemoryRegionClass *imrc;
hwaddr page_mask = (hwaddr)(-1);
hwaddr plen = (hwaddr)(-1);
if (plen_out) {
plen = *plen_out;
if (!plen_out) {
plen_out = &plen;
}
for (;;) {
section = address_space_translate_internal(
flatview_to_dispatch(fv), addr, &addr,
&plen, is_mmio);
section = address_space_translate_internal(
flatview_to_dispatch(fv), addr, xlat,
plen_out, is_mmio);
iommu_mr = memory_region_get_iommu(section->mr);
if (!iommu_mr) {
break;
}
imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
iotlb = imrc->translate(iommu_mr, addr, is_write ?
IOMMU_WO : IOMMU_RO);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
page_mask &= iotlb.addr_mask;
plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) {
goto translate_fail;
}
fv = address_space_to_flatview(iotlb.target_as);
*target_as = iotlb.target_as;
iommu_mr = memory_region_get_iommu(section->mr);
if (unlikely(iommu_mr)) {
return address_space_translate_iommu(iommu_mr, xlat,
plen_out, page_mask_out,
is_write, is_mmio,
target_as);
}
*xlat = addr;
if (page_mask == (hwaddr)(-1)) {
/* Not behind an IOMMU, use default page size. */
page_mask = ~TARGET_PAGE_MASK;
}
if (page_mask_out) {
*page_mask_out = page_mask;
}
if (plen_out) {
*plen_out = plen;
/* Not behind an IOMMU, use default page size. */
*page_mask_out = ~TARGET_PAGE_MASK;
}
return *section;
translate_fail:
return (MemoryRegionSection) { .mr = &io_mem_unassigned };
}
/* Called from RCU critical section */
@ -3606,33 +3641,130 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
hwaddr len,
bool is_write)
{
cache->len = len;
cache->as = as;
cache->xlat = addr;
return len;
AddressSpaceDispatch *d;
hwaddr l;
MemoryRegion *mr;
assert(len > 0);
l = len;
cache->fv = address_space_get_flatview(as);
d = flatview_to_dispatch(cache->fv);
cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true);
mr = cache->mrs.mr;
memory_region_ref(mr);
if (memory_access_is_direct(mr, is_write)) {
l = flatview_extend_translation(cache->fv, addr, len, mr,
cache->xlat, l, is_write);
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
} else {
cache->ptr = NULL;
}
cache->len = l;
cache->is_write = is_write;
return l;
}
void address_space_cache_invalidate(MemoryRegionCache *cache,
hwaddr addr,
hwaddr access_len)
{
assert(cache->is_write);
if (likely(cache->ptr)) {
invalidate_and_set_dirty(cache->mrs.mr, addr + cache->xlat, access_len);
}
}
void address_space_cache_destroy(MemoryRegionCache *cache)
{
cache->as = NULL;
if (!cache->mrs.mr) {
return;
}
if (xen_enabled()) {
xen_invalidate_map_cache_entry(cache->ptr);
}
memory_region_unref(cache->mrs.mr);
flatview_unref(cache->fv);
cache->mrs.mr = NULL;
cache->fv = NULL;
}
/* Called from RCU critical section. This function has the same
* semantics as address_space_translate, but it only works on a
* predefined range of a MemoryRegion that was mapped with
* address_space_cache_init.
*/
static inline MemoryRegion *address_space_translate_cached(
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
hwaddr *plen, bool is_write)
{
MemoryRegionSection section;
MemoryRegion *mr;
IOMMUMemoryRegion *iommu_mr;
AddressSpace *target_as;
assert(!cache->ptr);
*xlat = addr + cache->xlat;
mr = cache->mrs.mr;
iommu_mr = memory_region_get_iommu(mr);
if (!iommu_mr) {
/* MMIO region. */
return mr;
}
section = address_space_translate_iommu(iommu_mr, xlat, plen,
NULL, is_write, true,
&target_as);
return section.mr;
}
/* Called from RCU critical section. address_space_read_cached uses this
* out of line function when the target is an MMIO or IOMMU region.
*/
void
address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
void *buf, int len)
{
hwaddr addr1, l;
MemoryRegion *mr;
l = len;
mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
flatview_read_continue(cache->fv,
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
addr1, l, mr);
}
/* Called from RCU critical section. address_space_write_cached uses this
* out of line function when the target is an MMIO or IOMMU region.
*/
void
address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
const void *buf, int len)
{
hwaddr addr1, l;
MemoryRegion *mr;
l = len;
mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
flatview_write_continue(cache->fv,
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
addr1, l, mr);
}
#define ARG1_DECL MemoryRegionCache *cache
#define ARG1 cache
#define SUFFIX _cached
#define TRANSLATE(addr, ...) \
address_space_translate(cache->as, cache->xlat + (addr), __VA_ARGS__)
#define IS_DIRECT(mr, is_write) true
#define MAP_RAM(mr, ofs) qemu_map_ram_ptr((mr)->ram_block, ofs)
#define SUFFIX _cached_slow
#define TRANSLATE(...) address_space_translate_cached(cache, __VA_ARGS__)
#define IS_DIRECT(mr, is_write) memory_access_is_direct(mr, is_write)
#define MAP_RAM(mr, ofs) (cache->ptr + (ofs - cache->xlat))
#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
#define RCU_READ_LOCK() rcu_read_lock()
#define RCU_READ_UNLOCK() rcu_read_unlock()
#define RCU_READ_LOCK() ((void)0)
#define RCU_READ_UNLOCK() ((void)0)
#include "memory_ldst.inc.c"
/* virtual memory access for debug (includes writing to ROM) */

View File

@ -291,12 +291,16 @@ int load_multiboot(FWCfgState *fw_cfg,
cmdline_len = strlen(kernel_filename) + 1;
cmdline_len += strlen(kernel_cmdline) + 1;
if (initrd_filename) {
const char *r = initrd_filename;
const char *r = get_opt_value(initrd_filename, NULL);
cmdline_len += strlen(r) + 1;
mbs.mb_mods_avail = 1;
while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
while (1) {
mbs.mb_mods_avail++;
r = get_opt_value(r, NULL);
if (!*r) {
break;
}
r++;
}
}
@ -313,7 +317,8 @@ int load_multiboot(FWCfgState *fw_cfg,
if (initrd_filename) {
const char *next_initrd;
char not_last, tmpbuf[strlen(initrd_filename) + 1];
char not_last;
char *one_file = NULL;
mbs.offset_mods = mbs.mb_buf_size;
@ -322,24 +327,26 @@ int load_multiboot(FWCfgState *fw_cfg,
int mb_mod_length;
uint32_t offs = mbs.mb_buf_size;
next_initrd = get_opt_value(tmpbuf, sizeof(tmpbuf), initrd_filename);
next_initrd = get_opt_value(initrd_filename, &one_file);
not_last = *next_initrd;
/* if a space comes after the module filename, treat everything
after that as parameters */
hwaddr c = mb_add_cmdline(&mbs, tmpbuf);
if ((next_space = strchr(tmpbuf, ' ')))
hwaddr c = mb_add_cmdline(&mbs, one_file);
next_space = strchr(one_file, ' ');
if (next_space) {
*next_space = '\0';
mb_debug("multiboot loading module: %s", tmpbuf);
mb_mod_length = get_image_size(tmpbuf);
}
mb_debug("multiboot loading module: %s", one_file);
mb_mod_length = get_image_size(one_file);
if (mb_mod_length < 0) {
error_report("Failed to open file '%s'", tmpbuf);
error_report("Failed to open file '%s'", one_file);
exit(1);
}
mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size);
mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
load_image(tmpbuf, (unsigned char *)mbs.mb_buf + offs);
load_image(one_file, (unsigned char *)mbs.mb_buf + offs);
mb_add_mod(&mbs, mbs.mb_buf_phys + offs,
mbs.mb_buf_phys + offs + mb_mod_length, c);
@ -347,6 +354,8 @@ int load_multiboot(FWCfgState *fw_cfg,
(char *)mbs.mb_buf + offs,
(char *)mbs.mb_buf + offs + mb_mod_length, c);
initrd_filename = next_initrd+1;
g_free(one_file);
one_file = NULL;
} while (not_last);
}

View File

@ -118,9 +118,16 @@ static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp)
{
unsigned long *bitmap = bitmap_new(max_slots);
unsigned long *bitmap;
int slot = 0;
if (max_slots <= 0) {
error_setg(errp, "no slots where allocated, please specify "
"the 'slots' option");
return slot;
}
bitmap = bitmap_new(max_slots);
object_child_foreach(qdev_get_machine(), pc_dimm_slot2bitmap, bitmap);
/* check if requested slot is not occupied */

View File

@ -168,51 +168,40 @@ extern unsigned long reserved_va;
#else
#include "exec/hwaddr.h"
uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
#define SUFFIX
#define ARG1 as
#define ARG1_DECL AddressSpace *as
#define TARGET_ENDIANNESS
#include "exec/memory_ldst.inc.h"
uint32_t lduw_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint32_t ldl_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint64_t ldq_phys_cached(MemoryRegionCache *cache, hwaddr addr);
void stl_phys_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stw_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stl_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stq_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
#define SUFFIX _cached_slow
#define ARG1 cache
#define ARG1_DECL MemoryRegionCache *cache
#define TARGET_ENDIANNESS
#include "exec/memory_ldst.inc.h"
uint32_t address_space_lduw_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_notdirty_cached(MemoryRegionCache *cache, hwaddr addr,
uint32_t val, MemTxAttrs attrs, MemTxResult *result);
void address_space_stw_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
{
address_space_stl_notdirty(as, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
#define SUFFIX
#define ARG1 as
#define ARG1_DECL AddressSpace *as
#define TARGET_ENDIANNESS
#include "exec/memory_ldst_phys.inc.h"
/* Inline fast path for direct RAM access. */
#define ENDIANNESS
#include "exec/memory_ldst_cached.inc.h"
#define SUFFIX _cached
#define ARG1 cache
#define ARG1_DECL MemoryRegionCache *cache
#define TARGET_ENDIANNESS
#include "exec/memory_ldst_phys.inc.h"
#endif
/* page related stuff */

View File

@ -31,6 +31,9 @@ static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
return flatview_to_dispatch(address_space_to_flatview(as));
}
FlatView *address_space_get_flatview(AddressSpace *as);
void flatview_unref(FlatView *view);
extern const MemoryRegionOps unassigned_mem_ops;
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,

View File

@ -1676,57 +1676,91 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
* @result: location to write the success/failure of the transaction;
* if NULL, this information is discarded
*/
uint32_t address_space_ldub(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
uint32_t ldub_phys(AddressSpace *as, hwaddr addr);
uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr);
uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr);
uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr);
uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr);
uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr);
uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr);
void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
#define SUFFIX
#define ARG1 as
#define ARG1_DECL AddressSpace *as
#include "exec/memory_ldst.inc.h"
#define SUFFIX
#define ARG1 as
#define ARG1_DECL AddressSpace *as
#include "exec/memory_ldst_phys.inc.h"
struct MemoryRegionCache {
void *ptr;
hwaddr xlat;
hwaddr len;
AddressSpace *as;
FlatView *fv;
MemoryRegionSection mrs;
bool is_write;
};
#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .as = NULL })
#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .mrs.mr = NULL })
/* address_space_ld*_cached: load from a cached #MemoryRegion
* address_space_st*_cached: store into a cached #MemoryRegion
*
* These functions perform a load or store of the byte, word,
* longword or quad to the specified address. The address is
* a physical address in the AddressSpace, but it must lie within
* a #MemoryRegion that was mapped with address_space_cache_init.
*
* The _le suffixed functions treat the data as little endian;
* _be indicates big endian; no suffix indicates "same endianness
* as guest CPU".
*
* The "guest CPU endianness" accessors are deprecated for use outside
* target-* code; devices should be CPU-agnostic and use either the LE
* or the BE accessors.
*
* @cache: previously initialized #MemoryRegionCache to be accessed
* @addr: address within the address space
* @val: data value, for stores
* @attrs: memory transaction attributes
* @result: location to write the success/failure of the transaction;
* if NULL, this information is discarded
*/
#define SUFFIX _cached_slow
#define ARG1 cache
#define ARG1_DECL MemoryRegionCache *cache
#include "exec/memory_ldst.inc.h"
/* Inline fast path for direct RAM access. */
static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len);
if (likely(cache->ptr)) {
return ldub_p(cache->ptr + addr);
} else {
return address_space_ldub_cached_slow(cache, addr, attrs, result);
}
}
static inline void address_space_stb_cached(MemoryRegionCache *cache,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len);
if (likely(cache->ptr)) {
stb_p(cache->ptr + addr, val);
} else {
address_space_stb_cached_slow(cache, addr, val, attrs, result);
}
}
#define ENDIANNESS _le
#include "exec/memory_ldst_cached.inc.h"
#define ENDIANNESS _be
#include "exec/memory_ldst_cached.inc.h"
#define SUFFIX _cached
#define ARG1 cache
#define ARG1_DECL MemoryRegionCache *cache
#include "exec/memory_ldst_phys.inc.h"
/* address_space_cache_init: prepare for repeated access to a physical
* memory region
@ -1772,72 +1806,6 @@ void address_space_cache_invalidate(MemoryRegionCache *cache,
*/
void address_space_cache_destroy(MemoryRegionCache *cache);
/* address_space_ld*_cached: load from a cached #MemoryRegion
* address_space_st*_cached: store into a cached #MemoryRegion
*
* These functions perform a load or store of the byte, word,
* longword or quad to the specified address. The address is
* a physical address in the AddressSpace, but it must lie within
* a #MemoryRegion that was mapped with address_space_cache_init.
*
* The _le suffixed functions treat the data as little endian;
* _be indicates big endian; no suffix indicates "same endianness
* as guest CPU".
*
* The "guest CPU endianness" accessors are deprecated for use outside
* target-* code; devices should be CPU-agnostic and use either the LE
* or the BE accessors.
*
* @cache: previously initialized #MemoryRegionCache to be accessed
* @addr: address within the address space
* @val: data value, for stores
* @attrs: memory transaction attributes
* @result: location to write the success/failure of the transaction;
* if NULL, this information is discarded
*/
uint32_t address_space_ldub_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_lduw_le_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_lduw_be_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl_le_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint32_t address_space_ldl_be_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq_le_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
uint64_t address_space_ldq_be_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stb_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stw_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stw_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stl_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq_le_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
void address_space_stq_be_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result);
uint32_t ldub_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint32_t lduw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint32_t lduw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint32_t ldl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint32_t ldl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint64_t ldq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
uint64_t ldq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
void stb_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
void stq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
void stq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
/* address_space_get_iotlb_entry: translate an address into an IOTLB
* entry. Should be called from an RCU critical section.
*/
@ -1925,6 +1893,13 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
MemoryRegion *mr);
void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
/* Internal functions, part of the implementation of address_space_read_cached
* and address_space_write_cached. */
void address_space_read_cached_slow(MemoryRegionCache *cache,
hwaddr addr, void *buf, int len);
void address_space_write_cached_slow(MemoryRegionCache *cache,
hwaddr addr, const void *buf, int len);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
if (is_write) {
@ -1993,7 +1968,11 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
void *buf, int len)
{
assert(addr < cache->len && len <= cache->len - addr);
address_space_read(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
if (likely(cache->ptr)) {
memcpy(buf, cache->ptr + addr, len);
} else {
address_space_read_cached_slow(cache, addr, buf, len);
}
}
/**
@ -2009,7 +1988,11 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
void *buf, int len)
{
assert(addr < cache->len && len <= cache->len - addr);
address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
if (likely(cache->ptr)) {
memcpy(cache->ptr + addr, buf, len);
} else {
address_space_write_cached_slow(cache, addr, buf, len);
}
}
#endif

View File

@ -0,0 +1,71 @@
/*
* Physical memory access templates
*
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2015 Linaro, Inc.
* Copyright (c) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef TARGET_ENDIANNESS
extern uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stw, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stl, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stq, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
#else
extern uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stb, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stw_le, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stl_le, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stq_le, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
extern void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
#endif
#undef ARG1_DECL
#undef ARG1
#undef SUFFIX
#undef TARGET_ENDIANNESS

View File

@ -0,0 +1,108 @@
/*
* Memory access templates for MemoryRegionCache
*
* Copyright (c) 2018 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#define ADDRESS_SPACE_LD_CACHED(size) \
glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached))
#define ADDRESS_SPACE_LD_CACHED_SLOW(size) \
glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached_slow))
#define LD_P(size) \
glue(glue(ld, size), glue(ENDIANNESS, _p))
static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 4 <= cache->len - addr);
if (likely(cache->ptr)) {
return LD_P(l)(cache->ptr + addr);
} else {
return ADDRESS_SPACE_LD_CACHED_SLOW(l)(cache, addr, attrs, result);
}
}
static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 8 <= cache->len - addr);
if (likely(cache->ptr)) {
return LD_P(q)(cache->ptr + addr);
} else {
return ADDRESS_SPACE_LD_CACHED_SLOW(q)(cache, addr, attrs, result);
}
}
static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 2 <= cache->len - addr);
if (likely(cache->ptr)) {
return LD_P(uw)(cache->ptr + addr);
} else {
return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result);
}
}
#undef ADDRESS_SPACE_LD_CACHED
#undef ADDRESS_SPACE_LD_CACHED_SLOW
#undef LD_P
#define ADDRESS_SPACE_ST_CACHED(size) \
glue(glue(address_space_st, size), glue(ENDIANNESS, _cached))
#define ADDRESS_SPACE_ST_CACHED_SLOW(size) \
glue(glue(address_space_st, size), glue(ENDIANNESS, _cached_slow))
#define ST_P(size) \
glue(glue(st, size), glue(ENDIANNESS, _p))
static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 4 <= cache->len - addr);
if (likely(cache->ptr)) {
ST_P(l)(cache->ptr + addr, val);
} else {
ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result);
}
}
static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 2 <= cache->len - addr);
if (likely(cache->ptr)) {
ST_P(w)(cache->ptr + addr, val);
} else {
ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result);
}
}
static inline void ADDRESS_SPACE_ST_CACHED(q)(MemoryRegionCache *cache,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 8 <= cache->len - addr);
if (likely(cache->ptr)) {
ST_P(q)(cache->ptr + addr, val);
} else {
ADDRESS_SPACE_ST_CACHED_SLOW(q)(cache, addr, val, attrs, result);
}
}
#undef ADDRESS_SPACE_ST_CACHED
#undef ADDRESS_SPACE_ST_CACHED_SLOW
#undef ST_P
#undef ENDIANNESS

View File

@ -0,0 +1,147 @@
/*
* Physical memory access templates
*
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2015 Linaro, Inc.
* Copyright (c) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef TARGET_ENDIANNESS
static inline uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
#else
static inline uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldub, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stb, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static inline void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
#endif
#undef ARG1_DECL
#undef ARG1
#undef SUFFIX
#undef TARGET_ENDIANNESS

View File

@ -137,7 +137,7 @@ char *qemu_find_file(int type, const char *name);
/* OS specific functions */
void os_setup_early_signal_handling(void);
char *os_find_datadir(void);
void os_parse_cmd_args(int index, const char *optarg);
int os_parse_cmd_args(int index, const char *optarg);
#include "qemu/module.h"

View File

@ -28,8 +28,7 @@
#include "qemu/queue.h"
const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
const char *get_opt_value(char *buf, int buf_size, const char *p);
const char *get_opt_value(const char *p, char **value);
void parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp);

View File

@ -1302,6 +1302,7 @@ Object *object_get_internal_root(void);
*
* Returns: The final component in the object's canonical path. The canonical
* path is the path within the composition tree starting from the root.
* %NULL if the object doesn't have a parent (and thus a canonical path).
*/
gchar *object_get_canonical_path_component(Object *obj);

View File

@ -52,7 +52,6 @@ struct HostMemoryBackend {
Object parent;
/* protected */
char *id;
uint64_t size;
bool merge, dump;
bool prealloc, force_prealloc, is_mapped, share;

View File

@ -298,7 +298,7 @@ static bool flatview_ref(FlatView *view)
return atomic_fetch_inc_nonzero(&view->ref) > 0;
}
static void flatview_unref(FlatView *view)
void flatview_unref(FlatView *view)
{
if (atomic_fetch_dec(&view->ref) == 1) {
trace_flatview_destroy_rcu(view, view->root);
@ -822,7 +822,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
}
}
static FlatView *address_space_get_flatview(AddressSpace *as)
FlatView *address_space_get_flatview(AddressSpace *as)
{
FlatView *view;

View File

@ -95,24 +95,6 @@ uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
DEVICE_BIG_ENDIAN);
}
uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
@ -189,24 +171,6 @@ uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
DEVICE_BIG_ENDIAN);
}
uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
@ -241,12 +205,6 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
return val;
}
uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldub, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
@ -323,24 +281,6 @@ uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
DEVICE_BIG_ENDIAN);
}
uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
@ -380,12 +320,6 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
RCU_READ_UNLOCK();
}
void glue(stl_phys_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl_notdirty, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs,
@ -460,24 +394,6 @@ void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
result, DEVICE_BIG_ENDIAN);
}
void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(address_space_stb, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
{
@ -509,12 +425,6 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
RCU_READ_UNLOCK();
}
void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stb, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
/* warning: addr must be aligned */
static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs,
@ -589,24 +499,6 @@ void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
DEVICE_BIG_ENDIAN);
}
void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
{
glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs,
MemTxResult *result, enum device_endian endian)
@ -680,24 +572,6 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
DEVICE_BIG_ENDIAN);
}
void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
{
glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
#undef ARG1_DECL
#undef ARG1
#undef SUFFIX

2
numa.c
View File

@ -580,7 +580,7 @@ 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->id = object_get_canonical_path_component(obj);
m->value->has_id = !!m->value->id;
m->value->size = object_property_get_uint(obj, "size",

View File

@ -165,7 +165,7 @@ static bool os_parse_runas_uid_gid(const char *optarg)
* Parse OS specific command line options.
* return 0 if option handled, -1 otherwise
*/
void os_parse_cmd_args(int index, const char *optarg)
int os_parse_cmd_args(int index, const char *optarg)
{
switch (index) {
#ifdef CONFIG_SLIRP
@ -199,7 +199,11 @@ void os_parse_cmd_args(int index, const char *optarg)
fips_set_state(true);
break;
#endif
default:
return -1;
}
return 0;
}
static void change_process_uid(void)

View File

@ -93,9 +93,9 @@ void os_set_line_buffering(void)
* Parse OS specific command line options.
* return 0 if option handled, -1 otherwise
*/
void os_parse_cmd_args(int index, const char *optarg)
int os_parse_cmd_args(int index, const char *optarg)
{
return;
return -1;
}
int qemu_create_pidfile(const char *filename)

View File

@ -39,6 +39,7 @@
* QEMU User space emulator::
* Implementation notes::
* Deprecated features::
* Supported build platforms::
* License::
* Index::
@end menu
@ -2786,16 +2787,6 @@ which is the default.
@section System emulator command line arguments
@subsection -no-kvm-pit-reinjection (since 1.3.0)
The ``-no-kvm-pit-reinjection'' argument is now a
synonym for setting ``-global kvm-pit.lost_tick_policy=discard''.
@subsection -no-kvm-irqchip (since 1.3.0)
The ``-no-kvm-irqchip'' argument is now a synonym for
setting ``-machine kernel_irqchip=off''.
@subsection -no-kvm (since 1.3.0)
The ``-no-kvm'' argument is now a synonym for setting
@ -2931,6 +2922,11 @@ The @code{-localtime} option has been replaced by @code{-rtc base=localtime}.
The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}.
@subsection -virtioconsole (since 2.13.0)
Option @option{-virtioconsole} has been replaced by
@option{-device virtconsole}.
@section qemu-img command line arguments
@subsection convert -s (since 2.0.0)
@ -2981,6 +2977,73 @@ The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
In order to prevent QEMU from automatically opening an image's backing
chain, use ``"backing": null'' instead.
@node Supported build platforms
@appendix Supported build platforms
QEMU aims to support building and executing on multiple host OS platforms.
This appendix outlines which platforms are the major build targets. These
platforms are used as the basis for deciding upon the minimum required
versions of 3rd party software QEMU depends on. The supported platforms
are the targets for automated testing performed by the project when patches
are submitted for review, and tested before and after merge.
If a platform is not listed here, it does not imply that QEMU won't work.
If an unlisted platform has comparable software versions to a listed platform,
there is every expectation that it will work. Bug reports are welcome for
problems encountered on unlisted platforms unless they are clearly older
vintage than what is described here.
Note that when considering software versions shipped in distros as support
targets, QEMU considers only the version number, and assumes the features in
that distro match the upstream release with the same version. In other words,
if a distro backports extra features to the software in their distro, QEMU
upstream code will not add explicit support for those backports, unless the
feature is auto-detectable in a manner that works for the upstream releases
too.
The Repology site @url{https://repology.org} is a useful resource to identify
currently shipped versions of software in various operating systems, though
it does not cover all distros listed below.
@section Linux OS
For distributions with frequent, short-lifetime releases, the project will
aim to support all versions that are not end of life by their respective
vendors. For the purposes of identifying supported software versions, the
project will look at Fedora, Ubuntu, and openSUSE distros. Other short-
lifetime distros will be assumed to ship similar software versions.
For distributions with long-lifetime releases, the project will aim to support
the most recent major version at all times. Support for the previous major
version will be dropped 2 years after the new major version is released. For
the purposes of identifying supported software versions, the project will look
at RHEL, Debian, Ubuntu LTS, and SLES distros. Other long-lifetime distros will
be assumed to ship similar software versions.
@section Windows
The project supports building with current versions of the MinGW toolchain,
hosted on Linux.
@section macOS
The project supports building with the two most recent versions of macOS, with
the current homebrew package set available.
@section FreeBSD
The project aims to support the all the versions which are not end of life.
@section NetBSD
The project aims to support the most recent major version at all times. Support
for the previous major version will be dropped 2 years after the new major
version is released.
@section OpenBSD
The project aims to support the all the versions which are not end of life.
@node License
@appendix License

View File

@ -3675,10 +3675,7 @@ STEXI
@item -virtioconsole @var{c}
@findex -virtioconsole
Set virtio console.
This option is maintained for backward compatibility.
Please use @code{-device virtconsole} for the new way of invocation.
This option is deprecated, please use @option{-device virtconsole} instead.
ETEXI
DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
@ -3917,16 +3914,6 @@ ETEXI
HXCOMM Deprecated by -machine accel=tcg property
DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
HXCOMM Deprecated by kvm-pit driver properties
DEF("no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection,
"", QEMU_ARCH_I386)
HXCOMM Deprecated by -machine kernel_irqchip=on|off property
DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386)
HXCOMM Deprecated (ignored)
DEF("tdf", 0, QEMU_OPTION_tdf,"", QEMU_ARCH_ALL)
DEF("msg", HAS_ARG, QEMU_OPTION_msg,
"-msg timestamp[=on|off]\n"
" change the format of messages\n"

View File

@ -1644,8 +1644,9 @@ gchar *object_get_canonical_path_component(Object *obj)
ObjectProperty *prop = NULL;
GHashTableIter iter;
g_assert(obj);
g_assert(obj->parent != NULL);
if (obj->parent == NULL) {
return NULL;
}
g_hash_table_iter_init(&iter, obj->parent->properties);
while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {

View File

@ -65,12 +65,6 @@ 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;

View File

@ -73,7 +73,7 @@ expand-objs = $(strip $(sort $(filter %.o,$1)) \
# must link with the C++ compiler, not the plain C compiler.
LINKPROG = $(or $(CXX),$(CC))
LINK = $(call quiet-command, $(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
LINK = $(call quiet-command, $(LINKPROG) $(QEMU_LDFLAGS) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
$(call process-archive-undefs, $1) \
$(version-obj-y) $(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@")

View File

@ -265,8 +265,36 @@ our @typeList = (
qr{${Ident}_handler_fn},
qr{target_(?:u)?long},
qr{hwaddr},
# external libraries
qr{xml${Ident}},
qr{xendevicemodel_handle},
# Glib definitions
qr{gchar},
qr{gshort},
qr{glong},
qr{gint},
qr{gboolean},
qr{guchar},
qr{gushort},
qr{gulong},
qr{guint},
qr{gfloat},
qr{gdouble},
qr{gpointer},
qr{gconstpointer},
qr{gint8},
qr{guint8},
qr{gint16},
qr{guint16},
qr{gint32},
qr{guint32},
qr{gint64},
qr{guint64},
qr{gsize},
qr{gssize},
qr{goffset},
qr{gintptr},
qr{guintptr},
);
# This can be modified by sub possible. Since it can be empty, be careful

View File

@ -118,9 +118,6 @@ for arch in $ARCHLIST; do
cp "$tmpdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/"
fi
if [ $arch = x86 ]; then
cat <<-EOF >"$output/include/standard-headers/asm-x86/hyperv.h"
/* this is a temporary placeholder until kvm_para.h stops including it */
EOF
cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/"
cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
@ -144,9 +141,6 @@ else
cp "$linux/COPYING" "$output/linux-headers"
fi
cat <<EOF >$output/linux-headers/asm-x86/hyperv.h
#include "standard-headers/asm-x86/hyperv.h"
EOF
cat <<EOF >$output/linux-headers/linux/virtio_config.h
#include "standard-headers/linux/virtio_config.h"
EOF

View File

@ -3047,7 +3047,7 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
return insn_len;
}
#include "translate_v10.c"
#include "translate_v10.inc.c"
/*
* Delay slots on QEMU/CRIS.

View File

@ -416,7 +416,8 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
NULL, NULL, NULL, NULL,
NULL /* hv_msr_debug_access */, NULL /* hv_msr_reenlightenment_access */,
NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
@ -4770,6 +4771,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),

View File

@ -1174,6 +1174,9 @@ typedef struct CPUX86State {
uint64_t msr_hv_synic_sint[HV_SINT_COUNT];
uint64_t msr_hv_stimer_config[HV_STIMER_COUNT];
uint64_t msr_hv_stimer_count[HV_STIMER_COUNT];
uint64_t msr_hv_reenlightenment_control;
uint64_t msr_hv_tsc_emulation_control;
uint64_t msr_hv_tsc_emulation_status;
uint64_t msr_rtit_ctrl;
uint64_t msr_rtit_status;
@ -1297,6 +1300,7 @@ struct X86CPU {
bool hyperv_synic;
bool hyperv_stimer;
bool hyperv_frequencies;
bool hyperv_reenlightenment;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;

View File

@ -35,7 +35,7 @@
#define HV_RESET_AVAILABLE (1u << 7)
#define HV_REFERENCE_TSC_AVAILABLE (1u << 9)
#define HV_ACCESS_FREQUENCY_MSRS (1u << 11)
#define HV_ACCESS_REENLIGHTENMENTS_CONTROL (1u << 13)
/*
* HV_CPUID_FEATURES.EDX bits
@ -129,6 +129,13 @@
#define HV_X64_MSR_CRASH_CTL 0x40000105
#define HV_CRASH_CTL_NOTIFY (1ull << 63)
/*
* Reenlightenment notification MSRs
*/
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107
#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108
/*
* Hypercall status code
*/

View File

@ -90,6 +90,7 @@ static bool has_msr_hv_runtime;
static bool has_msr_hv_synic;
static bool has_msr_hv_stimer;
static bool has_msr_hv_frequencies;
static bool has_msr_hv_reenlightenment;
static bool has_msr_xss;
static bool has_msr_spec_ctrl;
static bool has_msr_smi_count;
@ -583,7 +584,8 @@ static bool hyperv_enabled(X86CPU *cpu)
cpu->hyperv_vpindex ||
cpu->hyperv_runtime ||
cpu->hyperv_synic ||
cpu->hyperv_stimer);
cpu->hyperv_stimer ||
cpu->hyperv_reenlightenment);
}
static int kvm_arch_set_tsc_khz(CPUState *cs)
@ -669,6 +671,16 @@ static int hyperv_handle_properties(CPUState *cs)
}
env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
}
if (cpu->hyperv_reenlightenment) {
if (!has_msr_hv_reenlightenment) {
fprintf(stderr,
"Hyper-V Reenlightenment MSRs "
"(requested by 'hv-reenlightenment' cpu flag) "
"are not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_REENLIGHTENMENTS_CONTROL;
}
env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
if (cpu->hyperv_reset) {
if (!has_msr_hv_reset) {
@ -1215,6 +1227,9 @@ static int kvm_get_supported_msrs(KVMState *s)
case HV_X64_MSR_TSC_FREQUENCY:
has_msr_hv_frequencies = true;
break;
case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
has_msr_hv_reenlightenment = true;
break;
case MSR_IA32_SPEC_CTRL:
has_msr_spec_ctrl = true;
break;
@ -1778,6 +1793,14 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC,
env->msr_hv_tsc);
}
if (cpu->hyperv_reenlightenment) {
kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL,
env->msr_hv_reenlightenment_control);
kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL,
env->msr_hv_tsc_emulation_control);
kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS,
env->msr_hv_tsc_emulation_status);
}
}
if (cpu->hyperv_vapic) {
kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE,
@ -2140,6 +2163,11 @@ static int kvm_get_msrs(X86CPU *cpu)
if (cpu->hyperv_time) {
kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0);
}
if (cpu->hyperv_reenlightenment) {
kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL, 0);
kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL, 0);
kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS, 0);
}
if (has_msr_hv_crash) {
int j;
@ -2397,6 +2425,15 @@ static int kvm_get_msrs(X86CPU *cpu)
env->msr_hv_stimer_count[(index - HV_X64_MSR_STIMER0_COUNT)/2] =
msrs[i].data;
break;
case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
env->msr_hv_reenlightenment_control = msrs[i].data;
break;
case HV_X64_MSR_TSC_EMULATION_CONTROL:
env->msr_hv_tsc_emulation_control = msrs[i].data;
break;
case HV_X64_MSR_TSC_EMULATION_STATUS:
env->msr_hv_tsc_emulation_status = msrs[i].data;
break;
case MSR_MTRRdefType:
env->mtrr_deftype = msrs[i].data;
break;

View File

@ -713,6 +713,29 @@ static const VMStateDescription vmstate_msr_hyperv_stimer = {
}
};
static bool hyperv_reenlightenment_enable_needed(void *opaque)
{
X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env;
return env->msr_hv_reenlightenment_control != 0 ||
env->msr_hv_tsc_emulation_control != 0 ||
env->msr_hv_tsc_emulation_status != 0;
}
static const VMStateDescription vmstate_msr_hyperv_reenlightenment = {
.name = "cpu/msr_hyperv_reenlightenment",
.version_id = 1,
.minimum_version_id = 1,
.needed = hyperv_reenlightenment_enable_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT64(env.msr_hv_reenlightenment_control, X86CPU),
VMSTATE_UINT64(env.msr_hv_tsc_emulation_control, X86CPU),
VMSTATE_UINT64(env.msr_hv_tsc_emulation_status, X86CPU),
VMSTATE_END_OF_LIST()
}
};
static bool avx512_needed(void *opaque)
{
X86CPU *cpu = opaque;
@ -1005,6 +1028,7 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_hyperv_runtime,
&vmstate_msr_hyperv_synic,
&vmstate_msr_hyperv_stimer,
&vmstate_msr_hyperv_reenlightenment,
&vmstate_avx512,
&vmstate_xss,
&vmstate_tsc_khz,

View File

@ -430,7 +430,8 @@ static int
sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
size_t *cert_chain_len)
{
guchar *pdh_data, *cert_chain_data;
guchar *pdh_data = NULL;
guchar *cert_chain_data = NULL;
struct sev_user_data_pdh_cert_export export = {};
int err, r;
@ -471,8 +472,9 @@ e_free:
SevCapability *
sev_get_capabilities(void)
{
SevCapability *cap;
guchar *pdh_data, *cert_chain_data;
SevCapability *cap = NULL;
guchar *pdh_data = NULL;
guchar *cert_chain_data = NULL;
size_t pdh_len = 0, cert_chain_len = 0;
uint32_t ebx;
int fd;
@ -486,7 +488,7 @@ sev_get_capabilities(void)
if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
&cert_chain_data, &cert_chain_len)) {
return NULL;
goto out;
}
cap = g_new0(SevCapability, 1);
@ -502,9 +504,9 @@ sev_get_capabilities(void)
*/
cap->reduced_phys_bits = 1;
out:
g_free(pdh_data);
g_free(cert_chain_data);
close(fd);
return cap;
}
@ -530,7 +532,7 @@ sev_launch_start(SEVState *s)
{
gsize sz;
int ret = 1;
int fw_error;
int fw_error, rc;
QSevGuestInfo *sev = s->sev_info;
struct kvm_sev_launch_start *start;
guchar *session = NULL, *dh_cert = NULL;
@ -543,7 +545,7 @@ sev_launch_start(SEVState *s)
&error_abort);
if (sev->session_file) {
if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
return 1;
goto out;
}
start->session_uaddr = (unsigned long)session;
start->session_len = sz;
@ -551,18 +553,18 @@ sev_launch_start(SEVState *s)
if (sev->dh_cert_file) {
if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
return 1;
goto out;
}
start->dh_uaddr = (unsigned long)dh_cert;
start->dh_len = sz;
}
trace_kvm_sev_launch_start(start->policy, session, dh_cert);
ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
if (ret < 0) {
rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
if (rc < 0) {
error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
__func__, ret, fw_error, fw_error_to_str(fw_error));
return 1;
goto out;
}
object_property_set_int(OBJECT(sev), start->handle, "handle",
@ -570,12 +572,13 @@ sev_launch_start(SEVState *s)
sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE);
s->handle = start->handle;
s->policy = start->policy;
ret = 0;
out:
g_free(start);
g_free(session);
g_free(dh_cert);
return 0;
return ret;
}
static int
@ -712,7 +715,7 @@ sev_guest_init(const char *id)
uint32_t host_cbitpos;
struct sev_user_data_status status = {};
s = g_new0(SEVState, 1);
sev_state = s = g_new0(SEVState, 1);
s->sev_info = lookup_sev_guest_info(id);
if (!s->sev_info) {
error_report("%s: '%s' is not a valid '%s' object",
@ -720,7 +723,6 @@ sev_guest_init(const char *id)
goto err;
}
sev_state = s;
s->state = SEV_STATE_UNINIT;
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);

View File

@ -20500,7 +20500,7 @@ void mips_tcg_init(void)
"fcr31");
}
#include "translate_init.c"
#include "translate_init.inc.c"
void cpu_mips_realize_env(CPUMIPSState *env)
{

View File

@ -379,7 +379,7 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
target_ulong helper_602_mfrom(target_ulong arg)
{
if (likely(arg < 602)) {
#include "mfrom_table.c"
#include "mfrom_table.inc.c"
return mfrom_ROM_table[arg];
} else {
return 0;

View File

@ -6991,7 +6991,7 @@ GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
};
#include "helper_regs.h"
#include "translate_init.c"
#include "translate_init.inc.c"
/*****************************************************************************/
/* Misc PowerPC helpers */

View File

@ -18,7 +18,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "disas/bfd.h"
#include "exec/gdbstub.h"
#include "kvm_ppc.h"

View File

@ -459,8 +459,6 @@ static void test_opts_parse(void)
{
Error *err = NULL;
QemuOpts *opts;
char long_key[129];
char *params;
/* Nothing */
opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
@ -471,22 +469,6 @@ static void test_opts_parse(void)
g_assert_cmpuint(opts_count(opts), ==, 1);
g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
/* Long key */
memset(long_key, 'a', 127);
long_key[127] = 'z';
long_key[128] = 0;
params = g_strdup_printf("%s=v", long_key);
opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort);
g_assert_cmpuint(opts_count(opts), ==, 1);
g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v");
/* Overlong key gets truncated */
opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
g_assert(opts_count(opts) == 1);
long_key[127] = 0;
g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
g_free(params);
/* Multiple keys, last one wins */
opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
false, &error_abort);

View File

@ -199,56 +199,56 @@ static void zrle_write_u8(VncState *vs, uint8_t value)
#define ZRLE_BPP 8
#define ZYWRLE_ENDIAN ENDIAN_NO
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZRLE_BPP
#define ZRLE_BPP 15
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_BIG
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZRLE_BPP
#define ZRLE_BPP 16
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_BIG
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZRLE_BPP
#define ZRLE_BPP 32
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_BIG
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#define ZRLE_COMPACT_PIXEL 24a
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_BIG
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZRLE_COMPACT_PIXEL
#define ZRLE_COMPACT_PIXEL 24b
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZYWRLE_ENDIAN
#define ZYWRLE_ENDIAN ENDIAN_BIG
#include "vnc-enc-zrle-template.c"
#include "vnc-enc-zrle.inc.c"
#undef ZRLE_COMPACT_PIXEL
#undef ZRLE_BPP

View File

@ -43,26 +43,23 @@
* first byte of the option name)
*
* The option name is delimited by delim (usually , or =) or the string end
* and is copied into buf. If the option name is longer than buf_size, it is
* truncated. buf is always zero terminated.
* and is copied into option. The caller is responsible for free'ing option
* when no longer required.
*
* The return value is the position of the delimiter/zero byte after the option
* name in p.
*/
const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
static const char *get_opt_name(const char *p, char **option, char delim)
{
char *q;
char *offset = strchr(p, delim);
q = buf;
while (*p != '\0' && *p != delim) {
if (q && (q - buf) < buf_size - 1)
*q++ = *p;
p++;
if (offset) {
*option = g_strndup(p, offset - p);
return offset;
} else {
*option = g_strdup(p);
return p + strlen(p);
}
if (q)
*q = '\0';
return p;
}
/*
@ -73,25 +70,37 @@ const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
* delimiter is fixed to be comma which starts a new option. To specify an
* option value that contains commas, double each comma.
*/
const char *get_opt_value(char *buf, int buf_size, const char *p)
const char *get_opt_value(const char *p, char **value)
{
char *q;
size_t capacity = 0, length;
const char *offset;
q = buf;
while (*p != '\0') {
if (*p == ',') {
if (*(p + 1) != ',')
break;
p++;
*value = NULL;
while (1) {
offset = strchr(p, ',');
if (!offset) {
offset = p + strlen(p);
}
if (q && (q - buf) < buf_size - 1)
*q++ = *p;
p++;
}
if (q)
*q = '\0';
return p;
length = offset - p;
if (*offset != '\0' && *(offset + 1) == ',') {
length++;
}
if (value) {
*value = g_renew(char, *value, capacity + length + 1);
strncpy(*value + capacity, p, length);
(*value)[capacity + length] = '\0';
}
capacity += length;
if (*offset == '\0' ||
*(offset + 1) != ',') {
break;
}
p += (offset - p) + 2;
}
return offset;
}
static void parse_option_bool(const char *name, const char *value, bool *ret,
@ -165,50 +174,43 @@ void parse_option_size(const char *name, const char *value,
bool has_help_option(const char *param)
{
size_t buflen = strlen(param) + 1;
char *buf = g_malloc(buflen);
const char *p = param;
bool result = false;
while (*p) {
p = get_opt_value(buf, buflen, p);
while (*p && !result) {
char *value;
p = get_opt_value(p, &value);
if (*p) {
p++;
}
if (is_help_option(buf)) {
result = true;
goto out;
}
result = is_help_option(value);
g_free(value);
}
out:
g_free(buf);
return result;
}
bool is_valid_option_list(const char *param)
bool is_valid_option_list(const char *p)
{
size_t buflen = strlen(param) + 1;
char *buf = g_malloc(buflen);
const char *p = param;
bool result = true;
char *value = NULL;
bool result = false;
while (*p) {
p = get_opt_value(buf, buflen, p);
if (*p && !*++p) {
result = false;
p = get_opt_value(p, &value);
if ((*p && !*++p) ||
(!*value || *value == ',')) {
goto out;
}
if (!*buf || *buf == ',') {
result = false;
goto out;
}
g_free(value);
value = NULL;
}
result = true;
out:
g_free(buf);
g_free(value);
return result;
}
@ -490,7 +492,7 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
}
}
static void opt_set(QemuOpts *opts, const char *name, const char *value,
static void opt_set(QemuOpts *opts, const char *name, char *value,
bool prepend, Error **errp)
{
QemuOpt *opt;
@ -499,6 +501,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
desc = find_desc_by_name(opts->list->desc, name);
if (!desc && !opts_accepts_any(opts)) {
g_free(value);
error_setg(errp, QERR_INVALID_PARAMETER, name);
return;
}
@ -512,8 +515,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
QTAILQ_INSERT_TAIL(&opts->head, opt, next);
}
opt->desc = desc;
opt->str = g_strdup(value);
assert(opt->str);
opt->str = value;
qemu_opt_parse(opt, &local_err);
if (local_err) {
error_propagate(errp, local_err);
@ -524,7 +526,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
Error **errp)
{
opt_set(opts, name, value, false, errp);
opt_set(opts, name, g_strdup(value), false, errp);
}
void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
@ -757,7 +759,8 @@ void qemu_opts_print(QemuOpts *opts, const char *separator)
static void opts_do_parse(QemuOpts *opts, const char *params,
const char *firstname, bool prepend, Error **errp)
{
char option[128], value[1024];
char *option = NULL;
char *value = NULL;
const char *p,*pe,*pc;
Error *local_err = NULL;
@ -768,39 +771,45 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
/* found "foo,more" */
if (p == params && firstname) {
/* implicitly named first option */
pstrcpy(option, sizeof(option), firstname);
p = get_opt_value(value, sizeof(value), p);
option = g_strdup(firstname);
p = get_opt_value(p, &value);
} else {
/* option without value, probably a flag */
p = get_opt_name(option, sizeof(option), p, ',');
p = get_opt_name(p, &option, ',');
if (strncmp(option, "no", 2) == 0) {
memmove(option, option+2, strlen(option+2)+1);
pstrcpy(value, sizeof(value), "off");
value = g_strdup("off");
} else {
pstrcpy(value, sizeof(value), "on");
value = g_strdup("on");
}
}
} else {
/* found "foo=bar,more" */
p = get_opt_name(option, sizeof(option), p, '=');
if (*p != '=') {
break;
}
p = get_opt_name(p, &option, '=');
assert(*p == '=');
p++;
p = get_opt_value(value, sizeof(value), p);
p = get_opt_value(p, &value);
}
if (strcmp(option, "id") != 0) {
/* store and parse */
opt_set(opts, option, value, prepend, &local_err);
value = NULL;
if (local_err) {
error_propagate(errp, local_err);
return;
goto cleanup;
}
}
if (*p != ',') {
break;
}
g_free(option);
g_free(value);
option = value = NULL;
}
cleanup:
g_free(option);
g_free(value);
}
/**
@ -819,7 +828,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
bool permit_abbrev, bool defaults, Error **errp)
{
const char *firstname;
char value[1024], *id = NULL;
char *id = NULL;
const char *p;
QemuOpts *opts;
Error *local_err = NULL;
@ -828,11 +837,9 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
firstname = permit_abbrev ? list->implied_opt_name : NULL;
if (strncmp(params, "id=", 3) == 0) {
get_opt_value(value, sizeof(value), params+3);
id = value;
get_opt_value(params + 3, &id);
} else if ((p = strstr(params, ",id=")) != NULL) {
get_opt_value(value, sizeof(value), p+4);
id = value;
get_opt_value(p + 4, &id);
}
/*
@ -844,6 +851,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
*/
assert(!defaults || list->merge_lists);
opts = qemu_opts_create(list, id, !defaults, &local_err);
g_free(id);
if (opts == NULL) {
error_propagate(errp, local_err);
return NULL;

View File

@ -482,7 +482,6 @@ static void __attribute__((constructor)) qemu_thread_atexit_init(void)
}
#ifdef CONFIG_PTHREAD_SETNAME_NP
typedef struct {
void *(*start_routine)(void *);
void *arg;
@ -495,16 +494,18 @@ static void *qemu_thread_start(void *args)
void *(*start_routine)(void *) = qemu_thread_args->start_routine;
void *arg = qemu_thread_args->arg;
#ifdef CONFIG_PTHREAD_SETNAME_NP
/* Attempt to set the threads name; note that this is for debug, so
* we're not going to fail if we can't set it.
*/
pthread_setname_np(pthread_self(), qemu_thread_args->name);
if (name_threads && qemu_thread_args->name) {
pthread_setname_np(pthread_self(), qemu_thread_args->name);
}
#endif
g_free(qemu_thread_args->name);
g_free(qemu_thread_args);
return start_routine(arg);
}
#endif
void qemu_thread_create(QemuThread *thread, const char *name,
void *(*start_routine)(void*),
@ -513,6 +514,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
sigset_t set, oldset;
int err;
pthread_attr_t attr;
QemuThreadArgs *qemu_thread_args;
err = pthread_attr_init(&attr);
if (err) {
@ -527,22 +529,13 @@ void qemu_thread_create(QemuThread *thread, const char *name,
sigfillset(&set);
pthread_sigmask(SIG_SETMASK, &set, &oldset);
#ifdef CONFIG_PTHREAD_SETNAME_NP
if (name_threads) {
QemuThreadArgs *qemu_thread_args;
qemu_thread_args = g_new0(QemuThreadArgs, 1);
qemu_thread_args->name = g_strdup(name);
qemu_thread_args->start_routine = start_routine;
qemu_thread_args->arg = arg;
qemu_thread_args = g_new0(QemuThreadArgs, 1);
qemu_thread_args->name = g_strdup(name);
qemu_thread_args->start_routine = start_routine;
qemu_thread_args->arg = arg;
err = pthread_create(&thread->thread, &attr,
qemu_thread_start, qemu_thread_args);
} else
#endif
{
err = pthread_create(&thread->thread, &attr,
start_routine, arg);
}
err = pthread_create(&thread->thread, &attr,
qemu_thread_start, qemu_thread_args);
if (err)
error_exit(err, __func__);

24
vl.c
View File

@ -3138,11 +3138,6 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
switch(popt->index) {
case QEMU_OPTION_no_kvm_irqchip: {
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "kernel_irqchip=off", false);
break;
}
case QEMU_OPTION_cpu:
/* hw initialization will check this */
cpu_model = optarg;
@ -3587,6 +3582,8 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_virtiocon:
warn_report("This option is deprecated, "
"use '-device virtconsole' instead");
add_device_config(DEV_VIRTCON, optarg);
default_virtcon = 0;
if (strncmp(optarg, "mon:", 4) == 0) {
@ -3694,18 +3691,6 @@ int main(int argc, char **argv, char **envp)
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=tcg", false);
break;
case QEMU_OPTION_no_kvm_pit_reinjection: {
static GlobalProperty kvm_pit_lost_tick_policy = {
.driver = "kvm-pit",
.property = "lost_tick_policy",
.value = "discard",
};
warn_report("deprecated, replaced by "
"-global kvm-pit.lost_tick_policy=discard");
qdev_prop_register_global(&kvm_pit_lost_tick_policy);
break;
}
case QEMU_OPTION_accel:
accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
optarg, true);
@ -4031,7 +4016,10 @@ int main(int argc, char **argv, char **envp)
}
break;
default:
os_parse_cmd_args(popt->index, optarg);
if (os_parse_cmd_args(popt->index, optarg)) {
error_report("Option not supported in this build");
exit(1);
}
}
}
}