0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <asm/xen/hypercall.h>
0014
0015 #include <xen/interface/memory.h>
0016 #include <xen/mem-reservation.h>
0017 #include <linux/moduleparam.h>
0018
0019 bool __read_mostly xen_scrub_pages = IS_ENABLED(CONFIG_XEN_SCRUB_PAGES_DEFAULT);
0020 core_param(xen_scrub_pages, xen_scrub_pages, bool, 0);
0021
0022
0023
0024
0025
0026 #define EXTENT_ORDER (fls(XEN_PFN_PER_PAGE) - 1)
0027
0028 #ifdef CONFIG_XEN_HAVE_PVMMU
0029 void __xenmem_reservation_va_mapping_update(unsigned long count,
0030 struct page **pages,
0031 xen_pfn_t *frames)
0032 {
0033 int i;
0034
0035 for (i = 0; i < count; i++) {
0036 struct page *page = pages[i];
0037 unsigned long pfn = page_to_pfn(page);
0038 int ret;
0039
0040 BUG_ON(!page);
0041
0042
0043
0044
0045
0046 BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
0047
0048 set_phys_to_machine(pfn, frames[i]);
0049
0050 ret = HYPERVISOR_update_va_mapping(
0051 (unsigned long)__va(pfn << PAGE_SHIFT),
0052 mfn_pte(frames[i], PAGE_KERNEL), 0);
0053 BUG_ON(ret);
0054 }
0055 }
0056 EXPORT_SYMBOL_GPL(__xenmem_reservation_va_mapping_update);
0057
0058 void __xenmem_reservation_va_mapping_reset(unsigned long count,
0059 struct page **pages)
0060 {
0061 int i;
0062
0063 for (i = 0; i < count; i++) {
0064 struct page *page = pages[i];
0065 unsigned long pfn = page_to_pfn(page);
0066 int ret;
0067
0068
0069
0070
0071
0072 BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
0073
0074 ret = HYPERVISOR_update_va_mapping(
0075 (unsigned long)__va(pfn << PAGE_SHIFT),
0076 __pte_ma(0), 0);
0077 BUG_ON(ret);
0078
0079 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
0080 }
0081 }
0082 EXPORT_SYMBOL_GPL(__xenmem_reservation_va_mapping_reset);
0083 #endif
0084
0085
0086 int xenmem_reservation_increase(int count, xen_pfn_t *frames)
0087 {
0088 struct xen_memory_reservation reservation = {
0089 .address_bits = 0,
0090 .extent_order = EXTENT_ORDER,
0091 .domid = DOMID_SELF
0092 };
0093
0094
0095 set_xen_guest_handle(reservation.extent_start, frames);
0096 reservation.nr_extents = count;
0097 return HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
0098 }
0099 EXPORT_SYMBOL_GPL(xenmem_reservation_increase);
0100
0101
0102 int xenmem_reservation_decrease(int count, xen_pfn_t *frames)
0103 {
0104 struct xen_memory_reservation reservation = {
0105 .address_bits = 0,
0106 .extent_order = EXTENT_ORDER,
0107 .domid = DOMID_SELF
0108 };
0109
0110
0111 set_xen_guest_handle(reservation.extent_start, frames);
0112 reservation.nr_extents = count;
0113 return HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
0114 }
0115 EXPORT_SYMBOL_GPL(xenmem_reservation_decrease);