#ifndef _VM_VM_MAP_H_
#define _VM_VM_MAP_H_
#ifndef _SYS_TYPES_H_
#include <sys/types.h>
#endif
#ifdef _KERNEL
#ifndef _SYS_KERNEL_H_
#include <sys/kernel.h>
#endif
#endif
#ifndef _SYS_TREE_H_
#include <sys/tree.h>
#endif
#ifndef _SYS_LOCK_H_
#include <sys/lock.h>
#endif
#ifndef _SYS_VKERNEL_H_
#include <sys/vkernel.h>
#endif
#ifndef _VM_VM_H_
#include <vm/vm.h>
#endif
#ifndef _MACHINE_PMAP_H_
#include <machine/pmap.h>
#endif
#ifndef _VM_VM_OBJECT_H_
#include <vm/vm_object.h>
#endif
#ifndef _SYS_NULL_H_
#include <sys/_null.h>
#endif
struct vm_map_rb_tree;
RB_PROTOTYPE(vm_map_rb_tree, vm_map_entry, rb_entry, rb_vm_map_compare);
typedef u_int vm_flags_t;
typedef u_int vm_eflags_t;
union vm_map_aux {
vm_offset_t avail_ssize;
vpte_t master_pde;
struct cdev *dev;
void *map_aux;
};
typedef enum {
VM_SUBSYS_UNKNOWN,
VM_SUBSYS_KMALLOC,
VM_SUBSYS_STACK,
VM_SUBSYS_IMGACT,
VM_SUBSYS_EFI,
VM_SUBSYS_RESERVED,
VM_SUBSYS_INIT,
VM_SUBSYS_PIPE,
VM_SUBSYS_PROC,
VM_SUBSYS_SHMEM,
VM_SUBSYS_SYSMAP,
VM_SUBSYS_MMAP,
VM_SUBSYS_BRK,
VM_SUBSYS_BOGUS,
VM_SUBSYS_BUF,
VM_SUBSYS_BUFDATA,
VM_SUBSYS_GD,
VM_SUBSYS_IPIQ,
VM_SUBSYS_PVENTRY,
VM_SUBSYS_PML4,
VM_SUBSYS_MAPDEV,
VM_SUBSYS_ZALLOC,
VM_SUBSYS_DM,
VM_SUBSYS_CONTIG,
VM_SUBSYS_DRM,
VM_SUBSYS_DRM_GEM,
VM_SUBSYS_DRM_SCAT,
VM_SUBSYS_DRM_VMAP,
VM_SUBSYS_DRM_TTM,
VM_SUBSYS_HAMMER,
VM_SUBSYS_NVMM,
VM_SUBSYS_VMPGHASH,
VM_SUBSYS_LIMIT
} vm_subsys_t;
#define UKSMAPOP_ADD 1
#define UKSMAPOP_REM 2
#define UKSMAPOP_FAULT 3
struct vm_map_backing {
vm_offset_t start;
vm_offset_t end;
struct pmap *pmap;
struct vm_map_backing *backing_ba;
TAILQ_ENTRY(vm_map_backing) entry;
union {
struct vm_object *object;
struct vm_map *sub_map;
int (*uksmap)(struct vm_map_backing *entry,
int op,
struct cdev *dev,
vm_page_t fake);
void *map_object;
};
void *aux_info;
vm_ooffset_t offset;
uint32_t flags;
uint32_t backing_count;
};
typedef struct vm_map_backing *vm_map_backing_t;
#define VM_MAP_BACK_EXCL_HEUR 0x00000001U
#define VM_MAP_BACK_VPAGETABLE 0x00000002U
struct vm_map_entry {
RB_ENTRY(vm_map_entry) rb_entry;
union vm_map_aux aux;
struct vm_map_backing ba;
vm_eflags_t eflags;
vm_maptype_t maptype;
vm_prot_t protection;
vm_prot_t max_protection;
vm_inherit_t inheritance;
int wired_count;
vm_subsys_t id;
};
typedef struct vm_map_entry *vm_map_entry_t;
#define MAPENT_FREELIST(ent) (ent)->rb_entry.rbe_left
#define MAP_ENTRY_NOSYNC 0x0001
#define MAP_ENTRY_STACK 0x0002
#define MAP_ENTRY_COW 0x0004
#define MAP_ENTRY_NEEDS_COPY 0x0008
#define MAP_ENTRY_NOFAULT 0x0010
#define MAP_ENTRY_USER_WIRED 0x0020
#define MAP_ENTRY_BEHAV_NORMAL 0x0000
#define MAP_ENTRY_BEHAV_SEQUENTIAL 0x0040
#define MAP_ENTRY_BEHAV_RANDOM 0x0080
#define MAP_ENTRY_BEHAV_RESERVED 0x00C0
#define MAP_ENTRY_BEHAV_MASK 0x00C0
#define MAP_ENTRY_IN_TRANSITION 0x0100
#define MAP_ENTRY_NEEDS_WAKEUP 0x0200
#define MAP_ENTRY_NOCOREDUMP 0x0400
#define MAP_ENTRY_KSTACK 0x0800
#define MAP_ENTRY_VPAGETABLE_WIRED 0x1000
#define MAP_CLIP_NO_HOLES 0x0001
#define MAP_RESERVE_COUNT 4
#define MAP_RESERVE_SLOP 512
#define MAP_RESERVE_HYST (MAP_RESERVE_SLOP - MAP_RESERVE_SLOP / 8)
#define FW_WIRED 0x0001
#define FW_DIDCOW 0x0002
static __inline u_char
vm_map_entry_behavior(struct vm_map_entry *entry)
{
return entry->eflags & MAP_ENTRY_BEHAV_MASK;
}
static __inline void
vm_map_entry_set_behavior(struct vm_map_entry *entry, u_char behavior)
{
entry->eflags = (entry->eflags & ~MAP_ENTRY_BEHAV_MASK) |
(behavior & MAP_ENTRY_BEHAV_MASK);
}
struct vm_map_ilock {
struct vm_map_ilock *next;
int flags;
vm_offset_t ran_beg;
vm_offset_t ran_end;
};
#define ILOCK_WAITING 0x00000001
#define VM_MAP_FFCOUNT 4
#define VM_MAP_FFMASK (VM_MAP_FFCOUNT - 1)
struct vm_map_freehint {
vm_offset_t start;
vm_offset_t length;
vm_offset_t align;
int unused01;
};
typedef struct vm_map_freehint vm_map_freehint_t;
RB_HEAD(vm_map_rb_tree, vm_map_entry);
struct vm_map {
struct lock lock;
struct vm_map_rb_tree rb_root;
vm_offset_t min_addr;
vm_offset_t max_addr;
int nentries;
unsigned int timestamp;
vm_size_t size;
u_char system_map;
u_char freehint_newindex;
u_char unused02;
u_char unused03;
vm_flags_t flags;
vm_map_freehint_t freehint[VM_MAP_FFCOUNT];
struct pmap *pmap;
struct vm_map_ilock *ilock_base;
struct spinlock ilock_spin;
struct lwkt_token token;
vm_offset_t pgout_offset;
};
typedef struct vm_map *vm_map_t;
#define MAP_WIREFUTURE 0x0001
struct vmspace {
struct vm_map vm_map;
struct pmap vm_pmap;
int vm_flags;
caddr_t vm_shm;
#define vm_startcopy vm_rssize
segsz_t vm_rssize;
segsz_t vm_swrss;
segsz_t vm_tsize;
segsz_t vm_dsize;
segsz_t vm_ssize;
caddr_t vm_taddr;
caddr_t vm_daddr;
caddr_t vm_maxsaddr;
caddr_t vm_minsaddr;
#define vm_endcopy vm_unused01
int vm_unused01;
int vm_unused02;
int vm_pagesupply;
u_int vm_holdcnt;
u_int vm_refcnt;
};
#define VM_REF_DELETED 0x80000000U
#define VMSPACE_EXIT1 0x0001
#define VMSPACE_EXIT2 0x0002
#define VMSPACE_HOLDEXIT 0x80000000
struct vmresident {
struct vnode *vr_vnode;
TAILQ_ENTRY(vmresident) vr_link;
struct vmspace *vr_vmspace;
intptr_t vr_entry_addr;
struct sysentvec *vr_sysent;
int vr_id;
int vr_refs;
};
#ifdef _KERNEL
#define ASSERT_VM_MAP_LOCKED(map) KKASSERT(lockowned(&(map)->lock))
#ifdef DIAGNOSTIC
#ifdef MAP_LOCK_DIAGNOSTIC
#define vm_map_lock(map) \
do { \
kprintf ("locking map LK_EXCLUSIVE: 0x%x\n", map); \
if (lockmgr(&(map)->lock, LK_EXCLUSIVE) != 0) { \
panic("vm_map_lock: failed to get lock"); \
} \
(map)->timestamp++; \
} while(0)
#else
#define vm_map_lock(map) \
do { \
if (lockmgr(&(map)->lock, LK_EXCLUSIVE) != 0) { \
panic("vm_map_lock: failed to get lock"); \
} \
(map)->timestamp++; \
} while(0)
#endif
#else
#define vm_map_lock(map) \
do { \
lockmgr(&(map)->lock, LK_EXCLUSIVE); \
(map)->timestamp++; \
} while(0)
#endif
#if defined(MAP_LOCK_DIAGNOSTIC)
#define vm_map_unlock(map) \
do { \
kprintf ("locking map LK_RELEASE: 0x%x\n", map); \
lockmgr(&(map)->lock, LK_RELEASE); \
} while (0)
#define vm_map_lock_read(map) \
do { \
kprintf ("locking map LK_SHARED: 0x%x\n", map); \
lockmgr(&(map)->lock, LK_SHARED); \
} while (0)
#define vm_map_unlock_read(map) \
do { \
kprintf ("locking map LK_RELEASE: 0x%x\n", map); \
lockmgr(&(map)->lock, LK_RELEASE); \
} while (0)
#else
#define vm_map_unlock(map) \
lockmgr(&(map)->lock, LK_RELEASE)
#define vm_map_lock_read(map) \
lockmgr(&(map)->lock, LK_SHARED)
#define vm_map_unlock_read(map) \
lockmgr(&(map)->lock, LK_RELEASE)
#endif
#define vm_map_lock_read_try(map) \
lockmgr(&(map)->lock, LK_SHARED | LK_NOWAIT)
static __inline__ int
vm_map_lock_read_to(vm_map_t map)
{
int error;
#if defined(MAP_LOCK_DIAGNOSTIC)
kprintf ("locking map LK_SHARED: 0x%x\n", map);
#endif
error = lockmgr(&(map)->lock, LK_SHARED | LK_TIMELOCK);
return error;
}
static __inline__ int
vm_map_lock_upgrade(vm_map_t map) {
int error;
#if defined(MAP_LOCK_DIAGNOSTIC)
kprintf("locking map LK_EXCLUPGRADE: 0x%x\n", map);
#endif
error = lockmgr(&map->lock, LK_EXCLUPGRADE);
if (error == 0)
map->timestamp++;
return error;
}
#if defined(MAP_LOCK_DIAGNOSTIC)
#define vm_map_lock_downgrade(map) \
do { \
kprintf ("locking map LK_DOWNGRADE: 0x%x\n", map); \
lockmgr(&(map)->lock, LK_DOWNGRADE); \
} while (0)
#else
#define vm_map_lock_downgrade(map) \
lockmgr(&(map)->lock, LK_DOWNGRADE)
#endif
#endif
#define vm_map_min(map) ((map)->min_addr)
#define vm_map_max(map) ((map)->max_addr)
#define vm_map_pmap(map) ((map)->pmap)
static __inline struct pmap *
vmspace_pmap(struct vmspace *vmspace)
{
return &vmspace->vm_pmap;
}
static __inline long
vmspace_resident_count(struct vmspace *vmspace)
{
return pmap_resident_count(vmspace_pmap(vmspace));
}
#define MAX_KMAP 10
#define MAX_MAPENT (SMP_MAXCPU * 32 + 1024)
#define COWF_UNUSED_01 0x0001
#define COWF_COPY_ON_WRITE 0x0002
#define COWF_NOFAULT 0x0004
#define COWF_PREFAULT 0x0008
#define COWF_PREFAULT_PARTIAL 0x0010
#define COWF_DISABLE_SYNCER 0x0020
#define COWF_IS_STACK 0x0040
#define COWF_IS_KSTACK 0x0080
#define COWF_DISABLE_COREDUMP 0x0100
#define COWF_PREFAULT_MADVISE 0x0200
#define COWF_PREFAULT_RELOCK 0x0400
#define COWF_SHARED 0x0800
#define COWF_32BIT 0x1000
#define VM_FAULT_NORMAL 0x00
#define VM_FAULT_CHANGE_WIRING 0x01
#define VM_FAULT_USER_WIRE 0x02
#define VM_FAULT_BURST 0x04
#define VM_FAULT_DIRTY 0x08
#define VM_FAULT_UNSWAP 0x10
#define VM_FAULT_BURST_QUICK 0x20
#define VM_FAULT_WIRE_MASK (VM_FAULT_CHANGE_WIRING|VM_FAULT_USER_WIRE)
#define VM_FAULT_USERMODE 0x40
#ifdef _KERNEL
boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t,
vm_prot_t, boolean_t);
struct pmap;
struct globaldata;
void vm_map_entry_allocate_object(vm_map_entry_t);
void vm_map_entry_reserve_cpu_init(struct globaldata *gd);
int vm_map_entry_reserve(int);
int vm_map_entry_kreserve(int);
void vm_map_entry_release(int);
void vm_map_entry_krelease(int);
int vm_map_delete (vm_map_t, vm_offset_t, vm_offset_t, int *);
int vm_map_find (vm_map_t, void *, void *,
vm_ooffset_t, vm_offset_t *, vm_size_t,
vm_size_t, boolean_t,
vm_maptype_t, vm_subsys_t id,
vm_prot_t, vm_prot_t, int);
int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_size_t,
int, vm_offset_t *);
vm_offset_t vm_map_hint(struct proc *, vm_offset_t, vm_prot_t, int);
int vm_map_inherit (vm_map_t, vm_offset_t, vm_offset_t, vm_inherit_t);
void vm_map_init (struct vm_map *, vm_offset_t, vm_offset_t, pmap_t);
int vm_map_insert (vm_map_t, int *,
void *, void *,
vm_ooffset_t, void *,
vm_offset_t, vm_offset_t,
vm_maptype_t, vm_subsys_t id,
vm_prot_t, vm_prot_t, int);
int vm_map_lookup (vm_map_t *, vm_offset_t, vm_prot_t,
vm_map_entry_t *, struct vm_map_backing **,
vm_pindex_t *, vm_pindex_t *, vm_prot_t *, int *);
void vm_map_lookup_done (vm_map_t, vm_map_entry_t, int);
boolean_t vm_map_lookup_entry (vm_map_t, vm_offset_t, vm_map_entry_t *);
int vm_map_kernel_wiring (vm_map_t, vm_offset_t, vm_offset_t, int);
int vm_map_user_wiring (vm_map_t, vm_offset_t, vm_offset_t, boolean_t);
int vm_map_clean (vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t);
int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t);
void vm_map_startup (void);
int vm_map_submap (vm_map_t, vm_offset_t, vm_offset_t, vm_map_t);
int vm_map_madvise (vm_map_t, vm_offset_t, vm_offset_t, int, off_t);
void vm_map_simplify_entry (vm_map_t, vm_map_entry_t, int *);
void vm_init2 (void);
int vm_uiomove (vm_map_t, vm_object_t, off_t, int, vm_offset_t, int *);
int vm_map_stack (vm_map_t, vm_offset_t *, vm_size_t, int,
vm_prot_t, vm_prot_t, int);
int vm_map_growstack (vm_map_t map, vm_offset_t addr);
vm_offset_t vmspace_swap_count (struct vmspace *vmspace);
vm_offset_t vmspace_anonymous_count (struct vmspace *vmspace);
void vm_map_set_wired_quick(vm_map_t map, vm_offset_t addr, vm_size_t size, int *);
void vm_map_transition_wait(vm_map_t map, int relock);
void vm_map_interlock(vm_map_t map, struct vm_map_ilock *ilock,
vm_offset_t ran_beg, vm_offset_t ran_end);
void vm_map_deinterlock(vm_map_t map, struct vm_map_ilock *ilock);
#if defined(__x86_64__) && defined(_KERNEL_VIRTUAL)
int vkernel_module_memory_alloc(vm_offset_t *, size_t);
void vkernel_module_memory_free(vm_offset_t, size_t);
#endif
#endif
#endif