[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] xen/pt: Avoid initializing BARs from the host ones


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Anthony Perard <anthony.perard@xxxxxxxxxx>, Paul Durrant <paul@xxxxxxx>
  • From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
  • Date: Mon, 9 May 2022 08:49:25 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=j4ffbgMF998iVYrdqam9WmKjOZmFHBmdRCUa7te/1mg=; b=UPoKsn4i66vfpa/vggpxrPA397sN04otXmzcFJSiyxxLqEC2/GVRxQGUZbWaD7Xqu14GuWapM+OFUhoCz8K/JBngqdhuMGL27+70LNN/hnJPlqJmcn7vHWnuMnjhXKWBm1FOBmzb5J3Xdu5x0dcACYauiU4hmo4lP9kHAaW0TopafBKiT3uJkO7i/mAWXCAJfRHb/AmDigpDkqo54OAho6Xcj8bGEuM63/4Q28Qj7AS3r/D4EhYoj0HkGlhNBCX6SQIeGhRfQkgU14t6xY0n/L+sr01cBNJNLc0h3HY3WWfHs1wpXZlUWlKyJUnlLbmZydH88+MqEPjFJgEcVyM39Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nJkskl2140nx0g+xpTb3DoMZmEtsE5jKZwF49iaNbK/IONOutmf5xIobN7L32p1BgwG7sLyQwEQ3ARW8K2wTIbr1FBfCVhnOUn2/4R2hC0BzBt09dF/X4ePCJhgsZtc5ZROlaehH/IEwIZ8yIBwD0KBtzskZgvsMxzjzWyrd8ok/xJCbUvmuYhya3ifjib2SJy8iWDGit2aXiBK7XwhKNjGZLCT/uo2e1lJdMxw4oxQTwLsVSlIWusIo55JcMOkgUDpMtZOQqMTd/s1Lm0k56rTULHc38o3bPdvVBgsrDTj5sgG+7gH/H3CIjogErMnuLLxg6xaLjih6ylup9nXlCQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "qemu-devel@xxxxxxxxxx" <qemu-devel@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Mon, 09 May 2022 08:49:45 +0000
  • Ironport-data: A9a23:jJiCuK6lwbY2nWjdV0oovwxRtCnGchMFZxGqfqrLsTDasY5as4F+v mdNXm7VMv7bamfweo8kao20oRlXvJKAmtQwGQJlpH0zHi5G8cbLO4+Ufxz6V8+wwmwvb67FA +E2MISowBUcFyeEzvuVGuG96yE6j8lkf5KkYAL+EnkZqTRMFWFw0HqPp8Zj2tQy2YXhU1vX0 T/Pi5a31GGNimYc3l08s8pvmDs31BglkGpF1rCWTakjUG72zxH5PrpGTU2CByKQrr1vNvy7X 47+IISRpQs1yfuP5uSNyd4XemVSKlLb0JPnZnB+A8BOiTAazsA+PzpS2FPxpi67hh3Q9+2dx umhurSfFwd2JanVodgzdBBqKxh5IZRJ263+dC3XXcy7lyUqclPK6tA3VgQaGNNd/ex6R2ZT6 fYfNTYBKAiZgP67y666Te8qgdk/KM7sP8UUvXQIITPxVK56B8ycBfibo4YHgV/chegXdRraT 9AeciEpaB3PbgdQM1MTIJk/gP2plj/0dDgwRFe9+vJtvjWOl10ZPL7FKIbnStmQW8Nsh1uWh X//wkfQH0E1K4nKodaC2jf27gPVpgvgQ54bHrC88v9sgXWQy3YVBRlQUkG0ydGhg1O6c8JSL QoT4CVGhbE/8VHuQtTjUhmQpnmCsRgBHd1KHIUS+AyLj6bZ/QudLmwFVSJaLswrstcsQj4n3 UPPmMnmbQGDq5WQQHOZs7uR8zW7PHFPKXdYPHBZCwwY/9PkvYc/yArVScpuG7K0iduzHizsx zeNr241gLB7YdM36phXNGvv21qEzqUlhCZsjukLdgpJNj9EWbM=
  • Ironport-hdrordr: A9a23:76KOMaqbWHst+WCxiVtzBIIaV5uJL9V00zEX/kB9WHVpm5Oj+v xGzc5w6farsl0ssSkb6Ku90KnpewK+yXcH2/hqAV7EZnirhILIFvAu0WKG+VHd8kLFh4lgPM tbEpSWTeeAdWSS7vyKrzVQcexQpuVvmZrA7Yix854ud3ASV0gK1XYaNu/vKDwTeOAwP+tdKH Pz3Kp6jgvlXU5SQtWwB3EDUeSGjcbMjojabRkPAANiwBWSjBuzgYSKUiSw71M7aXdi0L0i+W /Kn0jS/aO4qcy2zRfayiv684lWot380dFObfb8yvT9aw+cyTpAVr4RHoFqjwpF5N1HL2xa1+ Ukli1QffibLUmhOF1d7yGdgjUImwxelkMKgWXo/UcL5/aJCg7SQvAx+76wfnbimjUdlcA536 RR022DsZ1LSRvGgSTm/tDNEwpnj0yuvBMZ4KYuZlFkIP0jgYVq3MUiFYJuYeU9NTO/7JpiHP hlDcna6voTeVSGb2rBtm0qxNC3RHw8EhqPX0BH46WuonJrtWE8y1FdyN0Un38G+p54Q55Y5/ 7cOqAtkL1VVMcZYa90Ge9ES8qqDW7GRw7KLQupUB/aPbBCP2iIp4/84b0z6u3vcJsUzIEqkJ CES19cvX5aQTOYNSRP5uw+zvngehTMYd228LAu23FQgMyOeJP7dSueVVspj8ys5/0CH8yzYY fHBK5r
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Msip_labels:
  • Thread-index: AQHYWlVI6k4vzeGas0CbAgtnJ0rrZq0WTf75
  • Thread-topic: [PATCH] xen/pt: Avoid initializing BARs from the host ones

