rdos wrote:Ethin wrote:I mean, that's why you use 64-bit on modern machines and you avoid 32-bit -- its no longer practical or workable without a bunch of hacks. With identity paging you don't have to map the entirety of RAM into the virtual address space; you can easily start with only your kernel mapped and then map what you need when you need it and unmap things when you don't. Its what I did in my Rust kernel and it works quite well.
I pretty much disagree. Using 64-bit makes people reckless and so they map everything to kernel space (maybe even to user space if they do it wrong) just because they can. The flat memory model is in a similar vain: You sacrifice the superior protection of segmentation and let everything be accessible.
Also, if you map physical memory it will be in the virtual address space. If it wasn't, why would you map it? All it takes is a malformed pointer and you can write to some other process or steal information that should be protected within the address space of the process. Any way you look at this, mapping all of physical memory makes it possible to access all virtual address spaces regardless if you are executing code in them or not. This basically takes away all the protection of paging.
Besides, I wouldn't call the algorithms used for file caches and disc device drivers for hacks. They are smart algorithms that avoid exposing file system data to the accessible virtual address space and that additionally work better since typical drivers need physical addresses and not virtual.
Its interesting that you still maintain that segmentation is superior. Clearly it isn't or we'd still be using it today.
First: paging in no way requires that a developer be reckless. Implemented correctly, paging can provide the same security features that segmentation provided, minus all its disadvantages. If when implementing paging you choose to be reckless, that's not the fault of 64-bit paging, that's your fault. Blaming the computer for your own stupidity is... Well, stupidity at its finest.
Second: mapping all of physical memory into a virtual address space doesn't mean that processes can access that physical memory. If you have a process in another address space and you don't map all of physical memory in that processes address space, the only way that process is going to be able to access your physical memory mappings is by taking advantage of software/hardware vulnerabilities like meltdown/spectre, and if a process is doing that segmentation isn't going to protect you either -- the whole point of meltdown in particular is to melt those barriers that separate processes, regardless of what method (segmentation or paging) your using. If that happens, your screwed anyway.
Third: paging doesn't allow processes to access one anothers memory without it being mapped first. That's literally the whole point: to make a process think that its the only thing that the computer is doing. If process 1 and 2 are in separate virtual address spaces, they can only access the addresses mapped in those address spaces. If I don't map any of process 2's memory into process 1's address space, process 1 can't access process 2's memory at all -- that'll either cause a page fault or process 1 will read its own memory. If process 1 and 2 are kernel-mode processes (and therefore can change the page tables at will), then the risk is higher -- either process can screw around and break things or read arbitrary memory, but that risk occurs with segmentation too: if a process can muck about with the segment registers, your screwed. Paging also has the advantage of being able to share memory without having to duplicate it. If I want to send data to process 2 from process 1, all I have to do is map the page containing the data I'd like to share into process 2's address space. The underlying physical address doesn't need to change, and I don't have to copy anything around. If I want both processes to be able to access the same memory, all I have to do is map it twice. Again, the underlying address in memory doesn't have to change. Or I could map the memory into process 2's address space and unmap it in process 1's. You can't do that with segmentation.
Of course, the other problem with segmentation is swapping to disk -- you can't swap part of a segment to disk and swap it back, you have to swap the entire segment to disk and reload it (which can cause memory fragmentation). With paging I can swap single pages to disk and back and don't have to do something ridiculous like, I dunno, swapping the entire virtual address space to disk and back. Like I said: if segmentation were truly superior to paging, we'd still be using it. Clearly, smarter heads believed that paging was a better and more secure option than segmentation. Paging certainly isn't perfect -- processor vulnerabilities can break its security guarantees -- but the same holds for segmentation, and I'm pretty sure that an OS solely using segmentation isn't immune to spectre or meltdown.