From: Anthony Liguori <anthony@codemonkey.ws>
To: Avi Kivity <avi@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [PATCH 1/5] Add target memory mapping API
Date: Tue, 20 Jan 2009 12:43:54 -0600 [thread overview]
Message-ID: <49761B6A.2020806@codemonkey.ws> (raw)
In-Reply-To: <1232308399-21679-2-git-send-email-avi@redhat.com>
Avi Kivity wrote:
> Devices accessing large amounts of memory (as with DMA) will wish to obtain
> a pointer to guest memory rather than access it indirectly via
> cpu_physical_memory_rw(). Add a new API to convert target addresses to
> host pointers.
>
> In case the target address does not correspond to RAM, a bounce buffer is
> allocated. To prevent the guest from causing the host to allocate unbounded
> amounts of bounce buffer, this memory is limited (currently to one page).
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
>
I've gone though the thread again and I think this patch series is a
pretty good start. I think the API can be refined a bit more down the
road to better support Xen but I think this is a good start.
Does anyone have major blockers with this API? If not, I'd like to
commit these patches. The consumers of it should be small provided that
we make sure to write helpers for the various types of IO pipelines.
Regards,
Anthony Liguori
> ---
> cpu-all.h | 5 +++
> exec.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 98 insertions(+), 0 deletions(-)
>
> diff --git a/cpu-all.h b/cpu-all.h
> index ee0a6e3..3439999 100644
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -923,6 +923,11 @@ static inline void cpu_physical_memory_write(target_phys_addr_t addr,
> {
> cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
> }
> +void *cpu_physical_memory_map(target_phys_addr_t addr,
> + target_phys_addr_t *plen,
> + int is_write);
> +void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
> + int is_write);
> uint32_t ldub_phys(target_phys_addr_t addr);
> uint32_t lduw_phys(target_phys_addr_t addr);
> uint32_t ldl_phys(target_phys_addr_t addr);
> diff --git a/exec.c b/exec.c
> index faa6333..7162271 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -3045,6 +3045,99 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
> }
> }
>
> +typedef struct {
> + void *buffer;
> + target_phys_addr_t addr;
> + target_phys_addr_t len;
> +} BounceBuffer;
> +
> +static BounceBuffer bounce;
> +
> +void *cpu_physical_memory_map(target_phys_addr_t addr,
> + target_phys_addr_t *plen,
> + int is_write)
> +{
> + target_phys_addr_t len = *plen;
> + target_phys_addr_t done = 0;
> + int l;
> + uint8_t *ret = NULL;
> + uint8_t *ptr;
> + target_phys_addr_t page;
> + unsigned long pd;
> + PhysPageDesc *p;
> + unsigned long addr1;
> +
> + while (len > 0) {
> + page = addr & TARGET_PAGE_MASK;
> + l = (page + TARGET_PAGE_SIZE) - addr;
> + if (l > len)
> + l = len;
> + p = phys_page_find(page >> TARGET_PAGE_BITS);
> + if (!p) {
> + pd = IO_MEM_UNASSIGNED;
> + } else {
> + pd = p->phys_offset;
> + }
> +
> + if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
> + if (done || bounce.buffer) {
> + break;
> + }
> + bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE);
> + bounce.addr = addr;
> + bounce.len = l;
> + if (!is_write) {
> + cpu_physical_memory_rw(addr, bounce.buffer, l, 0);
> + }
> + ptr = bounce.buffer;
> + } else {
> + addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
> + ptr = phys_ram_base + addr1;
> + }
> + if (!done) {
> + ret = ptr;
> + } else if (ret + done != ptr) {
> + break;
> + }
> +
> + len -= l;
> + addr += l;
> + done += l;
> + }
> + *plen = done;
> + return ret;
> +}
> +
> +void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
> + int is_write)
> +{
> + if (buffer != bounce.buffer) {
> + if (is_write) {
> + unsigned long addr1 = (uint8_t *)buffer - phys_ram_base;
> + do {
> + unsigned l;
> + l = TARGET_PAGE_SIZE;
> + if (l > len)
> + l = len;
> + if (!cpu_physical_memory_is_dirty(addr1)) {
> + /* invalidate code */
> + tb_invalidate_phys_page_range(addr1, addr1 + len, 0);
> + /* set dirty bit */
> + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
> + (0xff & ~CODE_DIRTY_FLAG);
> + }
> + addr1 += l;
> + len -= l;
> + } while (len);
> + }
> + return;
> + }
> + if (is_write) {
> + cpu_physical_memory_write(bounce.addr, bounce.buffer, bounce.len);
> + }
> + qemu_free(bounce.buffer);
> + bounce.buffer = NULL;
> +}
>
> /* warning: addr must be aligned */
> uint32_t ldl_phys(target_phys_addr_t addr)
>
next prev parent reply other threads:[~2009-01-20 18:44 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-18 19:53 [Qemu-devel] [PATCH 0/5] Direct memory access for devices Avi Kivity
2009-01-18 19:53 ` [Qemu-devel] [PATCH 1/5] Add target memory mapping API Avi Kivity
2009-01-19 13:49 ` Ian Jackson
2009-01-19 14:54 ` Avi Kivity
2009-01-19 15:39 ` Anthony Liguori
2009-01-19 16:18 ` Paul Brook
2009-01-19 16:33 ` Anthony Liguori
2009-01-19 16:39 ` Avi Kivity
2009-01-19 19:15 ` Anthony Liguori
2009-01-20 10:09 ` Avi Kivity
2009-01-19 16:57 ` Ian Jackson
2009-01-19 19:23 ` Anthony Liguori
2009-01-20 10:17 ` Avi Kivity
2009-01-20 14:18 ` Ian Jackson
2009-01-19 16:40 ` Ian Jackson
2009-01-19 17:28 ` Avi Kivity
2009-01-19 17:53 ` Ian Jackson
2009-01-19 18:29 ` Avi Kivity
2009-01-20 14:32 ` Ian Jackson
2009-01-20 17:23 ` Avi Kivity
2009-01-19 18:25 ` Jamie Lokier
2009-01-19 18:43 ` Avi Kivity
2009-01-20 14:49 ` Ian Jackson
2009-01-20 17:42 ` Avi Kivity
2009-01-20 18:08 ` Jamie Lokier
2009-01-20 20:27 ` Avi Kivity
2009-01-21 16:53 ` Ian Jackson
2009-01-21 16:50 ` Ian Jackson
2009-01-21 17:18 ` Avi Kivity
2009-01-21 21:54 ` Anthony Liguori
2009-01-20 14:44 ` Ian Jackson
2009-01-21 12:06 ` [Qemu-devel] " Mike Day
2009-01-21 12:18 ` Avi Kivity
2009-01-19 15:05 ` [Qemu-devel] [PATCH 1/5] " Gerd Hoffmann
2009-01-19 15:23 ` Avi Kivity
2009-01-19 15:29 ` Avi Kivity
2009-01-19 15:57 ` Gerd Hoffmann
2009-01-19 16:25 ` Avi Kivity
2009-01-19 17:08 ` Ian Jackson
2009-01-19 17:16 ` Avi Kivity
2009-01-19 14:56 ` [Qemu-devel] " Anthony Liguori
2009-01-19 15:03 ` Avi Kivity
2009-01-19 15:49 ` Anthony Liguori
2009-01-19 15:51 ` Avi Kivity
2009-01-20 18:43 ` Anthony Liguori [this message]
2009-01-21 17:09 ` Ian Jackson
2009-01-21 18:56 ` [Qemu-devel] " Mike Day
2009-01-21 19:35 ` Avi Kivity
2009-01-21 19:36 ` [Qemu-devel] Re: [PATCH 1/5] " Anthony Liguori
2009-01-22 12:18 ` Ian Jackson
2009-01-22 18:46 ` Anthony Liguori
2009-01-26 12:23 ` Ian Jackson
2009-01-26 18:03 ` Anthony Liguori
2009-01-21 11:52 ` [Qemu-devel] " Mike Day
2009-01-21 12:17 ` Avi Kivity
2009-01-21 17:37 ` Paul Brook
2009-01-18 19:53 ` [Qemu-devel] [PATCH 2/5] Add map client retry notification Avi Kivity
2009-01-19 14:58 ` [Qemu-devel] " Anthony Liguori
2009-01-18 19:53 ` [Qemu-devel] [PATCH 3/5] Vectored block device API Avi Kivity
2009-01-19 16:54 ` Blue Swirl
2009-01-19 17:19 ` Avi Kivity
2009-01-18 19:53 ` [Qemu-devel] [PATCH 4/5] I/O vector helpers Avi Kivity
2009-01-18 19:53 ` [Qemu-devel] [PATCH 5/5] Convert IDE to directly access guest memory Avi Kivity
2009-01-19 16:50 ` [Qemu-devel] [PATCH 0/5] Direct memory access for devices Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49761B6A.2020806@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=avi@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).