All of lore.kernel.org
 help / color / mirror / Atom feed
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: Mon, 19 Jan 2009 08:56:23 -0600	[thread overview]
Message-ID: <49749497.6040701@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>
> ---
>  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;
>   

I like the bouncing approach.  Namely, that it never bounces more than a 
page at a time.  I think that's clever.

Could you add some documentation to this function?  Namely, making it 
clear that it can return NULL and that if it does, the caller must retry.

> +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;
>   

If map() fails, how does the caller determine when to retry the mapping?

Regards,

Anthony Liguori

> +}
>  
>  /* warning: addr must be aligned */
>  uint32_t ldl_phys(target_phys_addr_t addr)
>   

  parent reply	other threads:[~2009-01-19 14:56 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   ` Anthony Liguori [this message]
2009-01-19 15:03     ` [Qemu-devel] " Avi Kivity
2009-01-19 15:49       ` Anthony Liguori
2009-01-19 15:51         ` Avi Kivity
2009-01-20 18:43   ` Anthony Liguori
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=49749497.6040701@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.