@@ -125,6 +125,7 @@
#include <asm/hvm/grant_table.h>
#include <asm/pv/grant_table.h>
+#include <asm/pv/mm.h>
#include "pv/emulate.h"
@@ -554,37 +555,6 @@ static inline void guest_unmap_l1e(void *p)
unmap_domain_page(p);
}
-/* Read a PV guest's l1e that maps this virtual address. */
-static inline void guest_get_eff_l1e(unsigned long addr, l1_pgentry_t *eff_l1e)
-{
- ASSERT(!paging_mode_translate(current->domain));
- ASSERT(!paging_mode_external(current->domain));
-
- if ( unlikely(!__addr_ok(addr)) ||
- __copy_from_user(eff_l1e,
- &__linear_l1_table[l1_linear_offset(addr)],
- sizeof(l1_pgentry_t)) )
- *eff_l1e = l1e_empty();
-}
-
-/*
- * Read the guest's l1e that maps this address, from the kernel-mode
- * page tables.
- */
-static inline void guest_get_eff_kern_l1e(struct vcpu *v, unsigned long addr,
- void *eff_l1e)
-{
- const bool user_mode = !(v->arch.flags & TF_kernel_mode);
-
- if ( user_mode )
- toggle_guest_mode(v);
-
- guest_get_eff_l1e(addr, eff_l1e);
-
- if ( user_mode )
- toggle_guest_mode(v);
-}
-
static inline void page_set_tlbflush_timestamp(struct page_info *page)
{
/*
@@ -669,7 +639,7 @@ int map_ldt_shadow_page(unsigned int off)
if ( is_pv_32bit_domain(d) )
gva = (u32)gva;
- guest_get_eff_kern_l1e(v, gva, &l1e);
+ pv_get_guest_eff_kern_l1e(v, gva, &l1e);
if ( unlikely(!(l1e_get_flags(l1e) & _PAGE_PRESENT)) )
return 0;
@@ -5168,7 +5138,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
int rc;
/* Attempt to read the PTE that maps the VA being accessed. */
- guest_get_eff_l1e(addr, &pte);
+ pv_get_guest_eff_l1e(addr, &pte);
/* We are looking only for read-only mappings of p.t. pages. */
if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||
@@ -5323,7 +5293,7 @@ int mmio_ro_do_page_fault(struct vcpu *v, unsigned long addr,
int rc;
/* Attempt to read the PTE that maps the VA being accessed. */
- guest_get_eff_l1e(addr, &pte);
+ pv_get_guest_eff_l1e(addr, &pte);
/* We are looking only for read-only mappings of MMIO pages. */
if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) )
@@ -7,6 +7,7 @@ obj-y += emul-priv-op.o
obj-y += hypercall.o
obj-y += iret.o
obj-y += misc-hypercalls.o
+obj-y += mm.o
obj-y += traps.o
obj-bin-y += dom0_build.init.o
new file mode 100644
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * arch/x86/pv/mm.c
+ *
+ * Memory management code for PV guests
+ *
+ * Copyright (c) 2002-2005 K A Fraser
+ * Copyright (c) 2004 Christian Limpach
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/guest_access.h>
+
+#include <asm/pv/mm.h>
+
+
+/* Read a PV guest's l1e that maps this virtual address. */
+void pv_get_guest_eff_l1e(unsigned long addr, l1_pgentry_t *eff_l1e)
+{
+ ASSERT(!paging_mode_translate(current->domain));
+ ASSERT(!paging_mode_external(current->domain));
+
+ if ( unlikely(!__addr_ok(addr)) ||
+ __copy_from_user(eff_l1e,
+ &__linear_l1_table[l1_linear_offset(addr)],
+ sizeof(l1_pgentry_t)) )
+ *eff_l1e = l1e_empty();
+}
+
+/*
+ * Read the guest's l1e that maps this address, from the kernel-mode
+ * page tables.
+ */
+void pv_get_guest_eff_kern_l1e(struct vcpu *v, unsigned long addr,
+ void *eff_l1e)
+{
+ const bool user_mode = !(v->arch.flags & TF_kernel_mode);
+
+ if ( user_mode )
+ toggle_guest_mode(v);
+
+ pv_get_guest_eff_l1e(addr, eff_l1e);
+
+ if ( user_mode )
+ toggle_guest_mode(v);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
new file mode 100644
@@ -0,0 +1,53 @@
+/*
+ * asm-x86/pv/mm.h
+ *
+ * Memory management interfaces for PV guests
+ *
+ * Copyright (C) 2017 Wei Liu <wei.liu2@citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __X86_PV_MM_H__
+#define __X86_PV_MM_H__
+
+#ifdef CONFIG_PV
+
+void pv_get_guest_eff_l1e(unsigned long addr, l1_pgentry_t *eff_l1e);
+
+void pv_get_guest_eff_kern_l1e(struct vcpu *v, unsigned long addr,
+ void *eff_l1e);
+
+#else
+
+static inline void pv_get_guest_eff_l1e(unsigned long addr,
+ l1_pgentry_t *eff_l1e)
+{}
+
+static inline void pv_get_guest_eff_kern_l1e(struct vcpu *v, unsigned long addr,
+ void *eff_l1e)
+{}
+
+#endif
+
+#endif /* __X86_PV_MM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
Move them to pv/mm.c and rename them to pv_get_guest_eff_{,kern}_l1e. Export them via pv/mm.h. They will be used later in emulation handlers. Signed-off-by: Wei Liu <wei.liu2@citrix.com> --- xen/arch/x86/mm.c | 38 +++---------------------- xen/arch/x86/pv/Makefile | 1 + xen/arch/x86/pv/mm.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/pv/mm.h | 53 +++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 xen/arch/x86/pv/mm.c create mode 100644 xen/include/asm-x86/pv/mm.h