On 3/11/20 8:24 AM, Sean Christopherson wrote:
On Tue, Mar 10, 2020 at 04:51:40PM -0700, Jim Mattson wrote:
On Tue, Mar 10, 2020 at 4:29 PM Krish Sadhukhan
<krish.sadhukhan@xxxxxxxxxx> wrote:
Even thought today's x86 hardware uses paging and not segmentation for memory
management, it is still good to have some tests that can verify the sanity of
the segment register fields on vmentry of nested guests.
The test on SS Selector field is failing because the hardware (I am using
Intel Xeon Platinum 8167M 2.00GHz) doesn't raise any error even if the
prescribed bit pattern is not set and as a result vmentry succeeds.
Are you sure this isn't just an L0 bug? For instance, does your L0 set
"unrestricted guest" in vmcs02, even when L1 doesn't set it in vmcs12?
I assume this is the check being discussed? The code is flawed, if CS=3
and SS=3, "sel = sel_saved | (~cs_rpl_bits & 0x3)" will yield SS=3 and pass.
I think you wanted something like:
sel = (sel_saved & ~0x3) | (~cs_rpl_bits & 0x3);
Yes, my bit-setting was wrong and I have fixed it. But that's not the
cause of the failure.
It appears that Jim's suspicion is correct. L0 is not checking in
prepare_vmcs02_early(), whether vmcs12 has "unrestricted guest" turned
off. After I put the relevant setting in that function, the test now
passes (meaning vmentry fails).
I will add this fix in v2.
+ if (!(vmcs_read(GUEST_RFLAGS) & X86_EFLAGS_VM) &&
+ !(vmcs_read(CPU_SECONDARY) & CPU_URG)) {
+ u16 cs_rpl_bits = vmcs_read(GUEST_SEL_CS) & 0x3;
+ sel_saved = vmcs_read(GUEST_SEL_SS);
+ sel = sel_saved | (~cs_rpl_bits & 0x3);
+ TEST_SEGMENT_SEL(GUEST_SEL_SS, "GUEST_SEL_SS", sel, sel_saved);
+ }
+}