Perhaps openHellPortal is complicated enough that you feel it should be a separate function. On the other hand, you want to be clear that nobody should expect openHellPortal to check the necessary precaution are in place. So, mark openHellPortal unsafe and provide a safe wrapper SafeHellPortal which internally calls openHellPortal after checking some necessary precautions are in place and ensures closeHellPortal is called when appropriate too.
As far as I know nobody builds hell portals with Rust (You have to assume there'd be a HN post about it right?) but they do plenty of embedded systems development, and those people use unsafe this way. Twiddling the SOC's interrupt controller is nothing to Rust itself, but the people writing the interrupt controller twiddling code can mark it "unsafe" and explain what callers must do to avoid chaos. Then callers can obey those instructions and make a safe wrapper for a particular purpose e.g. "SerialPort", and the average developer needn't even know that under the hood randomly twiddling the interrupt controller causes everything to catch fire, because they're using a safe SerialPort abstraction which can't cause that even if they hold it wrong.