ia64/xen-unstable

changeset 18002:92992f188053

ioemu: pass-through: pt_bar_mapping fix

In pt_bar_mapping function, r->addr should not be changed by invalid
value(-1). This value(-1) causes failure of mapping BAR when I/O Space
or Memory Space enable bit is updated repeatedly by native windows
driver.

This situation occurs in Windows Vista guest.

Signed-off-by: Naoki Nishiguchi <nisiguti@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 09 10:39:13 2008 +0100 (2008-07-09)
parents 823caffa7ddf
children 79978fcf8797
files tools/ioemu/hw/pass-through.c
line diff
     1.1 --- a/tools/ioemu/hw/pass-through.c	Wed Jul 09 10:38:20 2008 +0100
     1.2 +++ b/tools/ioemu/hw/pass-through.c	Wed Jul 09 10:39:13 2008 +0100
     1.3 @@ -1519,7 +1519,7 @@ static void pt_bar_mapping(struct pt_dev
     1.4      PCIDevice *dev = (PCIDevice *)&ptdev->dev;
     1.5      PCIIORegion *r;
     1.6      struct pt_region *base = NULL;
     1.7 -    uint32_t r_size = 0;
     1.8 +    uint32_t r_size = 0, r_addr = -1;
     1.9      int ret = 0;
    1.10      int i;
    1.11  
    1.12 @@ -1537,30 +1537,33 @@ static void pt_bar_mapping(struct pt_dev
    1.13             (base->bar_flag == PT_BAR_FLAG_UPPER))
    1.14                 continue;
    1.15  
    1.16 +        /* copy region address to temporary */
    1.17 +        r_addr = r->addr;
    1.18 +
    1.19          /* clear region address in case I/O Space or Memory Space disable */
    1.20          if (((base->bar_flag == PT_BAR_FLAG_IO) && !io_enable ) ||
    1.21              ((base->bar_flag == PT_BAR_FLAG_MEM) && !mem_enable ))
    1.22 -            r->addr = -1;
    1.23 +            r_addr = -1;
    1.24  
    1.25          /* prevent guest software mapping memory resource to 00000000h */
    1.26 -        if ((base->bar_flag == PT_BAR_FLAG_MEM) && (r->addr == 0))
    1.27 -            r->addr = -1;
    1.28 +        if ((base->bar_flag == PT_BAR_FLAG_MEM) && (r_addr == 0))
    1.29 +            r_addr = -1;
    1.30  
    1.31          /* align resource size (memory type only) */
    1.32          r_size = r->size;
    1.33          PT_GET_EMUL_SIZE(base->bar_flag, r_size);
    1.34  
    1.35          /* check overlapped address */
    1.36 -        ret = pt_chk_bar_overlap(dev->bus, dev->devfn, r->addr, r_size);
    1.37 +        ret = pt_chk_bar_overlap(dev->bus, dev->devfn, r_addr, r_size);
    1.38          if (ret > 0)
    1.39              PT_LOG("Base Address[%d] is overlapped. "
    1.40 -                "[Address:%08xh][Size:%04xh]\n", i, r->addr, r_size);
    1.41 +                "[Address:%08xh][Size:%04xh]\n", i, r_addr, r_size);
    1.42  
    1.43          /* check whether we need to update the mapping or not */
    1.44 -        if (r->addr != ptdev->bases[i].e_physbase)
    1.45 +        if (r_addr != ptdev->bases[i].e_physbase)
    1.46          {
    1.47              /* mapping BAR */
    1.48 -            r->map_func((PCIDevice *)ptdev, i, r->addr, 
    1.49 +            r->map_func((PCIDevice *)ptdev, i, r_addr, 
    1.50                           r_size, r->type);
    1.51          }
    1.52      }