]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/map_util-objs.cpp
update
[l4.git] / kernel / fiasco / src / kern / map_util-objs.cpp
1 INTERFACE:
2
3 #include "kobject_mapdb.h"
4
5
6 IMPLEMENTATION:
7
8 #include "assert.h"
9 #include "obj_space.h"
10 #include "l4_types.h"
11 #include "mappable.h"
12
13 inline
14 void
15 save_access_attribs (Kobject_mapdb* /*mapdb*/,
16     const Kobject_mapdb::Frame& /*mapdb_frame*/,
17     Kobject_mapdb::Mapping* /*mapping*/, Obj_space* /*space*/,
18     unsigned /*page_rights*/,
19     Obj_space::Addr /*virt*/, Obj_space::Phys_addr /*phys*/, Obj_space::Size /*size*/,
20     bool /*me_too*/)
21 {}
22
23 L4_error
24 obj_map(Space *from, L4_fpage const &fp_from,
25         Space *to, L4_fpage const &fp_to, L4_msg_item control,
26         Kobject ***reap_list)
27 {
28   typedef Map_traits<Obj_space> Mt;
29   Mt::Addr rcv_addr = Mt::get_addr(fp_to);
30   Mt::Addr snd_addr = Mt::get_addr(fp_from);
31   Mt::Size snd_size = Mt::Size::from_shift(fp_from.order());
32   Mt::Size rcv_size = Mt::Size::from_shift(fp_to.order());
33   Mt::Addr offs(control.index());
34
35   snd_addr = snd_addr.trunc(snd_size);
36   rcv_addr = rcv_addr.trunc(rcv_size);
37
38   Mt::constraint(snd_addr, snd_size, rcv_addr, rcv_size, offs);
39
40   if (snd_size == 0)
41     {
42       if (Config::conservative)
43         kdb_ke("fpage transfer = nop");
44       return L4_error::None;
45     }
46
47   unsigned long del_attribs, add_attribs;
48   Mt::attribs(control, fp_from, &del_attribs, &add_attribs);
49
50   return map((Kobject_mapdb*)0,
51               from->obj_space(), from, snd_addr,
52               snd_size,
53               to->obj_space(), to, rcv_addr,
54               control.is_grant(), add_attribs, del_attribs,
55               reap_list);
56 }
57
58 unsigned
59 obj_fpage_unmap(Space * space, L4_fpage fp, L4_map_mask mask,
60                 Kobject ***reap_list)
61 {
62   typedef Map_traits<Obj_space> Mt;
63   Mt::Size size = Mt::Size::from_shift(fp.order());
64   Mt::Addr addr = Mt::get_addr(fp);
65   addr = addr.trunc(size);
66
67   // XXX prevent unmaps when a task has no caps enabled
68
69   return unmap((Kobject_mapdb*)0, space->obj_space(), space,
70                addr, size,
71                fp.rights(), mask, reap_list);
72 }
73
74
75 L4_error
76 obj_map(Space *from, unsigned long snd_addr, unsigned long snd_size,
77         Space *to, unsigned long rcv_addr,
78         Kobject ***reap_list, bool grant = false,
79         unsigned attrib_add = 0, unsigned attrib_del = 0)
80 {
81   typedef Map_traits<Obj_space> Mt;
82
83   return map((Kobject_mapdb*)0,
84              from->obj_space(), from, Mt::Addr(snd_addr),
85              Mt::Size(snd_size),
86              to->obj_space(), to, Mt::Addr(rcv_addr),
87              grant, attrib_add, attrib_del, reap_list);
88 }
89
90 bool
91 map(Kobject_iface *o, Obj_space* to, Space *to_id, Address _rcv_addr,
92     Kobject ***reap_list, unsigned attribs = L4_fpage::CRWSD)
93 {
94   typedef Obj_space SPACE;
95   typedef Obj_space::Addr Addr;
96   typedef Obj_space::Size Size;
97
98   Page_number const rcv_addr = Page_number::create(_rcv_addr);
99
100   if (EXPECT_FALSE(rcv_addr >= to->map_max_address()))
101     return 0;
102
103   // Receiver lookup.
104   Obj_space::Phys_addr r_phys;
105   Size r_size;
106   unsigned r_attribs;
107
108   Addr ra(rcv_addr);
109   if (to->v_lookup(ra, &r_phys, &r_size, &r_attribs))
110     unmap((Kobject_mapdb*)0, to, to_id, ra, r_size,
111           L4_fpage::RWX, L4_map_mask::full(), reap_list);
112
113   attribs &= L4_fpage::WX;
114   // Do the actual insertion.
115   Obj_space::Status status
116     = to->v_insert(o, ra, Size::create(1), attribs);
117
118   switch (status)
119     {
120     case SPACE::Insert_warn_exists:
121     case SPACE::Insert_warn_attrib_upgrade:
122     case SPACE::Insert_ok:
123
124       if (status == SPACE::Insert_ok)
125         {
126           if (! o->map_root()->insert(0, to_id, ra))
127             {
128               to->v_delete(rcv_addr, Obj_space::Size::create(1));
129               return 0;
130             }
131         }
132       break;
133
134     case SPACE::Insert_err_nomem:
135       return 0;
136       break;
137
138     case SPACE::Insert_err_exists:
139       if (Config::conservative)
140         kdb_ke("existing mapping");
141       // Do not flag an error here -- because according to L4
142       // semantics, it isn't.
143     }
144
145   return 1;
146 }