]> git.proxmox.com Git - mirror_qemu.git/commitdiff
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220307' into...
authorPeter Maydell <peter.maydell@linaro.org>
Tue, 8 Mar 2022 15:26:10 +0000 (15:26 +0000)
committerPeter Maydell <peter.maydell@linaro.org>
Tue, 8 Mar 2022 15:26:10 +0000 (15:26 +0000)
target-arm queue:
 * cleanups of qemu_oom_check() and qemu_memalign()
 * target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
 * target/arm/translate-neon: Simplify align field check for VLD3
 * GICv3 ITS: add more trace events
 * GICv3 ITS: implement 8-byte accesses properly
 * GICv3: fix minor issues with some trace/log messages
 * ui/cocoa: Use the standard about panel
 * target/arm: Provide cpu property for controling FEAT_LPA2
 * hw/arm/virt: Disable LPA2 for -machine virt-6.2

# gpg: Signature made Mon 07 Mar 2022 16:46:06 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20220307:
  hw/arm/virt: Disable LPA2 for -machine virt-6.2
  target/arm: Provide cpu property for controling FEAT_LPA2
  ui/cocoa: Use the standard about panel
  hw/intc/arm_gicv3_cpuif: Fix register names in ICV_HPPIR read trace event
  hw/intc/arm_gicv3: Fix missing spaces in error log messages
  hw/intc/arm_gicv3: Specify valid and impl in MemoryRegionOps
  hw/intc/arm_gicv3_its: Add trace events for table reads and writes
  hw/intc/arm_gicv3_its: Add trace events for commands
  target/arm/translate-neon: Simplify align field check for VLD3
  target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
  osdep: Move memalign-related functions to their own header
  util: Put qemu_vfree() in memalign.c
  util: Use meson checks for valloc() and memalign() presence
  util: Share qemu_try_memalign() implementation between POSIX and Windows
  meson.build: Don't misdetect posix_memalign() on Windows
  util: Return valid allocation for qemu_try_memalign() with zero size
  util: Unify implementations of qemu_memalign()
  util: Make qemu_oom_check() a static function

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
1  2 
block/block-copy.c
block/io.c
hw/ide/core.c
include/qemu/osdep.h
meson.build
softmmu/physmem.c
target/arm/cpu.h

diff --combined block/block-copy.c
index ef948dccecd25db4a2fcd8904777ca8deaf586b6,619e5580fafb939e5f3c309327ef214bd20e07f5..ec46775ea5c06e7996c775e395840dbc5f655167
  #include "trace.h"
  #include "qapi/error.h"
  #include "block/block-copy.h"
 +#include "block/reqlist.h"
  #include "sysemu/block-backend.h"
  #include "qemu/units.h"
  #include "qemu/coroutine.h"
  #include "block/aio_task.h"
  #include "qemu/error-report.h"
+ #include "qemu/memalign.h"
  
  #define BLOCK_COPY_MAX_COPY_RANGE (16 * MiB)
  #define BLOCK_COPY_MAX_BUFFER (1 * MiB)
