Browse Source

[bios] Make uses of REAL_CODE() and PHYS_CODE() 64-bit clean

On a 64-bit CPU, any modification of a register by 32-bit or 16-bit
code will destroy the invisible upper 32 bits of the corresponding
64-bit register.  For example: a 32-bit "pushl %eax" followed by a
"popl %eax" will zero the upper half of %rax.  This differs from the
treatment of upper halves of 32-bit registers by 16-bit code: a
"pushw %ax" followed by a "popw %ax" will leave the upper 16 bits of
%eax unmodified.

Inline assembly generated using REAL_CODE() or PHYS_CODE() will
therefore have to preserve the upper halves of all registers, to avoid
clobbering registers that gcc expects to be preserved.

Output operands from REAL_CODE() and PHYS_CODE() assembly may
therefore contain undefined values in the upper 32 bits.

Fix by using explicit variable widths (e.g. uint32_t) for
non-discarded output operands, to ensure that undefined values in the
upper 32 bits of 64-bit registers are ignored.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
a3b4d6328c

+ 2
- 2
src/arch/x86/image/nbi.c View File

241
  */
241
  */
242
 static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
242
 static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
243
 	int discard_D, discard_S, discard_b;
243
 	int discard_D, discard_S, discard_b;
244
-	int rc;
244
+	int32_t rc;
245
 
245
 
246
 	DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image,
246
 	DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image,
247
 	       imgheader->execaddr.segoff.segment,
247
 	       imgheader->execaddr.segoff.segment,
283
 		0
283
 		0
284
 	};
284
 	};
285
 	int discard_D, discard_S, discard_b;
285
 	int discard_D, discard_S, discard_b;
286
-	int rc;
286
+	int32_t rc;
287
 
287
 
288
 	DBGC ( image, "NBI %p executing 32-bit image at %lx\n",
288
 	DBGC ( image, "NBI %p executing 32-bit image at %lx\n",
289
 	       image, imgheader->execaddr.linear );
289
 	       image, imgheader->execaddr.linear );

+ 2
- 2
src/arch/x86/interface/pcbios/memmap.c View File

174
 	struct memory_region *prev_region = NULL;
174
 	struct memory_region *prev_region = NULL;
175
 	uint32_t next = 0;
175
 	uint32_t next = 0;
176
 	uint32_t smap;
176
 	uint32_t smap;
177
-	size_t size;
177
+	uint32_t size;
178
 	unsigned int flags;
178
 	unsigned int flags;
179
 	unsigned int discard_D;
179
 	unsigned int discard_D;
180
 
180
 
216
 		}
216
 		}
217
 
217
 
218
 		if ( size < E820_MIN_SIZE ) {
218
 		if ( size < E820_MIN_SIZE ) {
219
-			DBG ( "INT 15,e820 returned only %zd bytes\n", size );
219
+			DBG ( "INT 15,e820 returned only %d bytes\n", size );
220
 			return -EINVAL;
220
 			return -EINVAL;
221
 		}
221
 		}
222
 
222
 

+ 4
- 4
src/arch/x86/interface/pcbios/pcibios.c View File

70
  */
70
  */
71
 int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
71
 int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
72
 	int discard_b, discard_D;
72
 	int discard_b, discard_D;
73
-	int status;
73
+	uint16_t status;
74
 
74
 
75
 	__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
75
 	__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
76
 					   "int $0x1a\n\t"
76
 					   "int $0x1a\n\t"
85
 				 "b" ( pci->busdevfn )
85
 				 "b" ( pci->busdevfn )
86
 			       : "edx" );
86
 			       : "edx" );
87
 
87
 
88
-	return ( ( status >> 8 ) & 0xff );
88
+	return ( status >> 8 );
89
 }
89
 }
90
 
90
 
91
 /**
91
 /**
98
  */
98
  */
99
 int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
99
 int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
100
 	int discard_b, discard_c, discard_D;
100
 	int discard_b, discard_c, discard_D;
101
-	int status;
101
+	uint16_t status;
102
 
102
 
103
 	__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
103
 	__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
104
 					   "int $0x1a\n\t"
104
 					   "int $0x1a\n\t"
111
 			         "b" ( pci->busdevfn ), "c" ( value )
111
 			         "b" ( pci->busdevfn ), "c" ( value )
112
 			       : "edx" );
112
 			       : "edx" );
113
 	
113
 	
114
-	return ( ( status >> 8 ) & 0xff );
114
+	return ( status >> 8 );
115
 }
115
 }
116
 
116
 
117
 PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );
117
 PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );

+ 1
- 1
src/arch/x86/interface/pcbios/rtc_entropy.c View File

187
 			    /* Disable interrupts */
187
 			    /* Disable interrupts */
188
 			    "cli\n\t"
188
 			    "cli\n\t"
189
 			    )
189
 			    )
190
-		: "=a" ( after ), "=d" ( before ), "=q" ( temp )
190
+		: "=a" ( after ), "=d" ( before ), "=Q" ( temp )
191
 		: "2" ( 0 ) );
191
 		: "2" ( 0 ) );
192
 
192
 
193
 	return ( after - before );
193
 	return ( after - before );

+ 8
- 4
src/arch/x86/interface/pxeparent/pxeparent.c View File

208
 		     void *params, size_t params_len ) {
208
 		     void *params, size_t params_len ) {
209
 	struct pxeparent_profiler *profiler = pxeparent_profiler ( function );
209
 	struct pxeparent_profiler *profiler = pxeparent_profiler ( function );
210
 	PXENV_EXIT_t exit;
210
 	PXENV_EXIT_t exit;
211
-	unsigned long started;
212
-	unsigned long stopped;
211
+	uint32_t before;
212
+	uint32_t started;
213
+	uint32_t stopped;
214
+	uint32_t after;
213
 	int discard_D;
215
 	int discard_D;
214
 	int rc;
216
 	int rc;
215
 
217
 
240
 			         "D" ( __from_data16 ( &pxeparent_params ) )
242
 			         "D" ( __from_data16 ( &pxeparent_params ) )
241
 			       : "ecx", "esi" );
243
 			       : "ecx", "esi" );
242
 	profile_stop ( &profiler->total );
244
 	profile_stop ( &profiler->total );
243
-	profile_start_at ( &profiler->p2r, profile_started ( &profiler->total));
245
+	before = profile_started ( &profiler->total );
246
+	after = profile_stopped ( &profiler->total );
247
+	profile_start_at ( &profiler->p2r, before );
244
 	profile_stop_at ( &profiler->p2r, started );
248
 	profile_stop_at ( &profiler->p2r, started );
245
 	profile_start_at ( &profiler->ext, started );
249
 	profile_start_at ( &profiler->ext, started );
246
 	profile_stop_at ( &profiler->ext, stopped );
250
 	profile_stop_at ( &profiler->ext, stopped );
247
 	profile_start_at ( &profiler->r2p, stopped );
251
 	profile_start_at ( &profiler->r2p, stopped );
248
-	profile_stop_at ( &profiler->r2p, profile_stopped ( &profiler->total ));
252
+	profile_stop_at ( &profiler->r2p, after );
249
 
253
 
250
 	/* Determine return status code based on PXENV_EXIT and
254
 	/* Determine return status code based on PXENV_EXIT and
251
 	 * PXENV_STATUS
255
 	 * PXENV_STATUS

Loading…
Cancel
Save