Hi,
I realized that the best place to modify sigma0's capabilities are when it is
created. I see that this happens in
kernel/fiasco/src/kern/kernel_thread-std.cpp in the init_workload() function. I
do not exactly understand how sigma0 gathers all the capabilities - the code is
a little hard to parse for me. Could someone explain this to me? Is there a way
to pass only limited capabilities to sigma0 -aka, allow the default and then
prune the resource tree?
For now, my sigma0 output report that it has the following:
SIGMA0: Dump of all resource maps
RAM:
[0:10b000;13]
[4:14;18cfff]
[0:18d000;2ecfff]
[4:2ed000;2edfff]
[0:2ee000;3f]
[0:45b000;119cfff]
[4:119d000;1360fff]
[0:1361000;25b98fff]
IOMEM:--
[0:0;f]
[0:2900;fedf]
[0:fee01000;]
IO PORTS--
[0:0;fff]
is there a way for me for example to limit RAM and IOMEM access to other
spaces?
Thanks,
ramya
From: Masti Ramya Jayaram
Sent: 11 September 2014 15:51
To: Adam Lackorzynski; l4-hackers@os.inf.tu-dresden.de
Subject: RE: Physical memory allocation to L4linux
Hey guys,
I see that the IO request reaches the io_map function in
kernel/fiasco/src/kern/ia32/map_util-io.cpp:
L4_error
io_map(Space *from, L4_fpage const fp_from,
Space *to, L4_fpage const fp_to, Mword control)
{
typedef Map_traitsIo_space Mt;
Mt::Addr rcv_pos = Mt::get_addr(fp_to);
Mt::Addr snd_pos = Mt::get_addr(fp_from);
Mt::Size rcv_size = Mt::Size::from_shift(fp_to.order());
Mt::Size snd_size = Mt::Size::from_shift(fp_from.order());
snd_pos = snd_pos.trunc(snd_size);
rcv_pos = rcv_pos.trunc(rcv_size);
Mt::constraint(snd_pos, snd_size, rcv_pos, rcv_size, Mt::Addr(0));
...
}
However, when I do a return L4_error:Map_failed from the beginning of this
function to deny all IO requests, it does not propagate back to sigma0. Could
someone explain how exactly this communication/IPC between the kernel and sigma
works?
Thanks,
Ramya
From: Masti Ramya Jayaram
Sent: 10 September 2014 16:07
To: Adam Lackorzynski; l4-hackers@os.inf.tu-dresden.de
Subject: RE: Physical memory allocation to L4linux
Update: Sorry, I misunderstood a few things in the previous email. The change
was in fiasco and not sigma and therefore, in theory, no user space process
should have access to the protected region. This also implies that sigma0 will
not have access if I understand correctly which is rather nice.
So, I tried changing the handle_sigma0_page_fault function. This is located in
kernel/fiasco/src/kern/ia32/thread-ia32.cpp to prevent mapping of some range of
physical memory (NOT RAM) as follows:
IMPLEMENT inline
bool
Thread::handle_sigma0_page_fault(Address pfa)
{
size_t size;
// Check if mapping a superpage doesn't exceed the size of physical memory
if (Cpu::have_superpages()
// Some distributions do not allow to mmap below a certain threshold
// (like 64k on Ubuntu 8.04) so we cannot map a superpage at 0 if
// we're Fiasco-UX
(!Config::Is_ux || !(pfa Config::SUPERPAGE_SIZE)))
{
pfa = Config::SUPERPAGE_MASK;
size = Config::SUPERPAGE_SIZE;
}
else
{
pfa = Config::PAGE_MASK;
size = Config::PAGE_SIZE;
}
--
- My change start
if((pfa=0xe000) (pfa=0xefff)){
printf(\nNot allowed...denying\n);
return Mem_space::Insert_err_nomem;
}
--
- My change end
return mem_space()-v_insert(Mem_space::Phys_addr(pfa), Mem_space::Addr(pfa),
Mem_space::Size(size),
Mem_space::Page_writable
| Mem_space::Page_user_accessible)
!= Mem_space::Insert_err_nomem;
}
However, I realized that when I try to map this address space using
l4io_request_iomem, I see that it goes through and the call never reaches until
fiasco's sigma0_page_fault handler. A little more debugging revealed that it
goes as far as the following function in l4/pkg/sigma0/server/src/memmap.cc:
static
void map_mem(l4_fpage_t fp, Memory_type fn, l4_umword_t t, Answer *an)
{
an-clear();
Mem_man *m;
switch (fn)
{
case Ram:
m = Mem_man::ram();
break;
case Io_mem:
case Io_mem_cached:
m = iomem;
break;
default:
return;
}
unsigned long addr = m-alloc(Region::bs(fp.raw ~((1UL 12) - 1),
1UL l4_fpage_size(fp), t));
if (addr == ~0UL)
return;
/* the Fiasco kernel makes the page non-cachable if the frame
* address is greater than mem_high */
an-snd_base(addr);