@@@ -84,6 -84,7 +85,6 @@@ typedef struct BlockCopyTask 
       */
      BlockCopyState *s;
      BlockCopyCallState *call_state;
 -    int64_t offset;
      /*
       * @method can also be set again in the while loop of
       * block_copy_dirty_clusters(), but it is never accessed concurrently
      BlockCopyMethod method;
  
      /*
 -     * Fields whose state changes throughout the execution
 -     * Protected by lock in BlockCopyState.
 -     */
 -    CoQueue wait_queue; /* coroutines blocked on this task */
 -    /*
 -     * Only protect the case of parallel read while updating @bytes
 -     * value in block_copy_task_shrink().
 +     * Generally, req is protected by lock in BlockCopyState, Still req.offset
 +     * is only set on task creation, so may be read concurrently after creation.
 +     * req.bytes is changed at most once, and need only protecting the case of
 +     * parallel read while updating @bytes value in block_copy_task_shrink().
       */
 -    int64_t bytes;
 -    QLIST_ENTRY(BlockCopyTask) list;
 +    BlockReq req;
  } BlockCopyTask;
  
  static int64_t task_end(BlockCopyTask *task)
  {
 -    return task->offset + task->bytes;
 +    return task->req.offset + task->req.bytes;
  }
  
  typedef struct BlockCopyState {
      CoMutex lock;
      int64_t in_flight_bytes;
      BlockCopyMethod method;
 -    QLIST_HEAD(, BlockCopyTask) tasks; /* All tasks from all block-copy calls */
 +    BlockReqList reqs;
      QLIST_HEAD(, BlockCopyCallState) calls;
      /*
       * skip_unallocated:
      RateLimit rate_limit;
  } BlockCopyState;
  
 -/* Called with lock held */
 -static BlockCopyTask *find_conflicting_task(BlockCopyState *s,
 -                                            int64_t offset, int64_t bytes)
 -{
 -    BlockCopyTask *t;
 -
 -    QLIST_FOREACH(t, &s->tasks, list) {
 -        if (offset + bytes > t->offset && offset < t->offset + t->bytes) {
 -            return t;
 -        }
 -    }
 -
 -    return NULL;
 -}
 -
 -/*
 - * If there are no intersecting tasks return false. Otherwise, wait for the
 - * first found intersecting tasks to finish and return true.
 - *
 - * Called with lock held. May temporary release the lock.
 - * Return value of 0 proves that lock was NOT released.
 - */
 -static bool coroutine_fn block_copy_wait_one(BlockCopyState *s, int64_t offset,
 -                                             int64_t bytes)
 -{
 -    BlockCopyTask *task = find_conflicting_task(s, offset, bytes);
 -
 -    if (!task) {
 -        return false;
 -    }
 -
 -    qemu_co_queue_wait(&task->wait_queue, &s->lock);
 -
 -    return true;
 -}
 -
  /* Called with lock held */
  static int64_t block_copy_chunk_size(BlockCopyState *s)
  {
@@@ -199,7 -240,7 +200,7 @@@ block_copy_task_create(BlockCopyState *
      bytes = QEMU_ALIGN_UP(bytes, s->cluster_size);
  
      /* region is dirty, so no existent tasks possible in it */
 -    assert(!find_conflicting_task(s, offset, bytes));
 +    assert(!reqlist_find_conflict(&s->reqs, offset, bytes));
  
      bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
      s->in_flight_bytes += bytes;
          .task.func = block_copy_task_entry,
          .s = s,
          .call_state = call_state,
 -        .offset = offset,
 -        .bytes = bytes,
          .method = s->method,
      };
 -    qemu_co_queue_init(&task->wait_queue);
 -    QLIST_INSERT_HEAD(&s->tasks, task, list);
 +    reqlist_init_req(&s->reqs, &task->req, offset, bytes);
  
      return task;
  }
@@@ -227,34 -271,34 +228,34 @@@ static void coroutine_fn block_copy_tas
                                                  int64_t new_bytes)
  {
      QEMU_LOCK_GUARD(&task->s->lock);
 -    if (new_bytes == task->bytes) {
 +    if (new_bytes == task->req.bytes) {
          return;
      }
  
 -    assert(new_bytes > 0 && new_bytes < task->bytes);
 +    assert(new_bytes > 0 && new_bytes < task->req.bytes);
  
 -    task->s->in_flight_bytes -= task->bytes - new_bytes;
 +    task->s->in_flight_bytes -= task->req.bytes - new_bytes;
      bdrv_set_dirty_bitmap(task->s->copy_bitmap,
 -                          task->offset + new_bytes, task->bytes - new_bytes);
 +                          task->req.offset + new_bytes,
 +                          task->req.bytes - new_bytes);
  
 -    task->bytes = new_bytes;
 -    qemu_co_queue_restart_all(&task->wait_queue);
 +    reqlist_shrink_req(&task->req, new_bytes);
  }
  
  static void coroutine_fn block_copy_task_end(BlockCopyTask *task, int ret)
  {
      QEMU_LOCK_GUARD(&task->s->lock);
 -    task->s->in_flight_bytes -= task->bytes;
 +    task->s->in_flight_bytes -= task->req.bytes;
      if (ret < 0) {
 -        bdrv_set_dirty_bitmap(task->s->copy_bitmap, task->offset, task->bytes);
 +        bdrv_set_dirty_bitmap(task->s->copy_bitmap, task->req.offset,
 +                              task->req.bytes);
      }
 -    QLIST_REMOVE(task, list);
      if (task->s->progress) {
          progress_set_remaining(task->s->progress,
                                 bdrv_get_dirty_count(task->s->copy_bitmap) +
                                 task->s->in_flight_bytes);
      }
 -    qemu_co_queue_restart_all(&task->wait_queue);
 +    reqlist_remove_req(&task->req);
  }
  
  void block_copy_state_free(BlockCopyState *s)