Ping?

> From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> Sent: Wednesday, April 27, 2022 5:38 PM
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx <xen-devel@xxxxxxxxxxxxxxxxxxxx>
> Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>; Anthony Perard 
> <anthony.perard@xxxxxxxxxx>; Paul Durrant <paul@xxxxxxx>; 
> qemu-devel@xxxxxxxxxx <qemu-devel@xxxxxxxxxx>; Ross Lagerwall 
> <ross.lagerwall@xxxxxxxxxx>
> Subject: [PATCH] xen/pt: Avoid initializing BARs from the host ones 
>  
> The BAR emulated register definition does not set emu_mask because it
> varies depending on bar_flag.  If emu_mask is not set, then the BAR is
> initialized based on the host value which causes the BAR to be initially
> mapped at whatever value the host device was using. Although it does
> eventually get mapped at the correct location, it causes unnecessary
> mapping/unmappings.
> 
> To fix this, initialize a per-register emu_mask in XenPTReg from the
> initial value in XenPTRegInfo and then let the register's init() function
> set/modify the emu_mask if necessary. Update the code to use emu_mask
> in XenPTReg consistently and rename the existing emu_mask in
> XenPTRegInfo to emu_mask_init to help with refactoring.
> 
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
>  hw/xen/xen_pt.c             |   2 +-
>  hw/xen/xen_pt.h             |   5 +-
>  hw/xen/xen_pt_config_init.c | 221 ++++++++++++++++++------------------
>  3 files changed, 115 insertions(+), 113 deletions(-)
> 
> diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
> index 027190fa44..f0af1cfcec 100644
> --- a/hw/xen/xen_pt.c
> +++ b/hw/xen/xen_pt.c
> @@ -327,7 +327,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, 
> uint32_t addr,
>              uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
>              uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
>              uint8_t *ptr_val = NULL;
> -            uint32_t wp_mask = reg->emu_mask | reg->ro_mask;
> +            uint32_t wp_mask = reg_entry->emu_mask | reg->ro_mask;
>  
>              valid_mask <<= (find_addr - real_offset) << 3;
>              ptr_val = (uint8_t *)&val + (real_offset & 3);
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index 6b8e13cdee..dbb917a46c 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -46,7 +46,7 @@ void igd_write_opregion(XenPCIPassthroughState *s, uint32_t 
> val);
>  
>  /* function type for config reg */
>  typedef int (*xen_pt_conf_reg_init)
> -    (XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset,
> +    (XenPCIPassthroughState *, XenPTReg *, uint32_t real_offset,
>       uint32_t *data);
>  typedef int (*xen_pt_conf_dword_write)
>      (XenPCIPassthroughState *, XenPTReg *cfg_entry,
> @@ -117,7 +117,7 @@ struct XenPTRegInfo {
>      /* reg read/write-1-clear field mask (ON:RW1C/RW1CS, OFF:other) */
>      uint32_t rw1c_mask;
>      /* reg emulate field mask (ON:emu, OFF:passthrough) */
> -    uint32_t emu_mask;
> +    uint32_t emu_mask_init;
>      xen_pt_conf_reg_init init;
>      /* read/write function pointer
>       * for double_word/word/byte size */
> @@ -146,6 +146,7 @@ struct XenPTReg {
>          uint16_t *half_word;
>          uint32_t *word;
>      } ptr; /* pointer to dev.config. */
> +    uint32_t emu_mask;
>  };
>  
>  typedef const struct XenPTRegGroupInfo XenPTRegGroupInfo;
> diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
> index c5c4e943a8..2a934494ed 100644
> --- a/hw/xen/xen_pt_config_init.c
> +++ b/hw/xen/xen_pt_config_init.c
> @@ -25,7 +25,7 @@
>  
>  /* prototype */
>  
> -static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg,
> +static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s, XenPTReg 
> *reg_entry,
>                                 uint32_t real_offset, uint32_t *data);
>  
>  
> @@ -98,9 +98,10 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t 
> address)
>  }
>  
>  static uint32_t get_throughable_mask(const XenPCIPassthroughState *s,
> -                                     XenPTRegInfo *reg, uint32_t valid_mask)
> +                                     XenPTReg *reg_entry, uint32_t 
> valid_mask)
>  {
> -    uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
> +    XenPTRegInfo *reg = reg_entry->reg;
> +    uint32_t throughable_mask = ~(reg_entry->emu_mask | reg->ro_mask);
>  
>      if (!s->permissive) {
>          throughable_mask &= ~reg->res_mask;
> @@ -116,10 +117,10 @@ static uint32_t get_throughable_mask(const 
> XenPCIPassthroughState *s,
>  /* register initialization function */
>  
>  static int xen_pt_common_reg_init(XenPCIPassthroughState *s,
> -                                  XenPTRegInfo *reg, uint32_t real_offset,
> +                                  XenPTReg *reg_entry, uint32_t real_offset,
>                                    uint32_t *data)
>  {
> -    *data = reg->init_val;
> +    *data = reg_entry->reg->init_val;
>      return 0;
>  }
>  
> @@ -128,12 +129,11 @@ static int 
> xen_pt_common_reg_init(XenPCIPassthroughState *s,
>  static int xen_pt_byte_reg_read(XenPCIPassthroughState *s, XenPTReg 
> *cfg_entry,
>                                  uint8_t *value, uint8_t valid_mask)
>  {
> -    XenPTRegInfo *reg = cfg_entry->reg;
>      uint8_t valid_emu_mask = 0;
>      uint8_t *data = cfg_entry->ptr.byte;
>  
>      /* emulate byte register */
> -    valid_emu_mask = reg->emu_mask & valid_mask;
> +    valid_emu_mask = cfg_entry->emu_mask & valid_mask;
>      *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask);
>  
>      return 0;
> @@ -141,12 +141,11 @@ static int xen_pt_byte_reg_read(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  static int xen_pt_word_reg_read(XenPCIPassthroughState *s, XenPTReg 
> *cfg_entry,
>                                  uint16_t *value, uint16_t valid_mask)
>  {
> -    XenPTRegInfo *reg = cfg_entry->reg;
>      uint16_t valid_emu_mask = 0;
>      uint16_t *data = cfg_entry->ptr.half_word;
>  
>      /* emulate word register */
> -    valid_emu_mask = reg->emu_mask & valid_mask;
> +    valid_emu_mask = cfg_entry->emu_mask & valid_mask;
>      *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask);
>  
>      return 0;
> @@ -154,12 +153,11 @@ static int xen_pt_word_reg_read(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  static int xen_pt_long_reg_read(XenPCIPassthroughState *s, XenPTReg 
> *cfg_entry,
>                                  uint32_t *value, uint32_t valid_mask)
>  {
> -    XenPTRegInfo *reg = cfg_entry->reg;
>      uint32_t valid_emu_mask = 0;
>      uint32_t *data = cfg_entry->ptr.word;
>  
>      /* emulate long register */
> -    valid_emu_mask = reg->emu_mask & valid_mask;
> +    valid_emu_mask = cfg_entry->emu_mask & valid_mask;
>      *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask);
>  
>      return 0;
> @@ -173,11 +171,11 @@ static int xen_pt_byte_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint8_t writable_mask = 0;
> -    uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint8_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      uint8_t *data = cfg_entry->ptr.byte;
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>  
>      /* create value for writing to I/O device register */
> @@ -192,11 +190,11 @@ static int xen_pt_word_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint16_t writable_mask = 0;
> -    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint16_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      uint16_t *data = cfg_entry->ptr.half_word;
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>  
>      /* create value for writing to I/O device register */
> @@ -211,11 +209,11 @@ static int xen_pt_long_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint32_t writable_mask = 0;
> -    uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint32_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      uint32_t *data = cfg_entry->ptr.word;
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>  
>      /* create value for writing to I/O device register */
> @@ -229,7 +227,7 @@ static int xen_pt_long_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  /* XenPTRegInfo declaration
>   * - only for emulated register (either a part or whole bit).
>   * - for passthrough register that need special behavior (like interacting 
> with
> - *   other component), set emu_mask to all 0 and specify r/w func properly.
> + *   other component), set emu_mask_init to all 0 and specify r/w func 
> properly.
>   * - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
>   */
>  
> @@ -238,21 +236,21 @@ static int xen_pt_long_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>   */
>  
>  static int xen_pt_vendor_reg_init(XenPCIPassthroughState *s,
> -                                  XenPTRegInfo *reg, uint32_t real_offset,
> +                                  XenPTReg *reg_entry, uint32_t real_offset,
>                                    uint32_t *data)
>  {
>      *data = s->real_device.vendor_id;
>      return 0;
>  }
>  static int xen_pt_device_reg_init(XenPCIPassthroughState *s,
> -                                  XenPTRegInfo *reg, uint32_t real_offset,
> +                                  XenPTReg *reg_entry, uint32_t real_offset,
>                                    uint32_t *data)
>  {
>      *data = s->real_device.device_id;
>      return 0;
>  }
>  static int xen_pt_status_reg_init(XenPCIPassthroughState *s,
> -                                  XenPTRegInfo *reg, uint32_t real_offset,
> +                                  XenPTReg *unused, uint32_t real_offset,
>                                    uint32_t *data)
>  {
>      XenPTRegGroup *reg_grp_entry = NULL;
> @@ -287,17 +285,17 @@ static int 
> xen_pt_status_reg_init(XenPCIPassthroughState *s,
>      return 0;
>  }
>  static int xen_pt_header_type_reg_init(XenPCIPassthroughState *s,
> -                                       XenPTRegInfo *reg, uint32_t 
> real_offset,
> -                                       uint32_t *data)
> +                                       XenPTReg *reg_entry,
> +                                       uint32_t real_offset, uint32_t *data)
>  {
>      /* read PCI_HEADER_TYPE */
> -    *data = reg->init_val | 0x80;
> +    *data = reg_entry->reg->init_val | 0x80;
>      return 0;
>  }
>  
>  /* initialize Interrupt Pin register */
>  static int xen_pt_irqpin_reg_init(XenPCIPassthroughState *s,
> -                                  XenPTRegInfo *reg, uint32_t real_offset,
> +                                  XenPTReg *reg_entry, uint32_t real_offset,
>                                    uint32_t *data)
>  {
>      if (s->real_device.irq) {
> @@ -313,7 +311,7 @@ static int xen_pt_cmd_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint16_t writable_mask = 0;
> -    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint16_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      uint16_t *data = cfg_entry->ptr.half_word;
>  
>      /* modify emulate register */
> @@ -405,13 +403,13 @@ static inline uint32_t 
> base_address_with_flags(XenHostPCIIORegion *hr)
>      }
>  }
>  
> -static int xen_pt_bar_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg,
> +static int xen_pt_bar_reg_init(XenPCIPassthroughState *s, XenPTReg 
> *reg_entry,
>                                 uint32_t real_offset, uint32_t *data)
>  {
>      uint32_t reg_field = 0;
>      int index;
>  
> -    index = xen_pt_bar_offset_to_index(reg->offset);
> +    index = xen_pt_bar_offset_to_index(reg_entry->reg->offset);
>      if (index < 0 || index >= PCI_NUM_REGIONS) {
>          XEN_PT_ERR(&s->dev, "Internal error: Invalid BAR index [%d].\n", 
> index);
>          return -1;
> @@ -423,6 +421,21 @@ static int xen_pt_bar_reg_init(XenPCIPassthroughState 
> *s, XenPTRegInfo *reg,
>          reg_field = XEN_PT_INVALID_REG;
>      }
>  
> +     /* set emulate mask depend on BAR flag */
> +     switch (s->bases[index].bar_flag) {
> +     case XEN_PT_BAR_FLAG_MEM:
> +         reg_entry->emu_mask = XEN_PT_BAR_MEM_EMU_MASK;
> +         break;
> +     case XEN_PT_BAR_FLAG_IO:
> +         reg_entry->emu_mask = XEN_PT_BAR_IO_EMU_MASK;
> +         break;
> +     case XEN_PT_BAR_FLAG_UPPER:
> +         reg_entry->emu_mask = XEN_PT_BAR_ALLF;
> +         break;
> +     default:
> +         break;
> +    }
> +
>      *data = reg_field;
>      return 0;
>  }
> @@ -431,7 +444,6 @@ static int xen_pt_bar_reg_read(XenPCIPassthroughState *s, 
> XenPTReg *cfg_entry,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint32_t valid_emu_mask = 0;
> -    uint32_t bar_emu_mask = 0;
>      int index;
>  
>      /* get BAR index */
> @@ -444,23 +456,8 @@ static int xen_pt_bar_reg_read(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>      /* use fixed-up value from kernel sysfs */
>      *value = base_address_with_flags(&s->real_device.io_regions[index]);
>  
> -    /* set emulate mask depend on BAR flag */
> -    switch (s->bases[index].bar_flag) {
> -    case XEN_PT_BAR_FLAG_MEM:
> -        bar_emu_mask = XEN_PT_BAR_MEM_EMU_MASK;
> -        break;
> -    case XEN_PT_BAR_FLAG_IO:
> -        bar_emu_mask = XEN_PT_BAR_IO_EMU_MASK;
> -        break;
> -    case XEN_PT_BAR_FLAG_UPPER:
> -        bar_emu_mask = XEN_PT_BAR_ALLF;
> -        break;
> -    default:
> -        break;
> -    }
> -
>      /* emulate BAR */
> -    valid_emu_mask = bar_emu_mask & valid_mask;
> +    valid_emu_mask = cfg_entry->emu_mask & valid_mask;
>      *value = XEN_PT_MERGE_VALUE(*value, *cfg_entry->ptr.word, 
> ~valid_emu_mask);
>  
>      return 0;
> @@ -474,7 +471,6 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>      PCIDevice *d = PCI_DEVICE(s);
>      const PCIIORegion *r;
>      uint32_t writable_mask = 0;
> -    uint32_t bar_emu_mask = 0;
>      uint32_t bar_ro_mask = 0;
>      uint32_t r_size = 0;
>      int index = 0;
> @@ -493,7 +489,6 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>      /* set emulate mask and read-only mask values depend on the BAR flag */
>      switch (s->bases[index].bar_flag) {
>      case XEN_PT_BAR_FLAG_MEM:
> -        bar_emu_mask = XEN_PT_BAR_MEM_EMU_MASK;
>          if (!r_size) {
>              /* low 32 bits mask for 64 bit bars */
>              bar_ro_mask = XEN_PT_BAR_ALLF;
> @@ -502,13 +497,11 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>          }
>          break;
>      case XEN_PT_BAR_FLAG_IO:
> -        bar_emu_mask = XEN_PT_BAR_IO_EMU_MASK;
>          bar_ro_mask = XEN_PT_BAR_IO_RO_MASK | (r_size - 1);
>          break;
>      case XEN_PT_BAR_FLAG_UPPER:
>          assert(index > 0);
>          r_size = d->io_regions[index - 1].size >> 32;
> -        bar_emu_mask = XEN_PT_BAR_ALLF;
>          bar_ro_mask = r_size ? r_size - 1 : 0;
>          break;
>      default:
> @@ -516,7 +509,7 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState 
> *s, XenPTReg *cfg_entry,
>      }
>  
>      /* modify emulate register */
> -    writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~bar_ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>  
>      /* check whether we need to update the virtual region address or not */
> @@ -547,7 +540,7 @@ static int 
> xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
>      XenPTRegion *base = NULL;
>      PCIDevice *d = PCI_DEVICE(s);
>      uint32_t writable_mask = 0;
> -    uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint32_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      pcibus_t r_size = 0;
>      uint32_t bar_ro_mask = 0;
>      uint32_t *data = cfg_entry->ptr.word;
> @@ -594,7 +587,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xFFFF,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_vendor_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -605,7 +598,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xFFFF,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_device_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -616,7 +609,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .res_mask   = 0xF880,
> -        .emu_mask   = 0x0743,
> +        .emu_mask_init = 0x0743,
>          .init       = xen_pt_common_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_cmd_reg_write,
> @@ -627,7 +620,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -643,7 +636,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .res_mask   = 0x0007,
>          .ro_mask    = 0x06F8,
>          .rw1c_mask  = 0xF900,
> -        .emu_mask   = 0x0010,
> +        .emu_mask_init = 0x0010,
>          .init       = xen_pt_status_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -654,7 +647,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0x00,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_common_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -665,7 +658,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0x00,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_common_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -676,7 +669,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0x00,
> +        .emu_mask_init = 0x00,
>          .init       = xen_pt_header_type_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -687,7 +680,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0x00,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_common_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -698,7 +691,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_irqpin_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -764,7 +757,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = ~PCI_ROM_ADDRESS_MASK & ~PCI_ROM_ADDRESS_ENABLE,
> -        .emu_mask   = (uint32_t)PCI_ROM_ADDRESS_MASK,
> +        .emu_mask_init = (uint32_t)PCI_ROM_ADDRESS_MASK,
>          .init       = xen_pt_bar_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_exp_rom_bar_reg_write,
> @@ -786,7 +779,7 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -795,7 +788,7 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
>          .offset     = PCI_VPD_ADDR,
>          .size       = 2,
>          .ro_mask    = 0x0003,
> -        .emu_mask   = 0x0003,
> +        .emu_mask_init = 0x0003,
>          .init       = xen_pt_common_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -817,7 +810,7 @@ static XenPTRegInfo xen_pt_emu_reg_vendor[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -854,9 +847,10 @@ static inline uint8_t 
> get_device_type(XenPCIPassthroughState *s,
>  
>  /* initialize Link Control register */
>  static int xen_pt_linkctrl_reg_init(XenPCIPassthroughState *s,
> -                                    XenPTRegInfo *reg, uint32_t real_offset,
> +                                    XenPTReg *reg_entry, uint32_t 
> real_offset,
>                                      uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset);
>      uint8_t dev_type = get_device_type(s, real_offset - reg->offset);
>  
> @@ -872,9 +866,10 @@ static int 
> xen_pt_linkctrl_reg_init(XenPCIPassthroughState *s,
>  }
>  /* initialize Device Control 2 register */
>  static int xen_pt_devctrl2_reg_init(XenPCIPassthroughState *s,
> -                                    XenPTRegInfo *reg, uint32_t real_offset,
> +                                    XenPTReg *reg_entry, uint32_t 
> real_offset,
>                                      uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset);
>  
>      /* no need to initialize in case of cap_ver 1.x */
> @@ -887,9 +882,10 @@ static int 
> xen_pt_devctrl2_reg_init(XenPCIPassthroughState *s,
>  }
>  /* initialize Link Control 2 register */
>  static int xen_pt_linkctrl2_reg_init(XenPCIPassthroughState *s,
> -                                     XenPTRegInfo *reg, uint32_t real_offset,
> +                                     XenPTReg *reg_entry, uint32_t 
> real_offset,
>                                       uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset);
>      uint32_t reg_field = 0;
>  
> @@ -921,7 +917,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -932,7 +928,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0xFFFFFFFF,
> -        .emu_mask   = 0x10000000,
> +        .emu_mask_init = 0x10000000,
>          .init       = xen_pt_common_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_long_reg_write,
> @@ -943,7 +939,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 2,
>          .init_val   = 0x2810,
>          .ro_mask    = 0x8400,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_common_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -965,7 +961,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xFC34,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_linkctrl_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -986,7 +982,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xFFE0,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_devctrl2_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -997,7 +993,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xE040,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_linkctrl2_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -1020,7 +1016,7 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -1031,7 +1027,7 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0xFFFF,
> -        .emu_mask   = 0xF9C8,
> +        .emu_mask_init = 0xF9C8,
>          .init       = xen_pt_common_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -1044,7 +1040,7 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
>          .res_mask   = 0x00F0,
>          .ro_mask    = 0x610C,
>          .rw1c_mask  = 0x8000,
> -        .emu_mask   = 0x810B,
> +        .emu_mask_init = 0x810B,
>          .init       = xen_pt_common_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_word_reg_write,
> @@ -1066,7 +1062,7 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
>  
>  /* Message Control register */
>  static int xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s,
> -                                   XenPTRegInfo *reg, uint32_t real_offset,
> +                                   XenPTReg *reg_entry, uint32_t real_offset,
>                                     uint32_t *data)
>  {
>      XenPTMSI *msi = s->msi;
> @@ -1088,7 +1084,7 @@ static int 
> xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s,
>      msi->initialized = false;
>      msi->mapped = false;
>  
> -    *data = reg->init_val;
> +    *data = reg_entry->reg->init_val;
>      return 0;
>  }
>  static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
> @@ -1098,7 +1094,7 @@ static int 
> xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
>      XenPTRegInfo *reg = cfg_entry->reg;
>      XenPTMSI *msi = s->msi;
>      uint16_t writable_mask = 0;
> -    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint16_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      uint16_t *data = cfg_entry->ptr.half_word;
>  
>      /* Currently no support for multi-vector */
> @@ -1107,7 +1103,7 @@ static int 
> xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
>      }
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>      msi->flags |= *data & ~PCI_MSI_FLAGS_ENABLE;
>  
> @@ -1148,14 +1144,14 @@ static int 
> xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
>  
>  /* initialize Message Upper Address register */
>  static int xen_pt_msgaddr64_reg_init(XenPCIPassthroughState *s,
> -                                     XenPTRegInfo *reg, uint32_t real_offset,
> +                                     XenPTReg *reg_entry, uint32_t 
> real_offset,
>                                       uint32_t *data)
>  {
>      /* no need to initialize in case of 32 bit type */
>      if (!(s->msi->flags & PCI_MSI_FLAGS_64BIT)) {
>          *data = XEN_PT_INVALID_REG;
>      } else {
> -        *data = reg->init_val;
> +        *data = reg_entry->reg->init_val;
>      }
>  
>      return 0;
> @@ -1163,15 +1159,16 @@ static int 
> xen_pt_msgaddr64_reg_init(XenPCIPassthroughState *s,
>  /* this function will be called twice (for 32 bit and 64 bit type) */
>  /* initialize Message Data register */
>  static int xen_pt_msgdata_reg_init(XenPCIPassthroughState *s,
> -                                   XenPTRegInfo *reg, uint32_t real_offset,
> +                                   XenPTReg *reg_entry, uint32_t real_offset,
>                                     uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint32_t flags = s->msi->flags;
>      uint32_t offset = reg->offset;
>  
>      /* check the offset whether matches the type or not */
>      if (xen_pt_msi_check_type(offset, flags, DATA)) {
> -        *data = reg->init_val;
> +        *data = reg_entry->reg->init_val;
>      } else {
>          *data = XEN_PT_INVALID_REG;
>      }
> @@ -1181,9 +1178,10 @@ static int 
> xen_pt_msgdata_reg_init(XenPCIPassthroughState *s,
>  /* this function will be called twice (for 32 bit and 64 bit type) */
>  /* initialize Mask register */
>  static int xen_pt_mask_reg_init(XenPCIPassthroughState *s,
> -                                XenPTRegInfo *reg, uint32_t real_offset,
> +                                XenPTReg *reg_entry, uint32_t real_offset,
>                                  uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint32_t flags = s->msi->flags;
>  
>      /* check the offset whether matches the type or not */
> @@ -1200,9 +1198,10 @@ static int xen_pt_mask_reg_init(XenPCIPassthroughState 
> *s,
>  /* this function will be called twice (for 32 bit and 64 bit type) */
>  /* initialize Pending register */
>  static int xen_pt_pending_reg_init(XenPCIPassthroughState *s,
> -                                   XenPTRegInfo *reg, uint32_t real_offset,
> +                                   XenPTReg *reg_entry, uint32_t real_offset,
>                                     uint32_t *data)
>  {
> +    XenPTRegInfo *reg = reg_entry->reg;
>      uint32_t flags = s->msi->flags;
>  
>      /* check the offset whether matches the type or not */
> @@ -1227,7 +1226,7 @@ static int 
> xen_pt_msgaddr32_reg_write(XenPCIPassthroughState *s,
>      uint32_t *data = cfg_entry->ptr.word;
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>      s->msi->addr_lo = *data;
>  
> @@ -1261,7 +1260,7 @@ static int 
> xen_pt_msgaddr64_reg_write(XenPCIPassthroughState *s,
>      }
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>      /* update the msi_info too */
>      s->msi->addr_hi = *data;
> @@ -1301,7 +1300,7 @@ static int 
> xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
>      }
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>      /* update the msi_info too */
>      msi->data = *data;
> @@ -1343,7 +1342,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -1355,7 +1354,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .init_val   = 0x0000,
>          .res_mask   = 0xFE00,
>          .ro_mask    = 0x018E,
> -        .emu_mask   = 0x017E,
> +        .emu_mask_init = 0x017E,
>          .init       = xen_pt_msgctrl_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_msgctrl_reg_write,
> @@ -1366,7 +1365,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0x00000003,
> -        .emu_mask   = 0xFFFFFFFF,
> +        .emu_mask_init = 0xFFFFFFFF,
>          .init       = xen_pt_common_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_msgaddr32_reg_write,
> @@ -1377,7 +1376,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0x00000000,
> -        .emu_mask   = 0xFFFFFFFF,
> +        .emu_mask_init = 0xFFFFFFFF,
>          .init       = xen_pt_msgaddr64_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_msgaddr64_reg_write,
> @@ -1388,7 +1387,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0x0000,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_msgdata_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_msgdata_reg_write,
> @@ -1399,7 +1398,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 2,
>          .init_val   = 0x0000,
>          .ro_mask    = 0x0000,
> -        .emu_mask   = 0xFFFF,
> +        .emu_mask_init = 0xFFFF,
>          .init       = xen_pt_msgdata_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_msgdata_reg_write,
> @@ -1410,7 +1409,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0xFFFFFFFF,
> -        .emu_mask   = 0xFFFFFFFF,
> +        .emu_mask_init = 0xFFFFFFFF,
>          .init       = xen_pt_mask_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_mask_reg_write,
> @@ -1421,7 +1420,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0xFFFFFFFF,
> -        .emu_mask   = 0xFFFFFFFF,
> +        .emu_mask_init = 0xFFFFFFFF,
>          .init       = xen_pt_mask_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_mask_reg_write,
> @@ -1432,7 +1431,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0xFFFFFFFF,
> -        .emu_mask   = 0x00000000,
> +        .emu_mask_init = 0x00000000,
>          .init       = xen_pt_pending_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_long_reg_write,
> @@ -1443,7 +1442,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>          .size       = 4,
>          .init_val   = 0x00000000,
>          .ro_mask    = 0xFFFFFFFF,
> -        .emu_mask   = 0x00000000,
> +        .emu_mask_init = 0x00000000,
>          .init       = xen_pt_pending_reg_init,
>          .u.dw.read  = xen_pt_long_reg_read,
>          .u.dw.write = xen_pt_long_reg_write,
> @@ -1460,7 +1459,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
>  
>  /* Message Control register for MSI-X */
>  static int xen_pt_msixctrl_reg_init(XenPCIPassthroughState *s,
> -                                    XenPTRegInfo *reg, uint32_t real_offset,
> +                                    XenPTReg *reg_entry, uint32_t 
> real_offset,
>                                      uint32_t *data)
>  {
>      uint16_t reg_field;
> @@ -1479,7 +1478,7 @@ static int 
> xen_pt_msixctrl_reg_init(XenPCIPassthroughState *s,
>  
>      s->msix->ctrl_offset = real_offset;
>  
> -    *data = reg->init_val;
> +    *data = reg_entry->reg->init_val;
>      return 0;
>  }
>  static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
> @@ -1488,12 +1487,12 @@ static int 
> xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
>  {
>      XenPTRegInfo *reg = cfg_entry->reg;
>      uint16_t writable_mask = 0;
> -    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
> +    uint16_t throughable_mask = get_throughable_mask(s, cfg_entry, 
> valid_mask);
>      int debug_msix_enabled_old;
>      uint16_t *data = cfg_entry->ptr.half_word;
>  
>      /* modify emulate register */
> -    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
> +    writable_mask = cfg_entry->emu_mask & ~reg->ro_mask & valid_mask;
>      *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask);
>  
>      /* create value for writing to I/O device register */
> @@ -1527,7 +1526,7 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
>          .size       = 1,
>          .init_val   = 0x00,
>          .ro_mask    = 0xFF,
> -        .emu_mask   = 0xFF,
> +        .emu_mask_init = 0xFF,
>          .init       = xen_pt_ptr_reg_init,
>          .u.b.read   = xen_pt_byte_reg_read,
>          .u.b.write  = xen_pt_byte_reg_write,
> @@ -1539,7 +1538,7 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
>          .init_val   = 0x0000,
>          .res_mask   = 0x3800,
>          .ro_mask    = 0x07FF,
> -        .emu_mask   = 0x0000,
> +        .emu_mask_init = 0x0000,
>          .init       = xen_pt_msixctrl_reg_init,
>          .u.w.read   = xen_pt_word_reg_read,
>          .u.w.write  = xen_pt_msixctrl_reg_write,
> @@ -1555,7 +1554,7 @@ static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
>          .offset     = 0x0,
>          .size       = 4,
>          .init_val   = 0,
> -        .emu_mask   = 0xFFFFFFFF,
> +        .emu_mask_init = 0xFFFFFFFF,
>          .u.dw.read   = xen_pt_intel_opregion_read,
>          .u.dw.write  = xen_pt_intel_opregion_write,
>      },
> @@ -1817,7 +1816,7 @@ static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = {
>  
>  /* initialize Capabilities Pointer or Next Pointer register */
>  static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s,
> -                               XenPTRegInfo *reg, uint32_t real_offset,
> +                               XenPTReg *reg_entry, uint32_t real_offset,
>                                 uint32_t *data)
>  {
>      int i, rc;
> @@ -1926,8 +1925,10 @@ static void 
> xen_pt_config_reg_init(XenPCIPassthroughState *s,
>          unsigned int offset;
>          uint32_t val;
>  
> +        reg_entry->emu_mask = reg->emu_mask_init;
> +
>          /* initialize emulate register */
> -        rc = reg->init(s, reg_entry->reg,
> +        rc = reg->init(s, reg_entry,
>                         reg_grp->base_offset + reg->offset, &data);
>          if (rc < 0) {
>              g_free(reg_entry);
> @@ -1961,7 +1962,7 @@ static void 
> xen_pt_config_reg_init(XenPCIPassthroughState *s,
>          /* Set bits in emu_mask are the ones we emulate. The dev.config shall
>           * contain the emulated view of the guest - therefore we flip the 
> mask
>           * to mask out the host values (which dev.config initially has) . */
> -        host_mask = size_mask & ~reg->emu_mask;
> +        host_mask = size_mask & ~reg_entry->emu_mask;
>  
>          if ((data & host_mask) != (val & host_mask)) {
>              uint32_t new_val;
> -- 
> 2.31.1


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.