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 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 284 #if TARGET_LONG_BITS > 32
287 285 /* Host memory outside guest VM. For 32-bit targets we have already
288 286 excluded high addresses. */
289 287 if (index > ((target_ulong)L2_SIZE * L1_SIZE))
290 288 return NULL;
291 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 300 p = *lp;
294 301 if (!p) {
295 302 /* allocate if not found */
... ... @@ -316,9 +323,12 @@ static inline PageDesc *page_find_alloc(target_ulong index)
316 323  
317 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 332 if (!p)
323 333 return 0;
324 334 return p + (index & (L2_SIZE - 1));
... ...