@@@ -341,10 -385,8 +342,10 @@@ static int64_t block_copy_calculate_clu
  }
  
  BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
 +                                     const BdrvDirtyBitmap *bitmap,
                                       Error **errp)
  {
 +    ERRP_GUARD();
      BlockCopyState *s;
      int64_t cluster_size;
      BdrvDirtyBitmap *copy_bitmap;
          return NULL;
      }
      bdrv_disable_dirty_bitmap(copy_bitmap);
 +    if (bitmap) {
 +        if (!bdrv_merge_dirty_bitmap(copy_bitmap, bitmap, NULL, errp)) {
 +            error_prepend(errp, "Failed to merge bitmap '%s' to internal "
 +                          "copy-bitmap: ", bdrv_dirty_bitmap_name(bitmap));
 +            bdrv_release_dirty_bitmap(copy_bitmap);
 +            return NULL;
 +        }
 +    } else {
 +        bdrv_set_dirty_bitmap(copy_bitmap, 0,
 +                              bdrv_dirty_bitmap_size(copy_bitmap));
 +    }
  
      /*
       * If source is in backing chain of target assume that target is going to be
  
      ratelimit_init(&s->rate_limit);
      qemu_co_mutex_init(&s->lock);
 -    QLIST_INIT(&s->tasks);
 +    QLIST_INIT(&s->reqs);
      QLIST_INIT(&s->calls);
  
      return s;
@@@ -440,7 -471,7 +441,7 @@@ static coroutine_fn int block_copy_task
  
      aio_task_pool_wait_slot(pool);
      if (aio_task_pool_status(pool) < 0) {
 -        co_put_to_shres(task->s->mem, task->bytes);
 +        co_put_to_shres(task->s->mem, task->req.bytes);
          block_copy_task_end(task, -ECANCELED);
          g_free(task);
          return -ECANCELED;
@@@ -553,8 -584,7 +554,8 @@@ static coroutine_fn int block_copy_task
      BlockCopyMethod method = t->method;
      int ret;
  
 -    ret = block_copy_do_copy(s, t->offset, t->bytes, &method, &error_is_read);
 +    ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
 +                             &error_is_read);
  
      WITH_QEMU_LOCK_GUARD(&s->lock) {
          if (s->method == t->method) {
                  t->call_state->error_is_read = error_is_read;
              }
          } else if (s->progress) {
 -            progress_work_done(s->progress, t->bytes);
 +            progress_work_done(s->progress, t->req.bytes);
          }
      }
 -    co_put_to_shres(s->mem, t->bytes);
 +    co_put_to_shres(s->mem, t->req.bytes);
      block_copy_task_end(t, ret);
  
      return ret;
@@@ -650,18 -680,6 +651,18 @@@ static int block_copy_is_cluster_alloca
      }
  }
  
 +void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes)
 +{
 +    QEMU_LOCK_GUARD(&s->lock);
 +
 +    bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
 +    if (s->progress) {
 +        progress_set_remaining(s->progress,
 +                               bdrv_get_dirty_count(s->copy_bitmap) +
 +                               s->in_flight_bytes);
 +    }
 +}
 +
  /*
   * Reset bits in copy_bitmap starting at offset if they represent unallocated
   * data in the image. May reset subsequent contiguous bits.
@@@ -682,7 -700,14 +683,7 @@@ int64_t block_copy_reset_unallocated(Bl
      bytes = clusters * s->cluster_size;
  
      if (!ret) {
 -        qemu_co_mutex_lock(&s->lock);
 -        bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
 -        if (s->progress) {
 -            progress_set_remaining(s->progress,
 -                                   bdrv_get_dirty_count(s->copy_bitmap) +
 -                                   s->in_flight_bytes);
 -        }
 -        qemu_co_mutex_unlock(&s->lock);
 +        block_copy_reset(s, offset, bytes);
      }
  
      *count = bytes;
@@@ -729,22 -754,22 +730,22 @@@ block_copy_dirty_clusters(BlockCopyCall
              trace_block_copy_skip_range(s, offset, bytes);
              break;
          }
 -        if (task->offset > offset) {
 -            trace_block_copy_skip_range(s, offset, task->offset - offset);
 +        if (task->req.offset > offset) {
 +            trace_block_copy_skip_range(s, offset, task->req.offset - offset);
          }
  
          found_dirty = true;
  
 -        ret = block_copy_block_status(s, task->offset, task->bytes,
 +        ret = block_copy_block_status(s, task->req.offset, task->req.bytes,
                                        &status_bytes);
          assert(ret >= 0); /* never fail */
 -        if (status_bytes < task->bytes) {
 +        if (status_bytes < task->req.bytes) {
              block_copy_task_shrink(task, status_bytes);
          }
          if (qatomic_read(&s->skip_unallocated) &&
              !(ret & BDRV_BLOCK_ALLOCATED)) {
              block_copy_task_end(task, 0);
 -            trace_block_copy_skip_range(s, task->offset, task->bytes);
 +            trace_block_copy_skip_range(s, task->req.offset, task->req.bytes);
              offset = task_end(task);
              bytes = end - offset;
              g_free(task);
              }
          }
  
 -        ratelimit_calculate_delay(&s->rate_limit, task->bytes);
 +        ratelimit_calculate_delay(&s->rate_limit, task->req.bytes);
  
 -        trace_block_copy_process(s, task->offset);
 +        trace_block_copy_process(s, task->req.offset);
  
 -        co_get_from_shres(s->mem, task->bytes);
 +        co_get_from_shres(s->mem, task->req.bytes);
  
          offset = task_end(task);
          bytes = end - offset;
