One problem with your design is if the overvoltage exceeds M2's maximum drain-source voltage, M2 won't actually disconnect the circuit.
Another is that when it's tripped, you'll have significant current and significant voltage in D2 and R1 and they'll get hot, and maybe fail.
The canonical solution for non-transient overvoltage protection is a crowbar circuit. This is a circuit which responds to an overvoltage not by attempting to disconnect the load, but instead by throwing a short circuit across the source. The advantage here is the voltage across the crowbar is relatively low, and so there will be less power dissipated in it, which means less heat and less chance of failure of the protection device itself.
Of course this results in drawing a very large current from the source too, so you add a fuse. Hopefully when the crowbar is tripped, it also blows the fuse. The fuse disconnects the load similarly to M2 in your circuit, but has a much higher maximum voltage.
It looks something like this:
simulate this circuit – Schematic created using CircuitLab
T1 is a thyristor. Normally it does not conduct. When the gate (the lead coming out the side) reaches some threshold voltage above the cathode (on the bottom), the thyristor begins conducting and won't stop until the current through the thyristor (from anode to cathode) decreases below some threshold.
When the threshold of D1 is reached, current begins to flow in R1, and consequently the voltage across R1 also increases. The thyristor's gate-cathode is in parallel with R1, so its voltage increases too. When the voltage across R1 reaches T1's threshold, T1 begins conducting and the crowbar is tripped.
C1 is just there to reduce nuisance tripping.
Two things can happen:
- the current will be very high, and blow the fuse
- the current won't be very high, and the fuse won't blow, and T1 will keep conducting until the fault is removed.
Accordingly, you'll want to select the fuse and spec the thyristor such that if the fuse doesn't blow, the thyristor won't overheat. This is easier since the voltage across a thyristor in conducting mode is relatively small.
You'll probably want to add to this arrangement a diode across the input which is normally reverse biased, but is forward biased in case the input voltage polarity is backwards. In this case the diode will conduct and either clamp the voltage to a safe level or blow the fuse.
Another option is to not connect the devices at all.
Instead, use an optoisolator. These devices are essentially an LED that shines on a transistor, in a convenient dark box. The light hitting the transistor creates a base current, just like light on a photodiode creates a current.
simulate this circuit
Select R1 such that at the intended input voltage, there's just enough current through the input diode to make it work, according to the datasheet. If there's an overvoltage fault on the input, then there will be more current through the input side, but usually there's significant headroom before anything is damaged.
If there's a very high or prolonged overvoltage fault, then the smoke will probably come out of the optoisolator or the resistor, however damage to the microcontroller is very unlikely. If you think this might happen a lot, put the optoisolator in a socket for easy replacement. They are pretty cheap.
A third option is to just put a large resistor in series with the input.
Since the microcontroller's inputs are already very high impedance, this won't make much of a difference under normal circumstances.
Microcontrollers almost always have ESD protection diodes on their inputs which clamp the inputs to within a diode-drop of the power supply rails. So in the case of overvoltage or reverse polarity on the input, one of these diodes will begin to conduct. If there's a resistor in series with the input, then the current through these diodes is limited and no damage is done.
A risk here is latch-up. If you have a current-limited power supply to the microcontroller, the risk of catastrophic failure can be reduced. One way to accomplish this is to power the MCU through a series resistor, shunted by a capacitor. The capacitor will supply the transient switching current for the microcontroller, but in the case of latch-up the resistor will limit the current, hopefully below the threshold of damage.
Usually if the current on the inputs and the power supply is limited, the latch-up won't be able to sustain itself once the fault is removed.
simulate this circuit