Re: [PATCH] m68knommu: remove set_fs()
Michael Schmitz <[email protected]> Thu, 8 Jul 2021 18:33:09 +1200
| Newsgroups | gmane.linux.ports.m68k,gmane.linux.uclinux.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Linus, Am 08.07.2021 um 16:14 schrieb Linus Torvalds: > On Wed, Jul 7, 2021 at 8:40 PM Michael Schmitz <[email protected]> wrote: >> >> going back to this one, I missed that bit earlier - the last three hunks >> of your patch replaced KERNEL_DS by USER_DATA, everywhere else it's >> replaced by SUPER_DATA. Typo, or something too subtle for me to grasp? > > So I think the old KERNEL_DS was purely legacy, and isn't what I think > it's really supposed to be. It didn't _matter_, because then execve() > will set it to USER_DS by the time you run any user program, but I > didn't like it. > > So I decided that in the new world order, the rules should be really > straightforward and simple: > > - SFC/DFC is always USER_DATA normally, which is how get_user/put_user want it. > > - special functions that actually use SFC/DFC for some temporary > override will set it to that temporary value, and then restore it to > USER_DATA after use. > > and that's what I wrote my patch for. OK, got it now. > BUT! And this is the important part: > > My patch was completely untested garbage. I may have had opinions, I > may have had a plan, but the reality is that without testing (and > fixing things up for the things I had missed - like the code in > mm/maccess.c) that plan is just so much hot air. > > In other words, take the above with a big pinch of salt. > > And I want to stress once more time: if any of the SFC/DFC > modifications are done in interrupt handlers, that whole "set it back > to USER_DATA" is _wrong_. If they can happen in interrupts, then those > functions that modify SFC/DFC need to save the old value, and restore > it at the end, because otherwise you might have > > - function that uses SFC/DFC: > > set new 'value A' > > <- get interrupt here > nested function that uses SFC/DFC > set new value B > .. do whatever special op > set SDC/DFC to USER_DATA > <- interrupt returns > > original SFC/DFC function now has SFC/DFC with USER_DATA > it _wanted_ to have it with 'value A' > > See the problem? > > So if nesting can occur - due to interrupts - then all the things that > set a different SFC/DFC really need to save/restore the old one, > rather than set it back blindly to USER_DATA. I can't recall any use of get_user() etc. in interrupt handlers, but that certainly warrants a closer look. > Also, finally: my patch had that "preempt_disable/preempt_enable" > around the SFC/DFC modifications. That was hot garbage. Christoph > correctly pointed out that switch_to() will save/restore SFC/DFC, so > there's no real reason to. > > Except now that I think about it, I worry about getting scheduled away > *between* the instruction that sets SFC and the one that sets DFC. And > then switch_to() will save just SFC to the thread-struct. And then > restore the (new thread) SFC value to _both_ SFC and DFC. I wonder whether we can end up scheduling in the return path from an interrupt (interrupts return via ret_from_exception on m68k, and that has a test for thread info flags relating to reschedule and signals)... > > So task switching doesn't actually save and restore SFC and DFC. It > only really saves SFC, and then it restores both SFC and DFC with the > same value. > > Which should be ok, if the m68k code that modifies DFC will _always_ > have modified SFC to the new value first. So even if we then schedule > away and back in between the two instructions, it only means that > we'll set DFC then to the value that it will soon be assigned anyway. > > But it's all a tiny bit subtle and somewhat confusing. Bit too subtle for me still ... Cheers, Michael > > Linus >