summaryrefslogtreecommitdiff
path: root/viengoos/vm.h
blob: b04c7d08fa1e0665dc8e8381f86e93cff8996f78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* vm.h - Virtual memory management interface.
   Copyright (C) 2009 Free Software Foundation, Inc.
   Written by Neal H. Walfield <neal@gnu.org>.

   This file is part of the GNU Hurd.

   The GNU Hurd 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 3 of the
   License, or (at your option) any later version.

   The GNU Hurd 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 VIENGOOS_VM_H
#define VIENGOOS_VM_H

#include <stdint.h>
#include <hurd/btree.h>
#include "list.h"

#include "sys.h"

enum
  {
    MEM_READABLE = 1 << 0,
    MEM_WRITABLE = 1 << 1,
    MEM_EXECUTABLE = 1 << 2,

    MEM_RW = MEM_READABLE | MEM_WRITABLE,
    MEM_RX = MEM_READABLE | MEM_EXECUTABLE,
    MEM_RWX = MEM_RW | MEM_EXECUTABLE,
  };

/* The data structure used to record mappings of objects in the
   hardware virtual address space.  */
struct vm_mapping
{
  /* The descriptor of the object that this mapping maps.  */
  struct object_desc *desc;
  /* Other mappings of this object (rooted in the object desc).  */
  struct list_node vm_object_mapping_node;

  /* The thread this maps for.  */
  struct thread *thread;
  /* The other objects mapped by this thread (rooted at the thread),
     keyed and sorted by ADDRESS.  */
  hurd_btree_node_t vm_thread_mapping_node;

  /* The address at which the mapping is established.  */
  uintptr_t address;
  /* The access for which this mapping is allowed.  */
  int access;

#ifdef MAPPING_SYSDEP_MEMBERS
  MAPPING_SYSDEP_MEMBERS
#endif
};

/* Compare two addresses.  Sort of.  If the least significant bit of
   *a is set, then a is actually two address, a start and an end.
   This allows for searching for any mapping in an area.  This relies
   on the fact that the btree implementation always passes the
   user-supplied key as the first arguement to the compare function,
   which it does.  */
static inline int
vm_mapping_node_compare (const uintptr_t *a, const uintptr_t *b)
{
  assert ((*b & 0x1) == 0);

  uintptr_t start, end;
  if ((*a & 0x1))
    {
      start = a[0] & ~0x1;
      end = a[1];
    }
  else
    {
      start = a[0];
      end = start;
    }

  if (end < *b)
    return -1;
  else if (*b < start)
    return 1;
  else
    return 0;
}

BTREE_CLASS(vm_thread_mappings, struct vm_mapping, uintptr_t, address,
	    vm_thread_mapping_node, vm_mapping_node_compare, false)

LIST_CLASS(vm_object_mappings, struct vm_mapping, vm_object_mapping_node, true)

/* Initialize the virtual memory subsystem.  */
extern void vm_init (void);

/* Map the object OBJECT into thread THREAD's VM address space at ADDR
   with the access rights described by ACCESS.  */
extern void vm_thread_map (struct thread *thread, struct object_desc *desc,
			   uintptr_t addr, uintptr_t access);

/* Remove the access rights ACCESS from all objects in thread's VM
   starting at address START and ending at END.  */
extern void vm_thread_revoke (struct thread *thread,
			      uintptr_t start, uintptr_t end,
			      uintptr_t access);

/* Destroy the hardware address space associated with the thread
   THREAD.  */
extern void vm_as_destroy (struct thread *thread);

/* Revoke the access specified in ACCESS to the object designed by
   DESC (i.e., any extant mappings with the access described in ACCESS
   are downgraded and potentially destroyed if they no longer grant
   any access).  If ACCESS is 0 or the ACCESS causes an object to be
   unmapped, updates the access bits (DESC->REFERENCED, DESC->DIRTY,
   DESC->USER_REFERENCED and DESC->USER_DIRTY) appropriately.  */
extern void vm_object_revoke (struct object_desc *desc, uintptr_t access);

/* Install thread THREAD's address space, i.e., make it the active
   address space.  */
extern void vm_as_install (struct thread *thread);

extern void vm_dump (struct thread *thread,
		     uintptr_t start, uintptr_t end);

#endif