diff options
author | Olaf Hering <olaf@aepfle.de> | 2012-10-01 15:18:01 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-10-04 11:30:30 -0400 |
commit | 34b6f01a79bd65fbd06511d2cb7b28e33a506246 (patch) | |
tree | 68adb1dad56bf5e11971a8344e4d3cbb09052a54 | |
parent | 9b6934a3b449266850149b717597408354039e95 (diff) |
xen pv-on-hvm: add pfn_is_ram helper for kdump
Register pfn_is_ram helper speed up reading /proc/vmcore in the kdump
kernel. See commit message of 997c136f518c ("fs/proc/vmcore.c: add hook
to read_from_oldmem() to check for non-ram pages") for details.
It makes use of a new hvmop HVMOP_get_mem_type which was introduced in
xen 4.2 (23298:26413986e6e0) and backported to 4.1.1.
The new function is currently only enabled for reading /proc/vmcore.
Later it will be used also for the kexec kernel. Since that requires
more changes in the generic kernel make it static for the time being.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r-- | arch/x86/xen/mmu.c | 41 | ||||
-rw-r--r-- | include/xen/interface/hvm/hvm_op.h | 19 |
2 files changed, 60 insertions, 0 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 5a16824cc2b3..963cb2df636a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/gfp.h> | 47 | #include <linux/gfp.h> |
48 | #include <linux/memblock.h> | 48 | #include <linux/memblock.h> |
49 | #include <linux/seq_file.h> | 49 | #include <linux/seq_file.h> |
50 | #include <linux/crash_dump.h> | ||
50 | 51 | ||
51 | #include <trace/events/xen.h> | 52 | #include <trace/events/xen.h> |
52 | 53 | ||
@@ -2381,6 +2382,43 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) | |||
2381 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); | 2382 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); |
2382 | 2383 | ||
2383 | #ifdef CONFIG_XEN_PVHVM | 2384 | #ifdef CONFIG_XEN_PVHVM |
2385 | #ifdef CONFIG_PROC_VMCORE | ||
2386 | /* | ||
2387 | * This function is used in two contexts: | ||
2388 | * - the kdump kernel has to check whether a pfn of the crashed kernel | ||
2389 | * was a ballooned page. vmcore is using this function to decide | ||
2390 | * whether to access a pfn of the crashed kernel. | ||
2391 | * - the kexec kernel has to check whether a pfn was ballooned by the | ||
2392 | * previous kernel. If the pfn is ballooned, handle it properly. | ||
2393 | * Returns 0 if the pfn is not backed by a RAM page, the caller may | ||
2394 | * handle the pfn special in this case. | ||
2395 | */ | ||
2396 | static int xen_oldmem_pfn_is_ram(unsigned long pfn) | ||
2397 | { | ||
2398 | struct xen_hvm_get_mem_type a = { | ||
2399 | .domid = DOMID_SELF, | ||
2400 | .pfn = pfn, | ||
2401 | }; | ||
2402 | int ram; | ||
2403 | |||
2404 | if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, &a)) | ||
2405 | return -ENXIO; | ||
2406 | |||
2407 | switch (a.mem_type) { | ||
2408 | case HVMMEM_mmio_dm: | ||
2409 | ram = 0; | ||
2410 | break; | ||
2411 | case HVMMEM_ram_rw: | ||
2412 | case HVMMEM_ram_ro: | ||
2413 | default: | ||
2414 | ram = 1; | ||
2415 | break; | ||
2416 | } | ||
2417 | |||
2418 | return ram; | ||
2419 | } | ||
2420 | #endif | ||
2421 | |||
2384 | static void xen_hvm_exit_mmap(struct mm_struct *mm) | 2422 | static void xen_hvm_exit_mmap(struct mm_struct *mm) |
2385 | { | 2423 | { |
2386 | struct xen_hvm_pagetable_dying a; | 2424 | struct xen_hvm_pagetable_dying a; |
@@ -2411,6 +2449,9 @@ void __init xen_hvm_init_mmu_ops(void) | |||
2411 | { | 2449 | { |
2412 | if (is_pagetable_dying_supported()) | 2450 | if (is_pagetable_dying_supported()) |
2413 | pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap; | 2451 | pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap; |
2452 | #ifdef CONFIG_PROC_VMCORE | ||
2453 | register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram); | ||
2454 | #endif | ||
2414 | } | 2455 | } |
2415 | #endif | 2456 | #endif |
2416 | 2457 | ||
diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h index a4827f46ee97..956a04682865 100644 --- a/include/xen/interface/hvm/hvm_op.h +++ b/include/xen/interface/hvm/hvm_op.h | |||
@@ -43,4 +43,23 @@ struct xen_hvm_pagetable_dying { | |||
43 | typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; | 43 | typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; |
44 | DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t); | 44 | DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t); |
45 | 45 | ||
46 | enum hvmmem_type_t { | ||
47 | HVMMEM_ram_rw, /* Normal read/write guest RAM */ | ||
48 | HVMMEM_ram_ro, /* Read-only; writes are discarded */ | ||
49 | HVMMEM_mmio_dm, /* Reads and write go to the device model */ | ||
50 | }; | ||
51 | |||
52 | #define HVMOP_get_mem_type 15 | ||
53 | /* Return hvmmem_type_t for the specified pfn. */ | ||
54 | struct xen_hvm_get_mem_type { | ||
55 | /* Domain to be queried. */ | ||
56 | domid_t domid; | ||
57 | /* OUT variable. */ | ||
58 | uint16_t mem_type; | ||
59 | uint16_t pad[2]; /* align next field on 8-byte boundary */ | ||
60 | /* IN variable. */ | ||
61 | uint64_t pfn; | ||
62 | }; | ||
63 | DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_get_mem_type); | ||
64 | |||
46 | #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ | 65 | #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ |