Commit 434929bf11f0573d953c24287badbc2431a042ef

Authored by aliguori
1 parent 03ff3ca3

Make page_find() return 0 for too-large addresses (Eduardo Habkost)

On some cases, such as under KVM, tb_invalidate_phys_page_range()
may be called for large addresses, when qemu is configured to more than
4GB of RAM.

On these cases, qemu was crashing because it was using an index too
large for l1_map[], that supports only 32-bit addresses when compiling
without CONFIG_USER_ONLY.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5227 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 16 additions and 6 deletions
@@ -279,17 +279,24 @@ static void page_init(void) @@ -279,17 +279,24 @@ static void page_init(void)
279 #endif 279 #endif
280 } 280 }
281 281
282 -static inline PageDesc *page_find_alloc(target_ulong index) 282 +static inline PageDesc **page_l1_map(target_ulong index)
283 { 283 {
284 - PageDesc **lp, *p;  
285 -  
286 #if TARGET_LONG_BITS > 32 284 #if TARGET_LONG_BITS > 32
287 /* Host memory outside guest VM. For 32-bit targets we have already 285 /* Host memory outside guest VM. For 32-bit targets we have already
288 excluded high addresses. */ 286 excluded high addresses. */
289 if (index > ((target_ulong)L2_SIZE * L1_SIZE)) 287 if (index > ((target_ulong)L2_SIZE * L1_SIZE))
290 return NULL; 288 return NULL;
291 #endif 289 #endif
292 - lp = &l1_map[index >> L2_BITS]; 290 + return &l1_map[index >> L2_BITS];
  291 +}
  292 +
  293 +static inline PageDesc *page_find_alloc(target_ulong index)
  294 +{
  295 + PageDesc **lp, *p;
  296 + lp = page_l1_map(index);
  297 + if (!lp)
  298 + return NULL;
  299 +
293 p = *lp; 300 p = *lp;
294 if (!p) { 301 if (!p) {
295 /* allocate if not found */ 302 /* allocate if not found */
@@ -316,9 +323,12 @@ static inline PageDesc *page_find_alloc(target_ulong index) @@ -316,9 +323,12 @@ static inline PageDesc *page_find_alloc(target_ulong index)
316 323
317 static inline PageDesc *page_find(target_ulong index) 324 static inline PageDesc *page_find(target_ulong index)
318 { 325 {
319 - PageDesc *p; 326 + PageDesc **lp, *p;
  327 + lp = page_l1_map(index);
  328 + if (!lp)
  329 + return NULL;
320 330
321 - p = l1_map[index >> L2_BITS]; 331 + p = *lp;
322 if (!p) 332 if (!p)
323 return 0; 333 return 0;
324 return p + (index & (L2_SIZE - 1)); 334 return p + (index & (L2_SIZE - 1));