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