]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
feef87eb VK |
2 | #include <linux/types.h> |
3 | #include <linux/crash_dump.h> | |
4 | ||
5 | #include <xen/interface/xen.h> | |
6 | #include <xen/hvm.h> | |
7 | ||
8 | #include "mmu.h" | |
9 | ||
10 | #ifdef CONFIG_PROC_VMCORE | |
11 | /* | |
12 | * This function is used in two contexts: | |
13 | * - the kdump kernel has to check whether a pfn of the crashed kernel | |
14 | * was a ballooned page. vmcore is using this function to decide | |
15 | * whether to access a pfn of the crashed kernel. | |
16 | * - the kexec kernel has to check whether a pfn was ballooned by the | |
17 | * previous kernel. If the pfn is ballooned, handle it properly. | |
18 | * Returns 0 if the pfn is not backed by a RAM page, the caller may | |
19 | * handle the pfn special in this case. | |
20 | */ | |
21 | static int xen_oldmem_pfn_is_ram(unsigned long pfn) | |
22 | { | |
23 | struct xen_hvm_get_mem_type a = { | |
24 | .domid = DOMID_SELF, | |
25 | .pfn = pfn, | |
26 | }; | |
27 | int ram; | |
28 | ||
29 | if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, &a)) | |
30 | return -ENXIO; | |
31 | ||
32 | switch (a.mem_type) { | |
33 | case HVMMEM_mmio_dm: | |
34 | ram = 0; | |
35 | break; | |
36 | case HVMMEM_ram_rw: | |
37 | case HVMMEM_ram_ro: | |
38 | default: | |
39 | ram = 1; | |
40 | break; | |
41 | } | |
42 | ||
43 | return ram; | |
44 | } | |
45 | #endif | |
46 | ||
47 | static void xen_hvm_exit_mmap(struct mm_struct *mm) | |
48 | { | |
49 | struct xen_hvm_pagetable_dying a; | |
50 | int rc; | |
51 | ||
52 | a.domid = DOMID_SELF; | |
53 | a.gpa = __pa(mm->pgd); | |
54 | rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a); | |
55 | WARN_ON_ONCE(rc < 0); | |
56 | } | |
57 | ||
58 | static int is_pagetable_dying_supported(void) | |
59 | { | |
60 | struct xen_hvm_pagetable_dying a; | |
61 | int rc = 0; | |
62 | ||
63 | a.domid = DOMID_SELF; | |
64 | a.gpa = 0x00; | |
65 | rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a); | |
66 | if (rc < 0) { | |
67 | printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n"); | |
68 | return 0; | |
69 | } | |
70 | return 1; | |
71 | } | |
72 | ||
73 | void __init xen_hvm_init_mmu_ops(void) | |
74 | { | |
75 | if (is_pagetable_dying_supported()) | |
76 | pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap; | |
77 | #ifdef CONFIG_PROC_VMCORE | |
78 | register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram); | |
79 | #endif | |
80 | } |