While running the kvm-unit-tests on Intel platforms with "split lock disable" feature, every test triggers a kernel warning of
x86/split lock detection: #AC: qemu-system-x86_64/373232 took a split_lock trap at address: 0x1e3 Hack KVM by exiting to QEMU on split lock #AC, we get KVM: exception 17 exit (error code 0x0) EAX=00000001 EBX=00000000 ECX=00000014 EDX=0001fb80 ESI=00000000 EDI=000000a8 EBP=00000000 ESP=00006f10 EIP=000001e3 EFL=00010002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0900 00009000 0000ffff 00009300 DPL=0 DS16 [-WA] CS =c000 000c0000 0000ffff 00009b00 DPL=0 CS16 [-RA] SS =0000 00000000 0000ffff 00009300 DPL=0 DS16 [-WA] DS =c000 000c0000 0000ffff 00009300 DPL=0 DS16 [-WA] FS =0950 00009500 0000ffff 00009300 DPL=0 DS16 [-WA] GS =06f2 00006f20 0000ffff 00009300 DPL=0 DS16 [-WA] LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy GDT= 000c02b4 00000027 IDT= 00000000 000003ff CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 EFER=0000000000000000 Code=89 16 08 00 65 66 0f 01 16 06 00 66 b8 01 00 00 00 0f 22 c0 <65> 66 ff 2e 00 00 b8 10 00 00 00 8e d0 8e d8 8e c0 8e e0 8e e8 66 b8 08 00 66 ba 10 05 66 And it matches with what disassembled from multiboo_dma.bin: #objdump -b binary -m i386 -D pc-bios/multiboot_dma.bin 1d1: 08 00 or %al,(%eax) 1d3: 65 66 0f 01 16 lgdtw %gs:(%esi) 1d8: 06 push %es 1d9: 00 66 b8 add %ah,-0x48(%esi) 1dc: 01 00 add %eax,(%eax) 1de: 00 00 add %al,(%eax) 1e0: 0f 22 c0 mov %eax,%cr0 > 1e3: 65 66 ff 2e ljmpw *%gs:(%esi) 1e7: 00 00 add %al,(%eax) 1e9: b8 10 00 00 00 mov $0x10,%eax 1ee: 8e d0 mov %eax,%ss 1f0: 8e d8 mov %eax,%ds 1f2: 8e c0 mov %eax,%es 1f4: 8e e0 mov %eax,%fs 1f6: 8e e8 mov %eax,%gs 1f8: 66 b8 08 00 mov $0x8,%ax 1fc: 66 ba 10 05 mov $0x510,%dx We can see that the instruction at 0x1e3 is a far jmp through the GDT. However, the GDT is not 8 byte aligned, the base is 0xc02b4. Intel processors follow the LOCK semantics to set the accessed flag of the segment descriptor when loading a segment descriptor. If the the segment descriptor crosses two cache line, it causes split lock. Fix it by aligning the GDT on 8 bytes, so that segment descriptor cannot span two cache lines. Signed-off-by: Xiaoyao Li <xiaoyao...@intel.com> --- pc-bios/multiboot_dma.bin | Bin 1024 -> 1024 bytes pc-bios/optionrom/multiboot.S | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/multiboot_dma.bin b/pc-bios/multiboot_dma.bin index c0e2c3102a3358207c61d3ae113524fb6007abc3..e6d0c97093b4fc11bc87fd58cbe6e577c2841cd0 100644 GIT binary patch delta 42 zcmV+_0M-A12!IHXDg)*M>ya%_3*Z7}i5><3W{V!;v4=GRlehvV0l2f@0vrJWTRMsk AMgRZ+ delta 46 zcmV+}0MY+|2!IHXDg)vI=aDT>3)})_i5><3W{V!)v4=GRlfVKZ0kpH@0vrL85Ca4O EZ**7=_y7O^ diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S index 181a4b03a3f2..c95e35c9cb62 100644 --- a/pc-bios/optionrom/multiboot.S +++ b/pc-bios/optionrom/multiboot.S @@ -208,7 +208,7 @@ ljmp2: prot_jump: .long prot_mode .short 8 -.align 4, 0 +.align 8, 0 gdt: /* 0x00 */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -- 2.43.0