summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2011-04-14 03:24:37 -0300
committerMarcelo Tosatti <mtosatti@redhat.com>2011-04-14 03:24:37 -0300
commit69087c73628a3d901ea13ebe8b643802a07d43ec (patch)
tree78642bd5041cb1c8d34c6aa24ce2e20687b80fa2 /exec.c
parentd236bdd7324a782ce521f0b02a1d664d1603aa5e (diff)
parent3c85e74fbf9e5a39d8d13ef91a5f3dd91f0bc8a8 (diff)
Merge commit '3c85e74fbf9e5a39d8d13ef91a5f3dd91f0bc8a8' into upstream-merge
* commit '3c85e74fbf9e5a39d8d13ef91a5f3dd91f0bc8a8': KVM, MCE, unpoison memory address across reboot Add qemu_ram_remap kvm: x86: Fail kvm_arch_init_vcpu if MCE initialization fails kvm: x86: Clean up kvm_setup_mce Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/exec.c b/exec.c
index bb0c1be4d..5985aa24e 100644
--- a/exec.c
+++ b/exec.c
@@ -2883,6 +2883,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
if (host) {
new_block->host = host;
+ new_block->flags |= RAM_PREALLOC_MASK;
} else {
if (mem_path) {
#if defined (__linux__) && !defined(TARGET_S390X)
@@ -2949,7 +2950,9 @@ void qemu_ram_free(ram_addr_t addr)
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr == block->offset) {
QLIST_REMOVE(block, next);
- if (mem_path) {
+ if (block->flags & RAM_PREALLOC_MASK) {
+ ;
+ } else if (mem_path) {
#if defined (__linux__) && !defined(TARGET_S390X)
if (block->fd) {
munmap(block->host, block->length);
@@ -2972,6 +2975,64 @@ void qemu_ram_free(ram_addr_t addr)
}
+#ifndef _WIN32
+void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
+{
+ RAMBlock *block;
+ ram_addr_t offset;
+ int flags;
+ void *area, *vaddr;
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ offset = addr - block->offset;
+ if (offset < block->length) {
+ vaddr = block->host + offset;
+ if (block->flags & RAM_PREALLOC_MASK) {
+ ;
+ } else {
+ flags = MAP_FIXED;
+ munmap(vaddr, length);
+ if (mem_path) {
+#if defined(__linux__) && !defined(TARGET_S390X)
+ if (block->fd) {
+#ifdef MAP_POPULATE
+ flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
+ MAP_PRIVATE;
+#else
+ flags |= MAP_PRIVATE;
+#endif
+ area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
+ flags, block->fd, offset);
+ } else {
+ flags |= MAP_PRIVATE | MAP_ANONYMOUS;
+ area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
+ flags, -1, 0);
+ }
+#endif
+ } else {
+#if defined(TARGET_S390X) && defined(CONFIG_KVM)
+ flags |= MAP_SHARED | MAP_ANONYMOUS;
+ area = mmap(vaddr, length, PROT_EXEC|PROT_READ|PROT_WRITE,
+ flags, -1, 0);
+#else
+ flags |= MAP_PRIVATE | MAP_ANONYMOUS;
+ area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
+ flags, -1, 0);
+#endif
+ }
+ if (area != vaddr) {
+ fprintf(stderr, "Could not remap addr: %lx@%lx\n",
+ length, addr);
+ exit(1);
+ }
+ qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE);
+ }
+ return;
+ }
+ }
+}
+#endif /* !_WIN32 */
+
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,