Home   News   Concept   AMIGA-Compatible   Hardware   Forum   Questions+Answers   Pictures   Contact & Team

Welcome to the Natami / Amiga Forum

This forum is for AMIGA fans interested in the new NATAMI platform.
Please read the forum usage manual.



All TopicsNewsQAFeaturesTalkTEAMLogin to post    Create account
Welcome to the Natami lounge.
Meet new AMIGA friends here and enjoy having a friendly chit chat.

(Non-68K) Supervisor Entry Models?page  1 2 
Børge Nøst
Norway

Posts 53
27 Apr 2012 16:39


I have been googling around, but I have trouble finding something that matches what I'm thinking of:

Does anyone have some good links for different models for going from user to supervisor mode (or generally from a lower to a higher rights level)?

I am thinking of something like a bit in the mmu tables saying that code in that page has the right to change the privilege mode. That would probably need some kind of "COMEFROM"/"PREAMBLE" instruction that marks the start of a function so other code can't just jump into the code stream and hijack the escalate.
Or are there other architectures that have cheap escalation models instead of the typical interrupt like type?

Deep Sub Micron
Germany
(MX-Board Owner)
Posts 566
27 Apr 2012 21:06


Isn't the code that has the right to change the privilege mode already privileged in some way?

I only know the interrupt/exception type of changing to more privileged mode. That has the advantage that the unprivileged code can not control the following instruction address.

So if you like to try something different with MMU support then how about the other way around and mark a memory page as supervisor jump table. That table must be only writable in supervisor mode. A branch or jump with help of this table set a more privileged supervisor mode. In that way you have as many supervisor entries as entries in the table, not limited by number of interrupts. I don't know if that makes much sense or if it already exists, just picking up your idea and turn it around a little.

I could also think of two programs and neither one is a supervisor, but they protect their interfaces with that kind of tables and can call each other without bothering the operating system.

Anyway, it might be similar to what you can do for synchronization mechanisms like semaphores, monitors, ... If you have one then you can use this to implement all the others. So to use a different type, it is possible without having special hardware.

So the question arise: What does your OS really need? Can you improve the operating system by choosing different kind of escalation models?


Børge Nøst
Norway

Posts 53
28 Apr 2012 19:14


deep sub micron wrote:
  So the question arise: What does your OS really need? Can you improve the operating system by choosing different kind of escalation models?