@@@ -837,8 -862,8 +838,8 @@@ static int coroutine_fn block_copy_comm
                   * Check that there is no task we still need to
                   * wait to complete
                   */
 -                ret = block_copy_wait_one(s, call_state->offset,
 -                                          call_state->bytes);
 +                ret = reqlist_wait_one(&s->reqs, call_state->offset,
 +                                       call_state->bytes, &s->lock);
                  if (ret == 0) {
                      /*
                       * No pending tasks, but check again the bitmap in this
                       * between this and the critical section in
                       * block_copy_dirty_clusters().
                       *
 -                     * block_copy_wait_one return value 0 also means that it
 +                     * reqlist_wait_one return value 0 also means that it
                       * didn't release the lock. So, we are still in the same
                       * critical section, not interrupted by any concurrent
                       * access to state.
diff --combined block/io.c
index f0c8da6b9fcf66e7bcb2bf4236f6bb85a0d19078,8e621a49464f16d85b86c396dfc162200f698e08..3280144a17d4e18c718206840fabf58c1aef152b
@@@ -32,6 -32,7 +32,7 @@@
  #include "block/coroutines.h"
  #include "block/write-threshold.h"
  #include "qemu/cutils.h"
+ #include "qemu/memalign.h"
  #include "qapi/error.h"
  #include "qemu/error-report.h"
  #include "qemu/main-loop.h"
@@@ -2203,7 -2204,6 +2204,7 @@@ static int coroutine_fn bdrv_co_do_zero
  
      padding = bdrv_init_padding(bs, offset, bytes, &pad);
      if (padding) {
 +        assert(!(flags & BDRV_REQ_NO_WAIT));
          bdrv_make_request_serialising(req, align);
  
          bdrv_padding_rmw_read(child, req, &pad, true);
@@@ -2340,7 -2340,6 +2341,7 @@@ int coroutine_fn bdrv_co_pwritev_part(B
           * serialize the request to prevent interactions of the
           * widened region with other transactions.
           */
 +        assert(!(flags & BDRV_REQ_NO_WAIT));
          bdrv_make_request_serialising(&req, align);
          bdrv_padding_rmw_read(child, &req, &pad, false);
      }
