1 /* 2 * Variable page size handling -- target specific part. 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #define IN_PAGE_VARY 1 21 22 #include "qemu/osdep.h" 23 #include "exec/page-vary.h" 24 #include "exec/target_page.h" 25 26 27 /* 28 * For system mode, the minimum comes from the number of bits 29 * required for maximum alignment (6) and the number of bits 30 * required for TLB_FLAGS_MASK (3). 31 * 32 * For user mode, TARGET_PAGE_BITS_VARY is a hack to allow the target 33 * page size to match the host page size. Mostly, this reduces the 34 * ordinary target page size to run on a host with 4KiB pages (i.e. x86). 35 * There is no true minimum required by the implementation, but keep the 36 * same minimum as for system mode for sanity. 37 * See linux-user/mmap.c, mmap_h_lt_g and mmap_h_gt_g. 38 */ 39 #define TARGET_PAGE_BITS_MIN 9 40 41 #ifndef TARGET_PAGE_BITS_VARY 42 QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN); 43 #endif 44 45 #ifndef CONFIG_USER_ONLY 46 #include "exec/tlb-flags.h" 47 48 QEMU_BUILD_BUG_ON(TLB_FLAGS_MASK & ((1u < TARGET_PAGE_BITS_MIN) - 1)); 49 migration_legacy_page_bits(void)50int migration_legacy_page_bits(void) 51 { 52 #ifdef TARGET_PAGE_BITS_VARY 53 QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS_LEGACY < TARGET_PAGE_BITS_MIN); 54 return TARGET_PAGE_BITS_LEGACY; 55 #else 56 return TARGET_PAGE_BITS; 57 #endif 58 } 59 #endif 60 set_preferred_target_page_bits(int bits)61bool set_preferred_target_page_bits(int bits) 62 { 63 assert(bits >= TARGET_PAGE_BITS_MIN); 64 #ifdef TARGET_PAGE_BITS_VARY 65 return set_preferred_target_page_bits_common(bits); 66 #else 67 return true; 68 #endif 69 } 70 finalize_target_page_bits(void)71void finalize_target_page_bits(void) 72 { 73 #ifndef TARGET_PAGE_BITS_VARY 74 finalize_target_page_bits_common(TARGET_PAGE_BITS); 75 #elif defined(CONFIG_USER_ONLY) 76 assert(target_page.bits != 0); 77 finalize_target_page_bits_common(target_page.bits); 78 #else 79 finalize_target_page_bits_common(TARGET_PAGE_BITS_LEGACY); 80 #endif 81 } 82