1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
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 | * The kdump kernel has to check whether a pfn of the crashed kernel |
13 | * was a ballooned page. vmcore is using this function to decide |
14 | * whether to access a pfn of the crashed kernel. |
15 | * Returns "false" if the pfn is not backed by a RAM page, the caller may |
16 | * handle the pfn special in this case. |
17 | */ |
18 | static bool xen_vmcore_pfn_is_ram(struct vmcore_cb *cb, unsigned long pfn) |
19 | { |
20 | struct xen_hvm_get_mem_type a = { |
21 | .domid = DOMID_SELF, |
22 | .pfn = pfn, |
23 | }; |
24 | |
25 | if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, arg: &a)) { |
26 | pr_warn_once("Unexpected HVMOP_get_mem_type failure\n"); |
27 | return true; |
28 | } |
29 | return a.mem_type != HVMMEM_mmio_dm; |
30 | } |
31 | static struct vmcore_cb xen_vmcore_cb = { |
32 | .pfn_is_ram = xen_vmcore_pfn_is_ram, |
33 | }; |
34 | #endif |
35 | |
36 | static void xen_hvm_exit_mmap(struct mm_struct *mm) |
37 | { |
38 | struct xen_hvm_pagetable_dying a; |
39 | int rc; |
40 | |
41 | a.domid = DOMID_SELF; |
42 | a.gpa = __pa(mm->pgd); |
43 | rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, arg: &a); |
44 | WARN_ON_ONCE(rc < 0); |
45 | } |
46 | |
47 | static int is_pagetable_dying_supported(void) |
48 | { |
49 | struct xen_hvm_pagetable_dying a; |
50 | int rc = 0; |
51 | |
52 | a.domid = DOMID_SELF; |
53 | a.gpa = 0x00; |
54 | rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, arg: &a); |
55 | if (rc < 0) { |
56 | printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n"); |
57 | return 0; |
58 | } |
59 | return 1; |
60 | } |
61 | |
62 | void __init xen_hvm_init_mmu_ops(void) |
63 | { |
64 | if (is_pagetable_dying_supported()) |
65 | pv_ops.mmu.exit_mmap = xen_hvm_exit_mmap; |
66 | #ifdef CONFIG_PROC_VMCORE |
67 | register_vmcore_cb(cb: &xen_vmcore_cb); |
68 | #endif |
69 | } |
70 |