0001
0002 #include <linux/types.h>
0003 #include <linux/crash_dump.h>
0004
0005 #include <xen/interface/xen.h>
0006 #include <xen/hvm.h>
0007
0008 #include "mmu.h"
0009
0010 #ifdef CONFIG_PROC_VMCORE
0011
0012
0013
0014
0015
0016
0017
0018 static bool xen_vmcore_pfn_is_ram(struct vmcore_cb *cb, unsigned long pfn)
0019 {
0020 struct xen_hvm_get_mem_type a = {
0021 .domid = DOMID_SELF,
0022 .pfn = pfn,
0023 };
0024
0025 if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, &a)) {
0026 pr_warn_once("Unexpected HVMOP_get_mem_type failure\n");
0027 return true;
0028 }
0029 return a.mem_type != HVMMEM_mmio_dm;
0030 }
0031 static struct vmcore_cb xen_vmcore_cb = {
0032 .pfn_is_ram = xen_vmcore_pfn_is_ram,
0033 };
0034 #endif
0035
0036 static void xen_hvm_exit_mmap(struct mm_struct *mm)
0037 {
0038 struct xen_hvm_pagetable_dying a;
0039 int rc;
0040
0041 a.domid = DOMID_SELF;
0042 a.gpa = __pa(mm->pgd);
0043 rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
0044 WARN_ON_ONCE(rc < 0);
0045 }
0046
0047 static int is_pagetable_dying_supported(void)
0048 {
0049 struct xen_hvm_pagetable_dying a;
0050 int rc = 0;
0051
0052 a.domid = DOMID_SELF;
0053 a.gpa = 0x00;
0054 rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
0055 if (rc < 0) {
0056 printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n");
0057 return 0;
0058 }
0059 return 1;
0060 }
0061
0062 void __init xen_hvm_init_mmu_ops(void)
0063 {
0064 if (is_pagetable_dying_supported())
0065 pv_ops.mmu.exit_mmap = xen_hvm_exit_mmap;
0066 #ifdef CONFIG_PROC_VMCORE
0067 register_vmcore_cb(&xen_vmcore_cb);
0068 #endif
0069 }