Lecture 15: Virtualization (cont.)
Mar ch 5th 2012
Alexander Chang
Page Faults:
When running into a page-fault we must use the page map (as covered last time) to map the virtual address to a real address in order to recover the meaningful data.
Each process gets its own page table in order to maintain isolation from other processes; however, threads in a process only get one page table.
When a page fault occurs a victim page from the RAM cache is picked and then we replace it with the one that we need, marking the old page with FAULT.
Mechanism
Code:
// assume we have a pointer to a function pmap that we can pass
// pmap(virtual address)
// maps a virtual address to a real address
// Each process has it's own pmap code which is why we pass it along as a function
// pointer so that we can change it how we want
// va = virtual address
// valim = virtual address limit
p->swapmap(va) {
return (va > p->valim ? FAULT : p->diskorigin + va);
}
// va = virtual address
// p = process
// ova = old virtual address
// op = old process
pfault(va, p, ova, op) {
if (p->swapmap(va) == FAULT)
kill(p);
else {
(op, ova) = removal_policy(); // removes the old process and virtual
pa = op->pmap(ova); // address via some removal policy
// reassign old pagemap to new process
// psuedo code
// write pa block to disk @ op->swapmap(ova);
// op->pmap(ova) = FAULT;
// read pa block to disk @ p->swapmap(va);
// p->pmap(va) = pa;
}
}
Policy
Removal Policy:
Q:
Which page to choose as a victim?
A0:
Pick a victim at random
(works if memory accesses truly are
random)
But: LOCALITY OF REFERENCE common
A1:
FIFO – change page that's been in RAM the longest
*Note:
Traces from real systems to test: list of va accesses from a real program → sequence of accessed virtual page numbers. Apply algorithm to traces.
Traces
Problem: How to take track?
Approximately: Invalidate PT on clock interrupt.
If the page is there, then good. If not, then just choose one that
is
still marked FAULT.
Improving Performance:
A:
Demand Paging
On Startup: read just
main page & then execute
+ idea: start faster (put up a splash
screen)
– more page fault code executed
– more
disk arm movement in a multi-process ap
B:
Don't write a victim page to disk if it's never been written to →
dirty bit – often in hardware, if not mark page as invalid →
kernel traps → records dirty bit
Mark each page without
write access even if they have write access. Once
the program
wants to execute a write, then the program will trap and
see
that the program actually does
have write access and flips the dirty
bit and the write access
bit.
To prevent
buffer overflows we can simply make it so that everything in
the
stack has read/write access but no execution access.
fork()
Copies all of process's virtual memory.
How to speed up?
1)
don't need to copy read only areas.
2) don't need to copy writable
pages either! → copy on write – on trap, re-allows write
permissions and copies page later
1) Simply have the page table of the child process point to the same page as the parent process without write permissions.
2) Similar to 1. Have the page table of the child process point to the same page as the parent process, however, remove write permissions from both. This will continue to work fine until one of the processes want to write, then the kernel will trap and find out that the process actually does have write permissions and will then copy a new page and change the page table to reflect the change. Then both pages will then have write permissions enabled again.
vfork
Parent
+ Child share memory (and therefore PTEs)
parent is frozen until
child exits
or execs
p = vfork();
if (!p) {
// fiddle a bit -- should not write to globally visible RAM
exec(--);
exit(--);
}
Networking:
Distributed
Systems & RPC (Remote Procedure Call)
transfer(10,
a b); // body of function runs on some other
// machine
RPCs
differ from ordinary function calls & syscalls
– slower
yet (speed of light problems)
+ have hard modularity (not sharing
address space)
– no call by reference (always call by
value)
±
don't need to agree on their own architecture (SPARC – big
endian vs. Intel – little endian)
(requires data format to
be known)
Caller:
Marshalling:
must marshal the data.
Re-arranges the data into a agreed upon
format.
Callee:
Must
unmarshal the data.
Re-arranges the marshalled data into a data
that the callee can process and send back.
Aside:
ROP (Return Oriented
Program) – Buffer overflow attack
Assuming that application
has a buffer overflow vulnerability that allows us to write whatever
we want on the stack. Even if we don't have execution permissions we
can still execute whatever code we want if target program is large
enough and we can analyze the main program.
Idea: Use small
snippets of code to do what we want
By editing the return
addresses we can continually jump to and from the main application
and use small executable instructions which edit the registers in
order to execute what we want in small snippets at a time.