Skip to contentSkip to conversation

KVM: when entering real mode align segment base to 16 bytes

PATCH RESEND Superseded Gleb Natapov 2 participants 6 messages Dec 27, 2010

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 1/1 KVM: when entering real mode align segment base to 16 bytes

VMX checks that base is equal segment shifted 4 bites left. Otherwise guest entry fails.

--
Same as previous one but with correct (I hope) To: header.

arch/x86/kvm/vmx.c +1 -1
index 2260783..45014ba 100644
@@ -1736,7 +1736,7 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
 	save->limit = vmcs_read32(sf->limit);
 	save->ar = vmcs_read32(sf->ar_bytes);
 	vmcs_write16(sf->selector, save->base >> 4);
-	vmcs_write32(sf->base, save->base & 0xfffff);
+	vmcs_write32(sf->base, save->base & 0xffff0);
 	vmcs_write32(sf->limit, 0xffff);
 	vmcs_write32(sf->ar_bytes, 0xf3);
 }

--
Gleb.

#1 lore raw
Quoted 12 lines · Gleb Natapov

VMX checks that base is equal segment shifted 4 bites left. Otherwise guest entry fails.

--
Same as previous one but with correct (I hope) To: header.

arch/x86/kvm/vmx.c +0 -0
index 2260783..45014ba 100644

arch/x86/kvm/vmx.c static void fix_rmode_seg(int seg, struct kvm_save_segment *save) · line 1742

Quoted 8 lines
arch/x86/kvm/vmx.c +1 -1
@@ -1736,7 +1736,7 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
  	save->limit = vmcs_read32(sf->limit);
  	save->ar = vmcs_read32(sf->ar_bytes);
  	vmcs_write16(sf->selector, save->base>>  4);
-	vmcs_write32(sf->base, save->base&  0xfffff);
+	vmcs_write32(sf->base, save->base&  0xffff0);
  	vmcs_write32(sf->limit, 0xffff);
  	vmcs_write32(sf->ar_bytes, 0xf3);
  }

This looks okay, but I'm curious what happened here. If the guest will use the segment it will fail on an incorrect address.

What's the scenario here? And what segment is involved? if it's fs or gs, or maybe ss, I can see it working out, but hardly otherwise.

Signature · 1 line
error compiling committee.c: too many arguments to function
#2 lore raw
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Gleb Natapov

VMX checks that base is equal segment shifted 4 bites left. Otherwise guest entry fails.

--
Same as previous one but with correct (I hope) To: header.

Quoted 17 lines

arch/x86/kvm/vmx.c static void fix_rmode_seg(int seg, struct kvm_save_segment *save) · line 1742

Quoted 13 lines
arch/x86/kvm/vmx.c +1 -1
index 2260783..45014ba 100644
@@ -1736,7 +1736,7 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
 	save->limit = vmcs_read32(sf->limit);
 	save->ar = vmcs_read32(sf->ar_bytes);
 	vmcs_write16(sf->selector, save->base>>  4);
-	vmcs_write32(sf->base, save->base&  0xfffff);
+	vmcs_write32(sf->base, save->base&  0xffff0);
 	vmcs_write32(sf->limit, 0xffff);
 	vmcs_write32(sf->ar_bytes, 0xf3);
 }

This looks okay, but I'm curious what happened here. If the guest will use the segment it will fail on an incorrect address.

Not much we can do about it. Either do what patch does, or exit to userspace with more meaningful message then:

kvm: unhandled exit 80000021
kvm_run returned -22

Quoted 3 lines

What's the scenario here? And what segment is involved? if it's fs or gs, or maybe ss, I can see it working out, but hardly otherwise.

The scenario is older Seabios that lefts DS segment unaligned during switch to real mode in int1587 function (copy extended memory).

--
Gleb.

#3 lore raw
Quoted 6 lines · Gleb Natapov
Quoted 3 lines

What's the scenario here? And what segment is involved? if it's fs or gs, or maybe ss, I can see it working out, but hardly otherwise.

The scenario is older Seabios that lefts DS segment unaligned during switch to real mode in int1587 function (copy extended memory).

Did it not use %ds then?

What about switching back to protected mode? I see we do restore the base, so it can continue to use the segment. I guess this isn't an issue for 1587.

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw
Quoted 10 lines · Avi Kivity
Quoted 6 lines · Gleb Natapov
Quoted 3 lines

What's the scenario here? And what segment is involved? if it's fs or gs, or maybe ss, I can see it working out, but hardly otherwise.

The scenario is older Seabios that lefts DS segment unaligned during switch to real mode in int1587 function (copy extended memory).

Did it not use %ds then?

It restores %ds before first use. There can be other guests of course that try to use %ds in protected mode. We can distinguish one from the other.

Quoted 4 lines

What about switching back to protected mode? I see we do restore the base, so it can continue to use the segment. I guess this isn't an issue for 1587.

Correct. 1587 does not return to protected mode again.

--
Gleb.

#5 lore raw
Quoted 9 lines · Gleb Natapov
Quoted 8 lines · Avi Kivity
Quoted 6 lines · Gleb Natapov
Quoted 3 lines

What's the scenario here? And what segment is involved? if it's fs or gs, or maybe ss, I can see it working out, but hardly otherwise.

The scenario is older Seabios that lefts DS segment unaligned during switch to real mode in int1587 function (copy extended memory).

Quoted 5 lines
Quoted 2 lines

Did it not use %ds then?

It restores %ds before first use. There can be other guests of course that try to use %ds in protected mode. We can distinguish one from the other.

Okay. Please add a printk_once() if we lose some bits here, so we know something bad happened.

In theory we should do this for the other cases too, but they have been there long enough.

Signature · 1 line
error compiling committee.c: too many arguments to function