Can two process share same physical page? - operating-system

Can OS map same physical page to different processes page tables? Can processes share same physical page? If they share same page, can one process can corrupt other processes data and code?

Yes. Specifically with reference to Linux, when a thread (task) is created, it may share the same memory location with other thread (task).
The clone system call has a special flag CLONE_VM in Linux, and it specifically for sharing of memory (which is after all deep down a physical page).
If they share same page, can one process can corrupt other processes data and code?
It is the responsibility of the programmer to take care of this. One of the ways to handle this is using mutex.

Related

Why page faults are usually handled by the OS, not hardware?

I find that during TLB missing process, some architecture use hardware to handle it while some use the OS. But when it comes to page fault, most of them use the OS instead of hardware.
I tried to find the answer but didn't find any article explains why.
Could anyone help with this?
Thanks.
If the hardware could handle it on its own, it wouldn't need to fault.
The whole point is that the OS hasn't wired the page into the hardware page tables, e.g. because it's not actually in memory at all, or because the OS needs to catch an attempt to write so the OS can implement copy-on-write.
Page faults come in three categories:
valid (the process logically has the memory mapped, but the OS was lazy or playing tricks):
hard: the page needs to be paged in from disk, either from swap space or from a disk file (e.g. a memory mapped file, like a page of an executable or shared library). Usually the OS will schedule another task while waiting for I/O.
soft: no disk access required, just for example allocating + zeroing a new physical page to back a virtual page that user-space just tried to write. Or copy-on-write of a writeable page that multiple processes had mapped, but where changes by one shouldn't be visible to the other (like mmap(MAP_PRIVATE)). This turns a shared page into a private dirty page.
invalid: There wasn't even a logical mapping for that page. A POSIX OS like Linux will deliver SIGSEGV signal to the offending process/thread.
The hardware doesn't know which is which, all it knows was that a page walk didn't find a valid page-table entry for that virtual address, so it's time to let the OS decide what to do next. (i.e. raise a page-fault exception which runs the OS's page-fault handler.) valid/invalid are purely software/OS concepts.
These example reasons are not an exhaustive list. e.g. an OS might remove the hardware mapping for a page without actually paging it out, just to see if the process touches it again soon. (In which case it's just a cheap soft page fault. But if not, then it might actually page it out to disk. Or drop it if it's clean.)
For HW to be able to fully handle a page fault, we'd need data structures with a hardware-specified layout that somehow lets hardware know what to do in some possible situations. Unless you build a whole kernel into the CPU microcode, it's not possible to have it handle every page fault, especially not invalid ones which require reading the OS's process / task-management data structures and delivering a signal to user-space. Either to a signal handler if there is one, or killing the process.
And especially not hard page faults, where a multi-tasking OS will let some other process run while waiting for the disk to DMA the page(s) into memory, before wiring up the page tables for this process and letting it retry the faulting load or store instruction.

Can OS processes share a single CPU stack?

Can processes share a single stack?
I'm currently thinking yes and no. That they "share" stack but it need to copy and save the information already there elsewere before using it and return it when the first process is getting picked up by the CPU again. But I might be confusing this with registers in general.
Can someone help me shed some light on this?
Processes do not share CPU stacks.
While processes can potentially share memory using shared-memory facilities, processes do not share memory by default. Operating systems try to minimize the amount of sharing between processes as a way to ensure security.
Sharing CPU stack between processes A and B would be detrimental to security, because process A would be able to poke around "junk" left on the stack by process B, and vice versa. Hackers managed to exploit an indirect sharing on a much smaller scale to create a major security vulnerability (you can read more about Meltdown and Spectre here). Sharing CPU stacks would create a much bigger problem.
It goes without saying that an attempt to share stacks would require a degree of inter-process synchronization that would be prohibitive to overall performance. An ability to make independent operations on CPU stack is so critical to concurrency that threads inside the same process are allocated separate stacks, even though they already share all the memory allocated to the process, so security is not a concern. Sharing stacks would effectively kill concurrency, because maintaining a shared stack would require frequent exclusive access with lots of synchronization.
Some systems use an interrupt stack shared by all processes. Generally, there is one interrupt stack per processor.
User stacks (and there is usually one for each processor mode used by the system) are unique to each process (or thread).
The difference between the registers and the stack is that the latter can be anywhere in memory (it is indirectly referenced by appropriate registers) while the formers are fixed (there is only one set of architecturally visible registers).
The stack is part of the state of a program, just like it make no sense to mix program instruction, data and context together, mixing two stacks make no sense.
If program A pushes X it expects to pop X and not an eventual value pushed by program B meanwhile.
It's possible to make all program shares the same memory area for the stack but this is, in general, counterproductive.
As you correctly noted, the stack must be swapped in an out, thus, in the case of two program A and B, two additional memory areas are needed: one for saving the stack of A and one for the stack of B.
In the end, three memory areas are used instead of two.
There are cases where the swapping is necessary: when the shared is at a fixed location.
This is the case, in some degenerate form, of registers but other structure can have a fixed location.
One simple example are the page table entries, if a program A is used to generate two processes A1 and A2, most OSs will copy-on-write them.
Under this circumstances, the two processes end up sharing a lot of pages, even all but a few. For the OS may be easier to swap in and out the few different pages rather than make the page table (or part of it) point to two different locations.
In general, if we cannot afford to have multiple instances of a resource, we need to time-share it.
Since we can afford to have more than one instance of the stack, we prefer to not share it.