@@@ -3389,8 -3388,6 +3390,8 @@@ static int coroutine_fn bdrv_co_copy_ra
      /* TODO We can support BDRV_REQ_NO_FALLBACK here */
      assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
      assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
 +    assert(!(read_flags & BDRV_REQ_NO_WAIT));
 +    assert(!(write_flags & BDRV_REQ_NO_WAIT));
  
      if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
          return -ENOMEDIUM;
@@@ -3654,75 -3651,3 +3655,75 @@@ void bdrv_cancel_in_flight(BlockDriverS
          bs->drv->bdrv_cancel_in_flight(bs);
      }
  }
 +
 +int coroutine_fn
 +bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
 +                        QEMUIOVector *qiov, size_t qiov_offset)
 +{
 +    BlockDriverState *bs = child->bs;
 +    BlockDriver *drv = bs->drv;
 +    int ret;
 +    IO_CODE();
 +
 +    if (!drv) {
 +        return -ENOMEDIUM;
 +    }
 +
 +    if (!drv->bdrv_co_preadv_snapshot) {
 +        return -ENOTSUP;
 +    }
 +
 +    bdrv_inc_in_flight(bs);
 +    ret = drv->bdrv_co_preadv_snapshot(bs, offset, bytes, qiov, qiov_offset);
 +    bdrv_dec_in_flight(bs);
 +
 +    return ret;
 +}
 +
 +int coroutine_fn
 +bdrv_co_snapshot_block_status(BlockDriverState *bs,
 +                              bool want_zero, int64_t offset, int64_t bytes,
 +                              int64_t *pnum, int64_t *map,
 +                              BlockDriverState **file)
 +{
 +    BlockDriver *drv = bs->drv;
 +    int ret;
 +    IO_CODE();
 +
 +    if (!drv) {
 +        return -ENOMEDIUM;
 +    }
 +
 +    if (!drv->bdrv_co_snapshot_block_status) {
 +        return -ENOTSUP;
 +    }
 +
 +    bdrv_inc_in_flight(bs);
 +    ret = drv->bdrv_co_snapshot_block_status(bs, want_zero, offset, bytes,
 +                                             pnum, map, file);
 +    bdrv_dec_in_flight(bs);
 +
 +    return ret;
 +}
 +
 +int coroutine_fn
 +bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
 +{
 +    BlockDriver *drv = bs->drv;
 +    int ret;
 +    IO_CODE();
 +
 +    if (!drv) {
 +        return -ENOMEDIUM;
 +    }
 +
 +    if (!drv->bdrv_co_pdiscard_snapshot) {
 +        return -ENOTSUP;
 +    }
 +
 +    bdrv_inc_in_flight(bs);
 +    ret = drv->bdrv_co_pdiscard_snapshot(bs, offset, bytes);
 +    bdrv_dec_in_flight(bs);
 +
 +    return ret;
 +}
diff --combined hw/ide/core.c
index d667d0b55eb936e10bebe012dacce55252b3eb53,a7ac4de18ad90dc607fa98bdb02cd4d2e3ec5702..3a5afff5d70deda547d47f982e4bba38c6898bfe
@@@ -30,6 -30,7 +30,7 @@@
  #include "qemu/main-loop.h"
  #include "qemu/timer.h"
  #include "qemu/hw-version.h"
+ #include "qemu/memalign.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/blockdev.h"
  #include "sysemu/dma.h"
