mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
|
||||
+7
-9
@@ -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) {
|
||||
|
||||
@@ -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 },
|
||||
{ }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) */
|
||||
|
||||
+21
-12
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -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 */
|
||||
|
||||
+31
-42
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
+95
-112
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ struct HostMemoryBackend {
|
||||
Object parent;
|
||||
|
||||
/* protected */
|
||||
char *id;
|
||||
uint64_t size;
|
||||
bool merge, dump;
|
||||
bool prealloc, force_prealloc, is_mapped, share;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user