Good question. What I really had in mind was a way to combine several levels of rights (think microkernals and driver support) with fast ways of switching to a more privileged level. In an Exec similar style.
You could mix library calls that need to be "protected" with others that simply is there for the sharing and coding ease if the JUMP instruction read the mmu table and set an internal rights bit - while all other instructions clear it - and a COMEFROM instruction actually escalate if that internal bit is set. (If you don't start with a COMEFROM your window of opportunity to raise level is gone.)


Marcel Verdaasdonk
Netherlands

Posts 3974
28 Apr 2012 22:41


it might be me but it looks like a chicken and the egg.
To check if it is a legal access to privileged space you need privileged access to that space.

IMHO it is better to make a strict split between public and private code space and let a handler do the access to this space this would mean some overhead in your code.

Thomas Richter
Germany
(MX-Board Owner)
Posts 1425
29 Apr 2012 12:29


Børge Nøst wrote:

  Does anyone have some good links for different models for going from user to supervisor mode (or generally from a lower to a higher rights level)?

There is for one thing the way how exec it does (aka "the wrong way"): Exec simply has the Supervisor() call which allows everyone to do that. What exec does is that it runs into a priviledged instruction (namely, setting the supervisor bit in the status register - what an irony!). Clearly, the 68K then traps. However, the exec supervisor priviledge trap handler checks whether the PC is the PC of the supervisor call itself, and then turns on the supervisor bit itself, jumping to the target PC in register a5.

And there is the right way, namely using specialized instructions for that, namely software interrupts. Basically, what *should* have happened is that Os calls are not simply library jumps, but line-A traps (as in MacOs classic); these instructions increase the priviledge level by themselves, and the Os trap handler has then to dispatch to the corresponding Os call, potentially lowering the access level again to that what the Os routine needs. Since process creation is such an Os call, a proper Os policy manager can increase the access level of a new thread - basically by lowering the supervisor access level on its entry point.

So basically, you use the hardware interrupts to higher the level, while the Os itself (the software) can only lower the access rights by dropping rights.

This is for example also how Linux and Unix works.

Børge Nøst wrote:

  I am thinking of something like a bit in the mmu tables saying that code in that page has the right to change the privilege mode.

This is really not related to the MMU - it is mainly a Os design problem. A process is assigned a set of access rights upon its creation; whenever the process calls the Os through the interrupt handlers, the Os can check agains the access rights of the process (as it has all rights at this point), and then, before proceeding with the actual work, lower the access rights for the specific task to be performed to the absolute minimum required.

For example, if I want to write to disk, I need to access the disk controller at some point. The process does not have such rights, the hardware handler does. The Os call first grants all rights by going into the supervisor level, the Os then lowers the access rights again, probably maps in the pages for the disk controller, then directs control to the disk driver which *does* have the rights to access the hardware interface. So the MMU only checks for rightful accesses, but it does not control the policies. This is part of a Os policy manager.

That said, Linux and is monolithic kernel are not a good example of proper Os design either.

Børge Nøst wrote:

  Or are there other architectures that have cheap escalation models instead of the typical interrupt like type?

What is the problem with the interrupt call? It's the right way to do it.


Børge Nøst
Norway

Posts 53
29 Apr 2012 16:27


Thomas Richter wrote:
  What is the problem with the interrupt call? It's the right way to do it.

  I know. I had the Operating Systems course too.
 
  (Syncronous)Interrupts (i.e. traps) are however often expensive. I was therefore wondering if there are other models/architectures that have fast(er) primitives for doing OS calls?
  (And related to that the Linux crowd will forever hate on Tanenbaum because the microkernel design is "too slow". Any Amiga-like/nextgen type OS would IMO be more microkernel like and I'm toying with ideas how to lower the 'cost'.)
 

Marcel Verdaasdonk
Netherlands

Posts 3974
29 Apr 2012 18:11


remove any unneeded abstraction whenever possible this is where micro-kernel grind to a halt.

Megol .

Posts 672
29 Apr 2012 21:07


Børge Nøst wrote:

Thomas Richter wrote:
  What is the problem with the interrupt call? It's the right way to do it.

  I know. I had the Operating Systems course too.
 
  (Syncronous)Interrupts (i.e. traps) are however often expensive. I was therefore wondering if there are other models/architectures that have fast(er) primitives for doing OS calls?
  (And related to that the Linux crowd will forever hate on Tanenbaum because the microkernel design is "too slow". Any Amiga-like/nextgen type OS would IMO be more microkernel like and I'm toying with ideas how to lower the 'cost'.) 

[Linux = OS project led by someone that have claimed Amiga OS doesn't have pre-emptative multitasking...]

FlexSC ( EXTERNAL LINK )
should be of interest.

Instead of trying to fit AOS into a micro kernel model look at a modified exokernel/library OS design. By using shared libraries and trying to locate all work to the process were the data will be consumed/generated one gains quality of service and minimizes unnecessary IPC.
Example: TCP/IP stack should route incoming packets to the right process (see: early demultiplex) and all other processing will be done using shared library code in that process.
Look at Nemesis and perhaps K42.

Børge Nøst
Norway

Posts 53
29 Apr 2012 23:20


Megol . wrote:
  FlexSC ( EXTERNAL LINK )
  should be of interest.

An interesting read, with good ideas. It is however a software solution and I was kinda coming at it from a hardware angle.
It also depends on spare cpu time to an extent.


Thomas Richter
Germany
(MX-Board Owner)
Posts 1425
30 Apr 2012 12:14


Børge Nøst wrote:

Thomas Richter wrote:
  What is the problem with the interrupt call? It's the right way to do it.

  I know. I had the Operating Systems course too.

Then you had more courses than I. I'm not a computer scientist, you know. (-; But anyhow, I believe I got the idea right. (-;

Børge Nøst wrote:

  (Syncronous)Interrupts (i.e. traps) are however often expensive.

I doubt it really makes any difference on today's machine. How many cycles does a line-A exception has, including interrupt handling and interrupt dispatcher in the Os? Probably a low three-digit number. That's nothing compared to the actual operation carried out by the Os.

That said, I wouldn't make functions like AddHead() or FindTagItem() operating system functions. These belong into user-space libraries of course.

AmigaOs never got this concept right. Neither did MacOs classic, here user programs run in supervisor space (wrong, too!). Neither did Linux, which has a kernel that is way, way, way, way too big, and too much happens in supervisor space. Neither does it have a virtual file system (aka "dos.library") as AmigaOs - or actually Tripos - has. (Probably user space file system is something in this direction, but only very few filing systems are driven by this mechanism.)

I do not know much about Windows, neither MacOs X, but there's currently not an Os on the market I'm aware of that works the way how it should work.

Børge Nøst wrote:

  I was therefore wondering if there are other models/architectures that have fast(er) primitives for doing OS calls?

None I'm aware of, and I neither see this as an actual problem.

Børge Nøst wrote:

  (And related to that the Linux crowd will forever hate on Tanenbaum because the microkernel design is "too slow". Any Amiga-like/nextgen type OS would IMO be more microkernel like and I'm toying with ideas how to lower the 'cost'.)

Well, I'd rather guess Linux just evolved into what we see by accident and because Linus didn't know better, neither would it be "slower" (at least not by a substancial amount). Tannenbaum is absolutely right: Linux is not the way how you should design an Os.

But as already stated, I'm myself not aware of an Os that is designed correctly (not that I know all of them either, so that doesn't say much).


Thomas Richter
Germany
(MX-Board Owner)
Posts 1425
30 Apr 2012 12:19


Børge Nøst wrote:

I was therefore wondering if there are other models/architectures that have fast(er) primitives for doing OS calls?

Which reminds me: Not that I believe that the concept is right, but Tripos had this absurd? novel? interesting? idea of the "Global Vector", basically a jump table into its operating system functions. (Wrong in so far as there was no priviledge escalation).

The interesting part of this is that the GlobVec was merged with the vectors of the program, and the program could overload parts of the GlobVec entries by its own functions. IOW, there was an operating system function "Read" (FRead by today's dos.library, not to be confused with Read() which is a low-level call). But if the program came with its own FRead, it could replace this Os entry point. Of course only for itself. This is why all the BCPL programs carry this GlobVec around, it's "their private copy of the Os".

As said, the idea was kinna neat, it also avoids the "patch hell" AmigaOs was (SetFunction is global, unlike GlobVec, which is local. Sigh! To the process, I mean.), but it was also kind of misdesigned because everything happened in user space.
 

Megol .

Posts 672
30 Apr 2012 15:07


Børge Nøst wrote:

Megol . wrote:
  FlexSC ( EXTERNAL LINK )
  should be of interest.

  An interesting read, with good ideas. It is however a software solution and I was kinda coming at it from a hardware angle.
  It also depends on spare cpu time to an extent.

I don't really understand what you are searching for :)
Conceptually a software interrupt (more correctly synchronous exception) is the only secure way to escalate to supervisor mode.

Even a design where one have a bit per page descriptor that allow supervisor instructions to execute transparently one have potential security problems. What if one have the equivalent to (supervisor instruction)(return) instruction pair somewhere? A non-privileged process could then call that address and execute the privileged instruction. There's a chicken & egg problem there as one have to be privileged to securely call code that can execute privileged instructions.

Another problem comes from the stack as privileged code never should use the user stack for anything. If one does there are potential attack vectors.

ARM code use SWI (SoftWare Interrupt). X86 code use INT, SYSENTER, SYSCALL, call to a "gate" or undefined instructions. 68k use F or A trap instructions. Alpha use PAL code calls. The (unreleased) Mediaunity Mediaprocessor had a branch gateway instruction (RISCified equivalent with x86 gate call).
All these are in fact software interrupts with differing semantics. There's really no reason to use anything else as with a good underlying design a software interrupt should be just a bit slower than a normal call instruction (x86 being the exception) :)

Deep Sub Micron
Germany
(MX-Board Owner)
Posts 566
30 Apr 2012 19:33


This is of cause not related to the MMU - but you can make it related: Mark a page with supervisor code as not executable by user code (or maybe even not readable). If a user program calls a function in there then an exception happens. The exception code is executed as supervisor. In the exception code you check for the page being a syscall entry page and that "COMEFROM" pseudo opcode would have been executed next(that must not appear in that page otherwise for example as immediate data - I don't feel comfortable with this check). The processor will still be in supervisor mode when calling the code right after the "COMEFROM" pseudo opcode.

This kind of method can also be used for all the other different kind of exceptions that exists.

In that way still an an exception interrupt is used to gain supervisor privileges. But if the exception code is simple (and short) enough, it might also be executed in hardware. I am just not sure whether the hardware is much faster or otherwise better than the software solution.

Once in supervisor mode I think the most time consuming part just begins. Which is almost identical to the common interrupt way.

If you would think of an processor that don't switch into supervisor mode on an exception, but has this proposed kind of system call. Then having the exception calling the a supervisor function has almost the same effect as the current processors exception where we started with.

So I am sure there are more than one method doing system calls that are even (or sometimes less) secure than interrupts. It will be very hard to find one that is more powerful in a way that the usually used exception call with switch to supervisor mode can't emulate it.

The FlexSC paper determined about 79/71 cycles for a mode switch. I would really like to know how much of it is wasted by hardware doing silly things like flushing pipelines.


Thomas Richter
Germany
(MX-Board Owner)
Posts 1425
30 Apr 2012 20:29


deep sub micron wrote:

This is of cause not related to the MMU - but you can make it related: Mark a page with supervisor code as not executable by user code (or maybe even not readable). If a user program calls a function in there then an exception happens. The exception code is executed as supervisor. In the exception code you check for the page being a syscall entry page and that "COMEFROM" pseudo opcode would have been executed next(that must not appear in that page otherwise for example as immediate data - I don't feel comfortable with this check). The processor will still be in supervisor mode when calling the code right after the "COMEFROM" pseudo opcode.

Why does that make anything better? According to the reference, the real problem is the polution of the caches due to the mode switch, which doesn't change when you trigger the switch by a page fault.

The only benefit of the mechanism in the quoted reference is that caches of user and supervisor mode become separated because they run on separate cores, but this actually means that it is not the Os that is at fault, but rather the CPU design. What the result tells is that the CPU should actually have separate caches for user and supervisor data whenever the Os call overhead is significant.

I somehow doubt, however, that it is in most practical applications. Typically, library function calls like fread or so first buffer in user space and only branch off into the Os if the resource runs empty.

deep sub micron wrote:

  If you would think of an processor that don't switch into supervisor mode on an exception, but has this proposed kind of system call. Then having the exception calling the a supervisor function has almost the same effect as the current processors exception where we started with.

That doesn't make a difference. It is not the 100 cycles that matter, but that the cache is poluted. Maybe. Of course you shouldn't call the Os in a tight inner loop, as done in the study.

deep sub micron wrote:

  The FlexSC paper determined about 79/71 cycles for a mode switch. I would really like to know how much of it is wasted by hardware doing silly things like flushing pipelines.

That's most likely included in the cycle count. But that is not quite the point: The point is that the core architectures (and all microprocessors I'm aware of) have a unified cache, i.e. a cache line occupied by user mode data can be invalidated by supervisor data. The same goes for the MMU descriptor cache. It probably means that this design should be re-considered. Wasting 100 cycles by a pipeline stall is nothing compared to the >100 cycles *each memory access* wastes that is not cached somewhere.


Børge Nøst
Norway

Posts 53
01 May 2012 03:31


deep sub micron wrote:
The FlexSC paper determined about 79/71 cycles for a mode switch.

Which is potentially 200-400 instructions depending on superscalarism.

And to skip to something a bit different; my line of thought also implies some other kind of mmu model where you have a group type of access that you don't need to totally flush out when switching modes/processes. This to enable sharing more easily.
I think the PA-RISC (and Itanium by heritage) has some abilities like this.


Wojtek P
Poland

Posts 1597
01 May 2012 08:36


Børge Nøst wrote:

I have been googling around, but I have trouble finding something that matches what I'm thinking of:
 
  Does anyone have some good links for different models for going from user to supervisor mode (or generally from a lower to a higher rights level)?
 
  I am thinking of something like a bit in the mmu tables saying that code in that page has the right to change the privilege mode. That would probably need some kind of "COMEFROM"/"PREAMBLE" instruction that marks the start of a function so other code can't just jump into the code stream and hijack the escalate.
  Or are there other architectures that have cheap escalation models instead of the typical interrupt like type?

In RISC processor it is as simple as using single instruction - like syscall.

Depends on architecture it is equivalent to jump and link to constant address and turning on supervisor bit, or similar.

Incredibly simple and enough.

Marcel Verdaasdonk
Netherlands

Posts 3974
01 May 2012 23:38


The 68K has TAS instructions for this because it's atomic except on a Amiga of course!

EDIT: it would work in FastMem btw.

Megol .

Posts 672
02 May 2012 11:17


Marcel Verdaasdonk wrote:

The 68K has TAS instructions for this because it's atomic except on a Amiga of course!
 
  EDIT: it would work in FastMem btw.

WHAT? TAS is a synchronization instruction together with CAS. This thread is about switching to supervisor mode.

Deep Sub Micron
Germany
(MX-Board Owner)
Posts 566
02 May 2012 15:24


Thomas Richter wrote:

According to the reference, the real problem is the polution of the caches due to the mode switch, which doesn't change when you trigger the switch by a page fault.

Ok, I undersatand that you focus on cache pollution as it is one of the biggest chunks of wasted cycles with a syscall. I was more interested in the minor part of the mode switch it self and emulating one method with another method.

But now back to cache pollution: I wonder what the difference is between a function call and a syscall? Both should pollute the cache. If yes then same tricks for reducing syscalls should also speed up library calls that also massively pollute cache.

And on AmigaOS, where no mode switch is required (since all is usermode), is a syscall causing a similar overhead only due to cache pollution?


Deep Sub Micron
Germany
(MX-Board Owner)
Posts 566
02 May 2012 15:37


Børge Nøst wrote:

  And to skip to something a bit different; my line of thought also implies some other kind of mmu model where you have a group type of access that you don't need to totally flush out when switching modes/processes. This to enable sharing more easily.
  I think the PA-RISC (and Itanium by heritage) has some abilities like this.

I am not sure what you try to tell with the group type of access.

If a mode switch is caused by an exception then processor usually assumes the exceptionally occurring exception is unlikely and puts the code after the syscall into the pipeline. In a syscall case the probability for an exception is 100% and the pipeline need to be fushed.

That is a good reason to introduce a syscall opcode where a processor can predict the system mode switch and can fill the pipeline with the correct stuff. So in this case there should be no pipeline flush anymore.


posts 38page  1 2