If using Pure Demand Paging, how does CPU know where the first instruction is in the executable?

I am reading Chap9 of Operating System Concepts and the concept of pure demand paging is described as follows:
In the extreme case, we can start executing a process with no pages in
memory. When the operating system sets the instruction pointer to the first instruction of the process, which is on a non-memory-resident page, the process
immediately faults for the page....
But if NONE of the pages, particularly the pages containing code, are in memory, how does the OS know where the program counter is in the first place? Is program counter set as part of process creation by inspecting the program image on disk? If so, I would assume the OS knows the format of the binary image and can directly access that info on disk. And it will only make sense if somehow this info is stored in the part of the program image not needed during program execution, if OS decides not to bring the page containing this info into memory.
To summarize, I would like to know:
How is program counter set for a new process if using pure demand paging?
Is any real OS using pure demand paging and what benefit does it have?
How does an executable's binary format (e.g. ELF, PE formats) help the OS do demand paging (OS needs to know where the first page is at least?)

How exactly does the MMU load a program from secondary memory to primary memory

What exactly happens when I open an application or a program which is not cached in the main memory.
a) How does the OS know where to look for the program?
b) If suppose all the pages cannot be loaded then does the address of the rest of the pages or at least starting address of the rest of the pages is maintained in the PCB?
c) Also is any information regarding the application is present in main memory, assuming it is never accessed before and it is not a critical component that has to be present in memory.
Any answers, follow-up questions, clarifications are welcome.
Edit: I have went through many links online but none states exactly what happens or who maintains the information. Most of the places it is stated that the program would be brought in the main memory by the page fault handler, I am looking for something more specific.
Read about page tables and page faults. That's the mechanism behind it. If you want something very specific, download x86 CPU manuals from intel or AMD and read the chapters about the same.

Difference between shared memory IPC mechanism and API/system-call invocation

I am studying about operating systems(Silberscatz, Galvin et al). My programming experiences are limited to occasional coding of exercise problems given in a programing text or an algorithm text. In other words I do not have a proper application programming or system programming experience. I think my below question is a result of a lack of experience of the above and hence a lack of context.
I am specifically studying IPC mechanisms. While reading about shared memory(SM) I couldn't imagine a real life scenario where processes communicate using SM. An inspection of processes attached to the same SM segment on my linux(ubuntu) machine(using 'ipcs' in a small shell script) is uploaded here
Most of the sharing by applications seem to be with the X deamon. From what I know , X is the process responsible for giving me my GUI. I infered that these applications(mostly applets which stay on my taskbar) share data with X about what needs to change in their appearances and displayed values. Is this a reasonable inference??
If so,
my question is, what is the difference between my applications communicating with 'X' via shared memory segments versus my applications invoking certain API's provided by 'X' and communicate to 'X' about the need to refresh their appearances?? BY difference I mean, why isn't the later approach used?
Isn't that how user processes and the kernel communicate? Application invokes a system call when it wants to, say read a file, communicating the name of the file and other related info via arguments of the system call?
Also could you provide me with examples of routinely used applications which make use of shared memory and message-passing for communication?
EDIT
I have made the question more clearer. I have formatted the edited part to be bold
First, since the X server is just another user space process, it cannot use the operating system's system call mechanism. Even when the communication is done through an API, if it is between user space processes, there will be some inter-process-communication (IPC) mechanism behind that API. Which might be shared memory, sockets, or others.
Typically shared memory is used when a lot of data is involved. Maybe there is a lot of data that multiple processes need to access, and it would be a waste of memory for each process to have its own copy. Or a lot of data needs to be communicated between processes, which would be slower if it were to be streamed, a byte at a time, through another IPC mechanism.
For graphics, it is not uncommon for a program to keep a buffer containing a pixel map of an image, a window, or even the whole screen that then needs to be regularly copied to the screen. Sometimes at a very high rate...30 times a second or more. I suspect this is why X uses shared memory when possible.
The difference is that with an API you as a developer might not have access to what is happening inside these functions, so memory would not necessarily be shared.
Shared Memory is mostly a specific region of memory to which both apps can write and read from. This off course requires that access to that memory is synchronized so things don't get corrupted.
Using somebody's API does not mean you are sharing memory with them, that process will just do what you asked and perhaps return the result of that operation to you, however that doesn't necessarily go via shared memory. Although it could, it depends, as always.
The preference for one over another I'd say depends on the specifications of the particular application and what it is doing and what it needs to share. I can imagine that a big dataset of some kind or another would be shared by shared memory, but passing a file name to another app might only need an API call. However largely dependent on requirements I'd say.