phil-opp / blog_os

Writing an OS in Rust
http://os.phil-opp.com
Apache License 2.0
14.27k stars 1.01k forks source link

Deadlock in VGA #814

Open vinaychandra opened 4 years ago

vinaychandra commented 4 years ago

The current VGA implementation has a dead lock possibility.

In post-12, main.rs,

    ...
    println!("Hello World{}", "!");
    blog_os::init();
    unsafe {
        println!("{}", *(0x500000 as *mut u8));
    }

Expected: PageFault output Actual: Deadlock in println in PageFault Handler.

GuillaumeDIDIER commented 3 years ago

Output in fault handlers is a very tricky problem.

For panic message output, you probably need to have a dedicated unsafe panic-printing facility.

More generally printing is probably one of those operation that should not happen in interrupt / fault handlers, as you generally want to protect printing with a kind of mutex and mutex are not async-signal safe (to use the unix signal safety terminology to reason about trap/fault/interrupt handlers). You can print in the other half of your driver (a normal task scheduled), if your kernel has an actual scheduler, or use special somewhat unsafe primitive mentioned above if you are in a hopeless situation.

phil-opp commented 3 years ago

Thanks for reporting and sorry for replying so late! As @GuillaumeDIDIER noted, there isn't a simple solution to this problem unfortunately.

I'm currently working on updating the blog for the upcoming UEFI bootloader and I plan to completely rewrite the screen output post for this. I'm thinking about reserving a part of the screen for errors in the new version, so that at least the first exception handler would always be able to print. We could even add some special error printer that doesn't use locking at all so that no deadlocks can occur. This would introduce some race conditions, but I think they should be technically safe (i.e. not lead to undefined behavior) in this case since we use volatile operations.