* [Qemu-devel] [RFC 1/2] Add qemu_ram_remap
@ 2010-12-31 5:22 Huang Ying
2011-01-04 20:35 ` [Qemu-devel] " Marcelo Tosatti
0 siblings, 1 reply; 2+ messages in thread
From: Huang Ying @ 2010-12-31 5:22 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti
Cc: Dean Nelson, Andi Kleen, qemu-devel@nongnu.org,
kvm@vger.kernel.org
qemu_ram_remap() unmaps the specified RAM pages, then re-maps these
pages again. This is used by KVM HWPoison support to clear HWPoisoned
page tables across guest rebooting, so that a new page may be
allocated later to recover the memory error.
Signed-off-by: Huang Ying <ying.huang@intel.com>
---
cpu-all.h | 4 +++
cpu-common.h | 1
exec.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 65 insertions(+), 1 deletion(-)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -861,10 +861,14 @@ target_phys_addr_t cpu_get_phys_page_deb
extern int phys_ram_fd;
extern ram_addr_t ram_size;
+/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
+#define RAM_PREALLOC_MASK (1 << 0)
+
typedef struct RAMBlock {
uint8_t *host;
ram_addr_t offset;
ram_addr_t length;
+ uint32_t flags;
char idstr[256];
QLIST_ENTRY(RAMBlock) next;
#if defined(__linux__) && !defined(TARGET_S390X)
--- a/exec.c
+++ b/exec.c
@@ -2845,6 +2845,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(Devic
if (host) {
new_block->host = host;
+ new_block->flags |= RAM_PREALLOC_MASK;
} else {
if (mem_path) {
#if defined (__linux__) && !defined(TARGET_S390X)
@@ -2911,7 +2912,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);
@@ -2934,6 +2937,62 @@ void qemu_ram_free(ram_addr_t addr)
}
+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;
+ }
+ }
+}
+
/* 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,
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -45,6 +45,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(Devic
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size);
void qemu_ram_unmap(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
+void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
/* This should only be used for ram local to a device. */
void *qemu_get_ram_ptr(ram_addr_t addr);
/* This should not be used by devices. */
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Qemu-devel] Re: [RFC 1/2] Add qemu_ram_remap
2010-12-31 5:22 [Qemu-devel] [RFC 1/2] Add qemu_ram_remap Huang Ying
@ 2011-01-04 20:35 ` Marcelo Tosatti
0 siblings, 0 replies; 2+ messages in thread
From: Marcelo Tosatti @ 2011-01-04 20:35 UTC (permalink / raw)
To: Huang Ying, Anthony Liguori
Cc: Dean Nelson, Andi Kleen, Avi Kivity, kvm@vger.kernel.org,
qemu-devel@nongnu.org
On Fri, Dec 31, 2010 at 01:22:34PM +0800, Huang Ying wrote:
> qemu_ram_remap() unmaps the specified RAM pages, then re-maps these
> pages again. This is used by KVM HWPoison support to clear HWPoisoned
> page tables across guest rebooting, so that a new page may be
> allocated later to recover the memory error.
>
> Signed-off-by: Huang Ying <ying.huang@intel.com>
> ---
> cpu-all.h | 4 +++
> cpu-common.h | 1
> exec.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 65 insertions(+), 1 deletion(-)
>
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -861,10 +861,14 @@ target_phys_addr_t cpu_get_phys_page_deb
> extern int phys_ram_fd;
> extern ram_addr_t ram_size;
>
> +/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
> +#define RAM_PREALLOC_MASK (1 << 0)
> +
> typedef struct RAMBlock {
> uint8_t *host;
> ram_addr_t offset;
> ram_addr_t length;
> + uint32_t flags;
> char idstr[256];
> QLIST_ENTRY(RAMBlock) next;
> #if defined(__linux__) && !defined(TARGET_S390X)
> --- a/exec.c
> +++ b/exec.c
> @@ -2845,6 +2845,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(Devic
>
> if (host) {
> new_block->host = host;
> + new_block->flags |= RAM_PREALLOC_MASK;
> } else {
> if (mem_path) {
> #if defined (__linux__) && !defined(TARGET_S390X)
> @@ -2911,7 +2912,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)
> + ;
Missing braces.
Otherwise looks fine to me.
Should be merged upstream QEMU... Anthony?
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-01-04 20:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-31 5:22 [Qemu-devel] [RFC 1/2] Add qemu_ram_remap Huang Ying
2011-01-04 20:35 ` [Qemu-devel] " Marcelo Tosatti
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).