Once in long mode, is there a straightforward way of loading a new GDT without immediately causing a general protection fault?
The issue is that as soon as the new GDT is loaded with lgdt, it seems that fetching the next instruction will immediately fault as the CS register has not been updated to point to the correct entry in the new table.
The only way I can see of updating a GDT is to copy over the original descriptors into the new table, and then add any new entries to the end. This way, the new GDT is "backwards compatible" with the old one, and so the active segment selectors will still be valid.
This seems like a convoluted solution - is there an easier way?