I am talking about latest SDM rev. 63 there. In the description of the #SS exception 'Stack Fault', it is stated that the exception is raised when
· A not-present stack segment is detected when attempting to load the SS register. This violation can occur
during the execution of a task switch, a CALL instruction to a different privilege level, a return to a different
privilege level, an LSS instruction, or a MOV or POP instruction to the SS register.
Experiments on the real hardware demonstrate that this exception can occur if inter-privilege IRET is executed and popped an %ss segment register value which references a non-present descriptor. Small issue is that the explanation above does not list IRET explicitely, but it arguably falls under the 'return to a different privilege level' enumerator.
Much more serious problem is that IRET instruction lists #NP (segment not present) in this situation:
#NP(selector) If the return code or stack segment is not present.
In particular, it seems that QEMU emulates #NP, following the documentation.
Of course I may be wrong with interpreting the experiment results, but it would be useful clarify either the IRET instruction specification, and/or #SS description.
The SS register will hold either a segment number (Real Mode or V86 Mode) or a selector (Protected Mode). When in Real/V86 mode, the current selector is used ( that on transition to V86 or power-up/0x0 for Real Mode), to which the segment number *10 is applied as an offset to the base of the memory referenced by the current SS selector. The Selector itself could be invalid, or the address resolved by the SS (selector) + Segment offset (Real/V86) or SIB reference off of SS: could potentially point to an unmapped page in memory, and fault.
I think the document is interchanging segment and selector when it ought not.