| Submitter | Cam Macdonell |
|---|---|
| Date | April 21, 2010, 5:53 p.m. |
| Message ID | <1271872408-22842-3-git-send-email-cam@cs.ualberta.ca> |
| Download | mbox | patch |
| Permalink | /patch/50669/ |
| State | New |
| Headers | show |
Comments
On 04/21/2010 08:53 PM, Cam Macdonell wrote: > This avoids the need of using qemu_ram_alloc and mmap with MAP_FIXED to map a > host file into guest RAM. This function mmaps the opened file anywhere and adds > the memory to the ram blocks. > > Usage is > > qemu_ram_mmap(fd, size, MAP_SHARED, offset); > Signoff? > > +ram_addr_t qemu_ram_mmap(int fd, ram_addr_t size, int flags, off_t offset) > +{ > + RAMBlock *new_block; > + > + size = TARGET_PAGE_ALIGN(size); > + new_block = qemu_malloc(sizeof(*new_block)); > + > + /* map the file passed as a parameter to be this part of memory */ > + new_block->host = mmap(0, size, PROT_READ|PROT_WRITE, flags, fd, offset); > + > + if (new_block->host == MAP_FAILED) > + exit(1); > Braces after if () > + if (kvm_enabled()) > + kvm_setup_guest_memory(new_block->host, size); > + > More braces.
On Mon, May 10, 2010 at 4:39 AM, Avi Kivity <avi@redhat.com> wrote: > On 04/21/2010 08:53 PM, Cam Macdonell wrote: >> >> This avoids the need of using qemu_ram_alloc and mmap with MAP_FIXED to >> map a >> host file into guest RAM. This function mmaps the opened file anywhere >> and adds >> the memory to the ram blocks. >> >> Usage is >> >> qemu_ram_mmap(fd, size, MAP_SHARED, offset); >> > > Signoff? >> >> +ram_addr_t qemu_ram_mmap(int fd, ram_addr_t size, int flags, off_t >> offset) >> +{ >> + RAMBlock *new_block; >> + >> + size = TARGET_PAGE_ALIGN(size); >> + new_block = qemu_malloc(sizeof(*new_block)); >> + >> + /* map the file passed as a parameter to be this part of memory */ >> + new_block->host = mmap(0, size, PROT_READ|PROT_WRITE, flags, fd, >> offset); >> + >> + if (new_block->host == MAP_FAILED) >> + exit(1); >> > > Braces after if () > >> + if (kvm_enabled()) >> + kvm_setup_guest_memory(new_block->host, size); >> + >> > > More braces. > This function is possibly made redundant by Marcelo's patch for qemu_ram_map http://kerneltrap.org/mailarchive/linux-kvm/2010/4/26/6261299 qemu_ram_map isn't merged yet either, but I'm fine with either one. Marcelo's requires the device to map the memory and then pass the pointer to be added to the memory allocation, so it gives the device full mapping control. Alternatively, I could add the protection flag to my function (I think that's all that is missing). Let me know and I'll change my patch if necessary. > -- > error compiling committee.c: too many arguments to function > >
Patch
diff --git a/cpu-common.h b/cpu-common.h index 49c7fb3..d7c7d3a 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -9,6 +9,7 @@ #include "bswap.h" #include "qemu-queue.h" +#include <sys/types.h> #if !defined(CONFIG_USER_ONLY) @@ -32,6 +33,7 @@ static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, } ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); +ram_addr_t qemu_ram_mmap(int fd, ram_addr_t addr, int flags, off_t offset); ram_addr_t qemu_ram_alloc(ram_addr_t); void qemu_ram_free(ram_addr_t addr); /* This should only be used for ram local to a device. */ diff --git a/exec.c b/exec.c index 467a0e7..702348e 100644 --- a/exec.c +++ b/exec.c @@ -2811,6 +2811,42 @@ static void *file_ram_alloc(ram_addr_t memory, const char *path) } #endif +ram_addr_t qemu_ram_mmap(int fd, ram_addr_t size, int flags, off_t offset) +{ + RAMBlock *new_block; + + size = TARGET_PAGE_ALIGN(size); + new_block = qemu_malloc(sizeof(*new_block)); + + /* map the file passed as a parameter to be this part of memory */ + new_block->host = mmap(0, size, PROT_READ|PROT_WRITE, flags, fd, offset); + + if (new_block->host == MAP_FAILED) + exit(1); + +#ifdef MADV_MERGEABLE + madvise(new_block->host, size, MADV_MERGEABLE); +#endif + + new_block->offset = last_ram_offset; + new_block->length = size; + + new_block->next = ram_blocks; + ram_blocks = new_block; + + phys_ram_dirty = qemu_realloc(phys_ram_dirty, + (last_ram_offset + size) >> TARGET_PAGE_BITS); + memset(phys_ram_dirty + (last_ram_offset >> TARGET_PAGE_BITS), + 0xff, size >> TARGET_PAGE_BITS); + + last_ram_offset += size; + + if (kvm_enabled()) + kvm_setup_guest_memory(new_block->host, size); + + return new_block->offset; +} + ram_addr_t qemu_ram_alloc(ram_addr_t size) { RAMBlock *new_block;