Skip to content

Commit a584b01

Browse files
Pull up following revision(s) (requested by bouyer in ticket #43):
sys/arch/i386/i386/locore.S: revision 1.202 sys/arch/i386/i386/locore.S: revision 1.203 sys/arch/i386/i386/locore.S: revision 1.204 sys/arch/amd64/amd64/locore.S: revision 1.231 sys/arch/amd64/amd64/locore.S: revision 1.232 sys/arch/amd64/amd64/locore.S: revision 1.233 sys/arch/xen/xen/hypervisor.c: revision 1.100 Our PVH bootstrap code assumed that the hvm_start_info structure provided by Xen is just after the end of the symbol case. With Xen 4.20 it's not always the case, so: - get the symbol table size from the first byte of the symbol table area provided by Xen. As we don't know if there is a symbol table or not, do a minimal sanity check on the size. - if the hvm_start_info structure is not in the page after kernel_end or esym, copy it there (this was already done in the genpvh case). While there, if we copy we can easily compute the size and not assume it all fits in one page. With this, a NetBSD PVH dom0 can boot on Xen 4.20 Fix some issues with symbol table detection on Xen PVH: - the stack grows down so the last pushed value is at 0(%esp), not -4(%esp). Pointed out by Joachim Kuebart. - 0x3fffffff is 1GB-1, not 1MB-1. Test the symtab size against 16MB (amd64 generic symbol table is just above 1MB these days) - I got confused by cmp's arguments order between intel and gas syntax, so the tests did the opposite of intended and the symtab was always considered valid. While there use unsigned conditions. Should fix booting in PVH mode with netbsd-INSTALL (which is stripped) Fix various typos, mainly in comments.
1 parent 2993880 commit a584b01

File tree

3 files changed

+203
-102
lines changed

3 files changed

+203
-102
lines changed

sys/arch/amd64/amd64/locore.S

Lines changed: 103 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: locore.S,v 1.230 2025/06/30 05:38:30 imil Exp $ */
1+
/* $NetBSD: locore.S,v 1.230.2.1 2025/10/01 17:12:58 martin Exp $ */
22

33
/*
44
* Copyright-o-rama!
@@ -856,6 +856,7 @@ next: pop %edi
856856
jmp compat
857857
compat:
858858

859+
movl $RELOC(tmpstk),%esp
859860
/*
860861
* 5. Not quite done yet, we're now in a compatibility segment, in
861862
* legacy mode. We must jump to a long mode segment. Need to set up
@@ -1092,7 +1093,6 @@ ENTRY(start_pvh)
10921093
*
10931094
* To distinguish between the 2 cases, we'll use the 'cpuid' instruction
10941095
*/
1095-
10961096
push %ebx
10971097
xorl %eax, %eax
10981098
cpuid
@@ -1115,82 +1115,139 @@ ENTRY(start_pvh)
11151115

11161116
.start_genpvh:
11171117

1118-
/* First, copy the hvm_start_info structure to __kernel_end */
1118+
/* announce ourself */
1119+
movl $VM_GUEST_GENPVH, RELOC(vm_guest)
1120+
1121+
pop %ebx
1122+
movl $RELOC(__kernel_end), %eax
1123+
movl %eax, %ecx
1124+
addl $KERNBASE_LO,%ecx
1125+
movl $RELOC(esym),%ebp
1126+
movl %ecx,(%ebp)
1127+
movl $KERNBASE_HI,4(%ebp)
1128+
1129+
jmp .copy_hvm_info
1130+
1131+
.start_xen32:
1132+
movl $VM_GUEST_XENPVH, RELOC(vm_guest)
1133+
/*
1134+
* Read the size of the symbol table, sanity-check and compute the end
1135+
* We have:
1136+
* | kernel |
1137+
* -------------- kernel_end
1138+
* alignment
1139+
* -------------- bsd_symtab
1140+
* | size (int) |
1141+
* | elf_header |
1142+
*
1143+
*/
1144+
movl $RELOC(__kernel_end), %ebp
1145+
addl $3, %ebp
1146+
andl $~3, %ebp
1147+
movl 0(%ebp), %eax /* read size */
1148+
testl $~0x00ffffff, %eax /* more than 16MB ? */
1149+
jnz .bad_esym
1150+
addl %ebp, %eax /* compute esym */
1151+
/* check if start_info is within symbol table */
1152+
movl 0(%esp), %ebx
1153+
cmp %ebp, %ebx
1154+
jb .save_esym /* %ebx < __kernel_end */
1155+
cmp %eax, %ebx
1156+
jae .save_esym /* %ebx >= esym */
1157+
1158+
.bad_esym:
1159+
movl $RELOC(__kernel_end), %eax
1160+
.save_esym:
1161+
movl %eax, %ebx
1162+
addl $KERNBASE_LO,%ebx
1163+
movl $RELOC(esym),%ebp
1164+
movl %ebx,(%ebp)
1165+
movl $KERNBASE_HI,4(%ebp)
1166+
/* advance to next page boundary, this will be our hvm_start_info */
1167+
addl $PGOFSET,%eax
1168+
andl $~PGOFSET,%eax
11191169
pop %ebx
1170+
1171+
.copy_hvm_info:
1172+
/*
1173+
* %ebx points to physical address provided by Xen
1174+
* %eax points to where we want it to be copied to
1175+
*/
1176+
/* check if %ebx and %eax are in the same page */
1177+
movl %ebx, %esi
1178+
addl $PGOFSET,%esi
1179+
andl $~PGOFSET,%esi
1180+
cmp %esi, %eax
1181+
je .same_hvm_info
1182+
1183+
/* First, copy the hvm_start_info structure to %eax */
11201184
movl %ebx, %esi
1121-
movl $RELOC(__kernel_end), %edi
1185+
movl %eax, %edi
11221186
movl $HVM_START_INFO_SIZE, %ecx
11231187
shrl $2, %ecx
11241188
rep movsl
11251189

11261190
/* Copy cmdline_paddr after hvm_start_info */
11271191
movl CMDLINE_PADDR(%ebx), %esi
1128-
movl $RELOC(__kernel_end), %ecx
1129-
movl %edi, CMDLINE_PADDR(%ecx) /* Set new cmdline_paddr in hvm_start_info */
1130-
.cmdline_copy:
1131-
movb (%esi), %al
1192+
movl %edi, CMDLINE_PADDR(%eax) /* Set new cmdline_paddr in hvm_start_info */
1193+
.cmdline_copy:
1194+
movb (%esi), %cl
11321195
movsb
1133-
cmp $0, %al
1196+
cmp $0, %cl
11341197
jne .cmdline_copy
11351198

11361199
/* Copy memmap_paddr after cmdline (only if hvm_start_info->version != 0) */
1137-
xorl %eax, %eax
1138-
cmpl START_INFO_VERSION(%ebx), %eax
1139-
je .reload_ebx
1200+
xorl %ecx, %ecx
1201+
cmpl START_INFO_VERSION(%ebx), %ecx
1202+
je .save_hvm_info
1203+
pushl %eax
11401204
movl MMAP_PADDR(%ebx), %esi
1141-
movl $RELOC(__kernel_end), %ecx
1142-
movl %edi, MMAP_PADDR(%ecx) /* Set new memmap_paddr in hvm_start_info */
1205+
movl %edi, MMAP_PADDR(%eax) /* Set new memmap_paddr in hvm_start_info */
11431206
movl MMAP_ENTRIES(%ebx), %eax /* Get memmap_entries */
11441207
movl $MMAP_ENTRY_SIZE, %ebx
11451208
mull %ebx /* eax * ebx => edx:eax */
11461209
movl %eax, %ecx
11471210
shrl $2, %ecx
11481211
rep movsl
1212+
popl %eax
11491213

1150-
.reload_ebx:
1151-
movl $RELOC(__kernel_end), %ebx
1152-
1153-
/* announce ourself */
1154-
movl $VM_GUEST_GENPVH, RELOC(vm_guest)
1155-
1156-
jmp .save_hvm_start_paddr
1157-
1158-
.start_xen32:
1159-
pop %ebx
1160-
movl $VM_GUEST_XENPVH, RELOC(vm_guest)
1161-
1162-
.save_hvm_start_paddr:
1163-
/*
1164-
* save addr of the hvm_start_info structure. This is also the end
1165-
* of the symbol table
1214+
.save_hvm_info:
1215+
/*
1216+
* %eax points to the start of hvm_start_info
1217+
* %edi points to the end
11661218
*/
1167-
movl %ebx, RELOC(hvm_start_paddr)
1168-
movl %ebx, %eax
1169-
addl $KERNBASE_LO,%eax
1170-
movl $RELOC(esym),%ebp
1219+
addl $KERNBASE_LO,%eax
1220+
movl $RELOC(hvm_start_info),%ebp
11711221
movl %eax,(%ebp)
11721222
movl $KERNBASE_HI,4(%ebp)
1223+
1224+
/* round end to next page boundary */
1225+
addl $PGOFSET,%edi
1226+
andl $~PGOFSET,%edi
1227+
11731228
/* get a page for HYPERVISOR_shared_info */
11741229
/* this is only needed if we are running on Xen */
11751230
cmpl $VM_GUEST_XENPVH, RELOC(vm_guest)
1176-
jne .add_hvm_start_info_page
1177-
addl $PAGE_SIZE, %ebx
1178-
addl $PGOFSET,%ebx
1179-
andl $~PGOFSET,%ebx
1231+
jne .save_eblob
11801232
movl $RELOC(HYPERVISOR_shared_info_pa),%ebp
1181-
movl %ebx,(%ebp)
1233+
movl %edi,(%ebp)
11821234
movl $0,4(%ebp)
1183-
/* XXX assume hvm_start_info+dependant structure fits in a single page */
1184-
.add_hvm_start_info_page:
1185-
addl $PAGE_SIZE, %ebx
1186-
addl $PGOFSET,%ebx
1187-
andl $~PGOFSET,%ebx
1188-
addl $KERNBASE_LO,%ebx
1235+
addl $PAGE_SIZE, %edi
1236+
.save_eblob:
1237+
addl $KERNBASE_LO,%edi
11891238
movl $RELOC(eblob),%ebp
1190-
movl %ebx,(%ebp)
1239+
movl %edi,(%ebp)
11911240
movl $KERNBASE_HI,4(%ebp)
11921241

11931242
jmp .Lbiosbasemem_finished
1243+
1244+
.same_hvm_info:
1245+
/* just use the provided %ebx */
1246+
/* XXX assume hvm_start_info+dependant structure fits in a single page */
1247+
movl %ebx, %eax
1248+
movl %ebx, %edi
1249+
addl $PAGE_SIZE, %edi
1250+
jmp .save_hvm_info
11941251
END(start_pvh)
11951252
.code64
11961253
# endif /* !XENPV */

0 commit comments

Comments
 (0)