@@@ -434,16 -435,12 +435,16 @@@ static const AIOCBInfo trim_aiocb_info 
  static void ide_trim_bh_cb(void *opaque)
  {
      TrimAIOCB *iocb = opaque;
 +    BlockBackend *blk = iocb->s->blk;
  
      iocb->common.cb(iocb->common.opaque, iocb->ret);
  
      qemu_bh_delete(iocb->bh);
      iocb->bh = NULL;
      qemu_aio_unref(iocb);
 +
 +    /* Paired with an increment in ide_issue_trim() */
 +    blk_dec_in_flight(blk);
  }
  
  static void ide_issue_trim_cb(void *opaque, int ret)
@@@ -513,9 -510,6 +514,9 @@@ BlockAIOCB *ide_issue_trim
      IDEState *s = opaque;
      TrimAIOCB *iocb;
  
 +    /* Paired with a decrement in ide_trim_bh_cb() */
 +    blk_inc_in_flight(s->blk);
 +
      iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
      iocb->s = s;
      iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
diff --combined include/qemu/osdep.h
index 650ba1aa505f47c0fba8d9365e5533c3783e58d0,bc3df26da3683d4b660838413932808fc9600ff9..c9ec7830c9f733b1eb6defad64c6fcd4513c9d20
@@@ -379,28 -379,10 +379,10 @@@ extern "C" 
  #endif
  
  int qemu_daemon(int nochdir, int noclose);
- void *qemu_try_memalign(size_t alignment, size_t size);
- void *qemu_memalign(size_t alignment, size_t size);
  void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
                            bool noreserve);
- void qemu_vfree(void *ptr);
  void qemu_anon_ram_free(void *ptr, size_t size);
  
- /*
-  * It's an analog of GLIB's g_autoptr_cleanup_generic_gfree(), used to define
-  * g_autofree macro.
-  */
- static inline void qemu_cleanup_generic_vfree(void *p)
- {
-   void **pp = (void **)p;
-   qemu_vfree(*pp);
- }
- /*
-  * Analog of g_autofree, but qemu_vfree is called on cleanup instead of g_free.
-  */
- #define QEMU_AUTO_VFREE __attribute__((cleanup(qemu_cleanup_generic_vfree)))
  #ifdef _WIN32
  #define HAVE_CHARDEV_SERIAL 1
  #elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__)    \
@@@ -673,6 -655,19 +655,6 @@@ static inline int platform_does_not_sup
  }
  #endif /* !HAVE_SYSTEM_FUNCTION */
  
 -/**
 - * Duplicate directory entry @dent.
 - *
 - * It is highly recommended to use this function instead of open coding
 - * duplication of @c dirent objects, because the actual @c struct @c dirent
 - * size may be bigger or shorter than @c sizeof(struct dirent) and correct
 - * handling is platform specific (see gitlab issue #841).
 - *
 - * @dent - original directory entry to be duplicated
 - * @returns duplicated directory entry which should be freed with g_free()
 - */
 -struct dirent *qemu_dirent_dup(struct dirent *dent);
 -
  #ifdef __cplusplus
  }
  #endif
diff --combined meson.build
index ace0ed1bc2aa3c8111ca62e740e8c58174d8bb4f,774d0248a6293175ba213a0da644d03ff654a55b..0763c3b6a0f7895494824111fc333b977742b0d8
@@@ -1462,16 -1462,14 +1462,16 @@@ dbus_display = get_option('dbus_display
    .allowed()
  
  have_virtfs = get_option('virtfs') \
 -    .require(targetos == 'linux',
 -             error_message: 'virtio-9p (virtfs) requires Linux') \
 -    .require(libattr.found() and libcap_ng.found(),
 -             error_message: 'virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel') \
 +    .require(targetos == 'linux' or targetos == 'darwin',
 +             error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
 +    .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
 +             error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
 +    .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
 +             error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
      .disable_auto_if(not have_tools and not have_system) \
      .allowed()
  
 -have_virtfs_proxy_helper = have_virtfs and have_tools
 +have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
  
  foreach k : get_option('trace_backends')
    config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
@@@ -1621,10 -1619,14 +1621,15 @@@ config_host_data.set('CONFIG_CLOCK_ADJT
  config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
  config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
  config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
- config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
+ # Note that we need to specify prefix: here to avoid incorrectly
+ # thinking that Windows has posix_memalign()
+ config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
+ config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
+ config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
+ config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
  config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
  config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
 +config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
  config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
  config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
  config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
@@@ -2435,8 -2437,8 +2440,8 @@@ if get_option('cfi') and slirp_opt == '
  endif
  
  fdt = not_found
 -fdt_opt = get_option('fdt')
  if have_system
 +  fdt_opt = get_option('fdt')
    if fdt_opt in ['enabled', 'auto', 'system']
      have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
      fdt = cc.find_library('fdt', kwargs: static_kwargs,
      fdt = declare_dependency(link_with: libfdt,
                               include_directories: fdt_inc)
    endif
 +else
 +  fdt_opt = 'disabled'
  endif
  if not fdt.found() and fdt_required.length() > 0
    error('fdt not available but required by targets ' + ', '.join(fdt_required))
diff --combined softmmu/physmem.c
index 364d563ee425fdf225694ea22e7117920b1276d7,59dcf13faf4577b8fd6b20ee4c999a4c0dc6ace5..43ae70fbe2e8876b2da4340cdde84d3ba85af615
@@@ -42,6 -42,7 +42,7 @@@
  #include "qemu/config-file.h"
  #include "qemu/error-report.h"
  #include "qemu/qemu-print.h"
+ #include "qemu/memalign.h"
  #include "exec/memory.h"
  #include "exec/ioport.h"
  #include "sysemu/dma.h"
@@@ -61,6 -62,7 +62,6 @@@
  
  #include "exec/memory-internal.h"
  #include "exec/ram_addr.h"
 -#include "exec/log.h"
  
  #include "qemu/pmem.h"
  
@@@ -3435,11 -3437,11 +3436,11 @@@ address_space_write_cached_slow(MemoryR
  #include "memory_ldst.c.inc"
  
  /* virtual memory access for debug (includes writing to ROM) */
 -int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
 -                        void *ptr, target_ulong len, bool is_write)
 +int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 +                        void *ptr, size_t len, bool is_write)
  {
      hwaddr phys_addr;
 -    target_ulong l, page;
 +    vaddr l, page;
      uint8_t *buf = ptr;
  
      cpu_synchronize_state(cpu);
diff --combined target/arm/cpu.h
index 0b4b5bbf54cadcd344cbf7db07be9fc7739f5ac6,4aa70ceca12527a1b5bd02d72ecc53e89083babb..157f214cce12d39c7d1314573ecb3125a3f44bac
@@@ -204,10 -204,12 +204,12 @@@ typedef struct 
  # define ARM_MAX_VQ    16
  void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
  void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
+ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
  #else
  # define ARM_MAX_VQ    1
  static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
  static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
+ static inline void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { }
  #endif
  
  typedef struct ARMVectorReg {
@@@ -232,7 -234,7 +234,7 @@@ typedef struct CPUARMTBFlags 
      target_ulong flags2;
  } CPUARMTBFlags;
  
 -typedef struct CPUARMState {
 +typedef struct CPUArchState {
      /* Regs for current mode.  */
      uint32_t regs[16];
  
@@@ -774,7 -776,7 +776,7 @@@ typedef struct ARMISARegisters ARMISARe
   *
   * An ARM CPU core.
   */
 -struct ARMCPU {
 +struct ArchCPU {
      /*< private >*/
      CPUState parent_obj;
      /*< public >*/
  
      /*
       * Intermediate values used during property parsing.
-      * Once finalized, the values should be read from ID_AA64ISAR1.
+      * Once finalized, the values should be read from ID_AA64*.
       */
      bool prop_pauth;
      bool prop_pauth_impdef;
+     bool prop_lpa2;
  
      /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
      uint32_t dcz_blocksize;
@@@ -3410,6 -3413,9 +3413,6 @@@ static inline bool arm_cpu_data_is_big_
      }
  }
  
 -typedef CPUARMState CPUArchState;
 -typedef ARMCPU ArchCPU;
 -
  #include "exec/cpu-all.h"
  
  /*