<div dir="ltr"><div>UNH CI reported an ABI failure for this patch which did not report due to a bug on our end, so I'm manually reporting it now. I see Maxime you already predicted the issue though!</div><div><pre class="gmail-console-output" style="box-sizing:inherit;white-space:pre-wrap;padding:0.8rem 1rem;border-radius:10px;color:rgb(51,51,51);letter-spacing:-0.176px;line-height:1.66"><span class="gmail-pipeline-node-63" style="box-sizing:inherit"><span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span> 1 function with some indirect sub-type change:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span> 
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>   [C] 'function int rte_vhost_get_mem_table(int, rte_vhost_memory**)' at vhost.c:922:1 has some indirect sub-type changes:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>     parameter 2 of type 'rte_vhost_memory**' has sub-type changes:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>       in pointed to type 'rte_vhost_memory*':
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>         in pointed to type 'struct rte_vhost_memory' at rte_vhost.h:145:1:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>           type size hasn't changed
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>           1 data member change:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>             type of 'rte_vhost_mem_region regions[]' changed:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>               array element type 'struct rte_vhost_mem_region' changed:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>                 type size changed from 448 to 512 (in bits)
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>                 1 data member insertion:
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>                   'uint64_t alignment', at offset 448 (in bits) at rte_vhost.h:139:1
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span>               type size hasn't changed
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span> 
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span> Error: ABI issue reported for abidiff --suppr dpdk/devtools/libabigail.abignore --no-added-syms --headers-dir1 reference/include --headers-dir2 build_install/include reference/dump/librte_vhost.dump build_install/dump/librte_vhost.dump
<span class="gmail-timestamp" style="box-sizing:inherit"><b style="box-sizing:inherit">07:58:32</b> </span> ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged this as a potential issue).</span></pre></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 23, 2023 at 11:57 AM Mike Pattrick <<a href="mailto:mkp@redhat.com">mkp@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, Feb 23, 2023 at 11:12 AM Maxime Coquelin<br>
<<a href="mailto:maxime.coquelin@redhat.com" target="_blank">maxime.coquelin@redhat.com</a>> wrote:<br>
><br>
> Hi Mike,<br>
><br>
> Thanks for  looking into this issue.<br>
><br>
> On 2/23/23 05:35, Mike Pattrick wrote:<br>
> > The arguments passed to madvise should be aligned to the alignment of<br>
> > the backing memory. Now we keep track of each regions alignment and use<br>
> > then when setting coredump preferences. To facilitate this, a new member<br>
> > was added to rte_vhost_mem_region. A new function was added to easily<br>
> > translate memory address back to region alignment. Unneeded calls to<br>
> > madvise were reduced, as the cache removal case should already be<br>
> > covered by the cache insertion case. The previously inline function<br>
> > mem_set_dump was removed from a header file and made not inline.<br>
> ><br>
> > Fixes: 338ad77c9ed3 ("vhost: exclude VM hugepages from coredumps")<br>
> ><br>
> > Signed-off-by: Mike Pattrick <<a href="mailto:mkp@redhat.com" target="_blank">mkp@redhat.com</a>><br>
> > ---<br>
> > Since v1:<br>
> >   - Corrected a cast for 32bit compiles<br>
> > ---<br>
> >   lib/vhost/iotlb.c      |  9 +++---<br>
> >   lib/vhost/rte_vhost.h  |  1 +<br>
> >   lib/vhost/vhost.h      | 12 ++------<br>
> >   lib/vhost/vhost_user.c | 63 +++++++++++++++++++++++++++++++++++-------<br>
> >   4 files changed, 60 insertions(+), 25 deletions(-)<br>
> ><br>
> > diff --git a/lib/vhost/iotlb.c b/lib/vhost/iotlb.c<br>
> > index a0b8fd7302..5293507b63 100644<br>
> > --- a/lib/vhost/iotlb.c<br>
> > +++ b/lib/vhost/iotlb.c<br>
> > @@ -149,7 +149,6 @@ vhost_user_iotlb_cache_remove_all(struct vhost_virtqueue *vq)<br>
> >       rte_rwlock_write_lock(&vq->iotlb_lock);<br>
> ><br>
> >       RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {<br>
> > -             mem_set_dump((void *)(uintptr_t)node->uaddr, node->size, true);<br>
><br>
> Hmm, it should have been called with enable=false here since we are<br>
> removing the entry from the IOTLB cache. It should be kept in order to<br>
> "DONTDUMP" pages evicted from the cache.<br>
<br>
Here I was thinking that if we add an entry and then remove a<br>
different entry, they could be in the same page. But on I should have<br>
kept an enable=false in remove_all().<br>
<br>
And now that I think about it again, I could just check if there are<br>
any active cache entries in the page on every evict/remove, they're<br>
sorted so that should be an easy check. Unless there are any<br>
objections I'll go forward with that.<br>
<br>
><br>
> >               TAILQ_REMOVE(&vq->iotlb_list, node, next);<br>
> >               vhost_user_iotlb_pool_put(vq, node);<br>
> >       }<br>
> > @@ -171,7 +170,6 @@ vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq)<br>
> ><br>
> >       RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {<br>
> >               if (!entry_idx) {<br>
> > -                     mem_set_dump((void *)(uintptr_t)node->uaddr, node->size, true);<br>
><br>
> Same here.<br>
><br>
> >                       TAILQ_REMOVE(&vq->iotlb_list, node, next);<br>
> >                       vhost_user_iotlb_pool_put(vq, node);<br>
> >                       vq->iotlb_cache_nr--;<br>
> > @@ -224,14 +222,16 @@ vhost_user_iotlb_cache_insert(struct virtio_net *dev, struct vhost_virtqueue *vq<br>
> >                       vhost_user_iotlb_pool_put(vq, new_node);<br>
> >                       goto unlock;<br>
> >               } else if (node->iova > new_node->iova) {<br>
> > -                     mem_set_dump((void *)(uintptr_t)node->uaddr, node->size, true);<br>
> > +                     mem_set_dump((void *)(uintptr_t)new_node->uaddr, new_node->size, true,<br>
> > +                             hua_to_alignment(dev->mem, (void *)(uintptr_t)node->uaddr));<br>
> >                       TAILQ_INSERT_BEFORE(node, new_node, next);<br>
> >                       vq->iotlb_cache_nr++;<br>
> >                       goto unlock;<br>
> >               }<br>
> >       }<br>
> ><br>
> > -     mem_set_dump((void *)(uintptr_t)node->uaddr, node->size, true);<br>
> > +     mem_set_dump((void *)(uintptr_t)new_node->uaddr, new_node->size, true,<br>
> > +             hua_to_alignment(dev->mem, (void *)(uintptr_t)new_node->uaddr));<br>
> >       TAILQ_INSERT_TAIL(&vq->iotlb_list, new_node, next);<br>
> >       vq->iotlb_cache_nr++;<br>
> ><br>
> > @@ -259,7 +259,6 @@ vhost_user_iotlb_cache_remove(struct vhost_virtqueue *vq,<br>
> >                       break;<br>
> ><br>
> >               if (iova < node->iova + node->size) {<br>
> > -                     mem_set_dump((void *)(uintptr_t)node->uaddr, node->size, true);<br>
> >                       TAILQ_REMOVE(&vq->iotlb_list, node, next);<br>
> >                       vhost_user_iotlb_pool_put(vq, node);<br>
> >                       vq->iotlb_cache_nr--;<br>
> > diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h<br>
> > index a395843fe9..c5c97ea67e 100644<br>
> > --- a/lib/vhost/rte_vhost.h<br>
> > +++ b/lib/vhost/rte_vhost.h<br>
> > @@ -136,6 +136,7 @@ struct rte_vhost_mem_region {<br>
> >       void     *mmap_addr;<br>
> >       uint64_t mmap_size;<br>
> >       int fd;<br>
> > +     uint64_t alignment;<br>
><br>
> This is not possible to do this as it breaks the ABI.<br>
> You have to store the information somewhere else, or simply call<br>
> get_blk_size() in hua_to_alignment() since the fd is not closed.<br>
><br>
<br>
Sorry about that! You're right, checking the fd per operation should<br>
be easy enough.<br>
<br>
Thanks for the review,<br>
<br>
M<br>
<br>
> >   };<br>
> ><br>
> >   /**<br>
> > diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h<br>
> > index 5750f0c005..a2467ba509 100644<br>
> > --- a/lib/vhost/vhost.h<br>
> > +++ b/lib/vhost/vhost.h<br>
> > @@ -1009,14 +1009,6 @@ mbuf_is_consumed(struct rte_mbuf *m)<br>
> >       return true;<br>
> >   }<br>
> ><br>
> > -static __rte_always_inline void<br>
> > -mem_set_dump(__rte_unused void *ptr, __rte_unused size_t size, __rte_unused bool enable)<br>
> > -{<br>
> > -#ifdef MADV_DONTDUMP<br>
> > -     if (madvise(ptr, size, enable ? MADV_DODUMP : MADV_DONTDUMP) == -1) {<br>
> > -             rte_log(RTE_LOG_INFO, vhost_config_log_level,<br>
> > -                     "VHOST_CONFIG: could not set coredump preference (%s).\n", strerror(errno));<br>
> > -     }<br>
> > -#endif<br>
> > -}<br>
> > +uint64_t hua_to_alignment(struct rte_vhost_memory *mem, void *ptr);<br>
> > +void mem_set_dump(void *ptr, size_t size, bool enable, uint64_t alignment);<br>
> >   #endif /* _VHOST_NET_CDEV_H_ */<br>
> > diff --git a/lib/vhost/vhost_user.c b/lib/vhost/vhost_user.c<br>
> > index d702d082dd..6d09597fbe 100644<br>
> > --- a/lib/vhost/vhost_user.c<br>
> > +++ b/lib/vhost/vhost_user.c<br>
> > @@ -737,6 +737,40 @@ log_addr_to_gpa(struct virtio_net *dev, struct vhost_virtqueue *vq)<br>
> >       return log_gpa;<br>
> >   }<br>
> ><br>
> > +uint64_t<br>
> > +hua_to_alignment(struct rte_vhost_memory *mem, void *ptr)<br>
> > +{<br>
> > +     struct rte_vhost_mem_region *r;<br>
> > +     uint32_t i;<br>
> > +     uintptr_t hua = (uintptr_t)ptr;<br>
> > +<br>
> > +     for (i = 0; i < mem->nregions; i++) {<br>
> > +             r = &mem->regions[i];<br>
> > +             if (hua >= r->host_user_addr &&<br>
> > +                     hua < r->host_user_addr + r->size) {<br>
> > +                     return r->alignment;<br>
> > +             }<br>
> > +     }<br>
> > +<br>
> > +     /* If region isn't found, don't align at all */<br>
> > +     return 1;<br>
> > +}<br>
> > +<br>
> > +void<br>
> > +mem_set_dump(void *ptr, size_t size, bool enable, uint64_t pagesz)<br>
> > +{<br>
> > +#ifdef MADV_DONTDUMP<br>
> > +     void *start = RTE_PTR_ALIGN_FLOOR(ptr, pagesz);<br>
> > +     uintptr_t end = RTE_ALIGN_CEIL((uintptr_t)ptr + size, pagesz);<br>
> > +     size_t len = end - (uintptr_t)start;<br>
> > +<br>
> > +     if (madvise(start, len, enable ? MADV_DODUMP : MADV_DONTDUMP) == -1) {<br>
> > +             rte_log(RTE_LOG_INFO, vhost_config_log_level,<br>
> > +                     "VHOST_CONFIG: could not set coredump preference (%s).\n", strerror(errno));<br>
> > +     }<br>
> > +#endif<br>
> > +}<br>
> > +<br>
> >   static void<br>
> >   translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >   {<br>
> > @@ -767,6 +801,8 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >                       return;<br>
> >               }<br>
> ><br>
> > +             mem_set_dump(vq->desc_packed, len, true,<br>
> > +                     hua_to_alignment(dev->mem, vq->desc_packed));<br>
> >               numa_realloc(&dev, &vq);<br>
> >               *pdev = dev;<br>
> >               *pvq = vq;<br>
> > @@ -782,6 +818,8 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >                       return;<br>
> >               }<br>
> ><br>
> > +             mem_set_dump(vq->driver_event, len, true,<br>
> > +                     hua_to_alignment(dev->mem, vq->driver_event));<br>
> >               len = sizeof(struct vring_packed_desc_event);<br>
> >               vq->device_event = (struct vring_packed_desc_event *)<br>
> >                                       (uintptr_t)ring_addr_to_vva(dev,<br>
> > @@ -793,9 +831,8 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >                       return;<br>
> >               }<br>
> ><br>
> > -             mem_set_dump(vq->desc_packed, len, true);<br>
> > -             mem_set_dump(vq->driver_event, len, true);<br>
> > -             mem_set_dump(vq->device_event, len, true);<br>
> > +             mem_set_dump(vq->device_event, len, true,<br>
> > +                     hua_to_alignment(dev->mem, vq->device_event));<br>
> >               vq->access_ok = true;<br>
> >               return;<br>
> >       }<br>
> > @@ -812,6 +849,7 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >               return;<br>
> >       }<br>
> ><br>
> > +     mem_set_dump(vq->desc, len, true, hua_to_alignment(dev->mem, vq->desc));<br>
> >       numa_realloc(&dev, &vq);<br>
> >       *pdev = dev;<br>
> >       *pvq = vq;<br>
> > @@ -827,6 +865,7 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >               return;<br>
> >       }<br>
> ><br>
> > +     mem_set_dump(vq->avail, len, true, hua_to_alignment(dev->mem, vq->avail));<br>
> >       len = sizeof(struct vring_used) +<br>
> >               sizeof(struct vring_used_elem) * vq->size;<br>
> >       if (dev->features & (1ULL << VIRTIO_RING_F_EVENT_IDX))<br>
> > @@ -839,6 +878,8 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >               return;<br>
> >       }<br>
> ><br>
> > +     mem_set_dump(vq->used, len, true, hua_to_alignment(dev->mem, vq->used));<br>
> > +<br>
> >       if (vq->last_used_idx != vq->used->idx) {<br>
> >               VHOST_LOG_CONFIG(dev->ifname, WARNING,<br>
> >                       "last_used_idx (%u) and vq->used->idx (%u) mismatches;\n",<br>
> > @@ -849,9 +890,6 @@ translate_ring_addresses(struct virtio_net **pdev, struct vhost_virtqueue **pvq)<br>
> >                       "some packets maybe resent for Tx and dropped for Rx\n");<br>
> >       }<br>
> ><br>
> > -     mem_set_dump(vq->desc, len, true);<br>
> > -     mem_set_dump(vq->avail, len, true);<br>
> > -     mem_set_dump(vq->used, len, true);<br>
> >       vq->access_ok = true;<br>
> ><br>
> >       VHOST_LOG_CONFIG(dev->ifname, DEBUG, "mapped address desc: %p\n", vq->desc);<br>
> > @@ -1230,7 +1268,8 @@ vhost_user_mmap_region(struct virtio_net *dev,<br>
> >       region->mmap_addr = mmap_addr;<br>
> >       region->mmap_size = mmap_size;<br>
> >       region->host_user_addr = (uint64_t)(uintptr_t)mmap_addr + mmap_offset;<br>
> > -     mem_set_dump(mmap_addr, mmap_size, false);<br>
> > +     region->alignment = alignment;<br>
> > +     mem_set_dump(mmap_addr, mmap_size, false, alignment);<br>
> ><br>
> >       if (dev->async_copy) {<br>
> >               if (add_guest_pages(dev, region, alignment) < 0) {<br>
> > @@ -1535,7 +1574,6 @@ inflight_mem_alloc(struct virtio_net *dev, const char *name, size_t size, int *f<br>
> >               return NULL;<br>
> >       }<br>
> ><br>
> > -     mem_set_dump(ptr, size, false);<br>
> >       *fd = mfd;<br>
> >       return ptr;<br>
> >   }<br>
> > @@ -1566,6 +1604,7 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev,<br>
> >       uint64_t pervq_inflight_size, mmap_size;<br>
> >       uint16_t num_queues, queue_size;<br>
> >       struct virtio_net *dev = *pdev;<br>
> > +     uint64_t alignment;<br>
> >       int fd, i, j;<br>
> >       int numa_node = SOCKET_ID_ANY;<br>
> >       void *addr;<br>
> > @@ -1628,6 +1667,8 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev,<br>
> >               dev->inflight_info->fd = -1;<br>
> >       }<br>
> ><br>
> > +     alignment = get_blk_size(fd);<br>
> > +     mem_set_dump(addr, mmap_size, false, alignment);<br>
> >       dev->inflight_info->addr = addr;<br>
> >       dev->inflight_info->size = ctx->msg.payload.inflight.mmap_size = mmap_size;<br>
> >       dev->inflight_info->fd = ctx->fds[0] = fd;<br>
> > @@ -1744,10 +1785,10 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev,<br>
> >               dev->inflight_info->fd = -1;<br>
> >       }<br>
> ><br>
> > -     mem_set_dump(addr, mmap_size, false);<br>
> >       dev->inflight_info->fd = fd;<br>
> >       dev->inflight_info->addr = addr;<br>
> >       dev->inflight_info->size = mmap_size;<br>
> > +     mem_set_dump(addr, mmap_size, false, get_blk_size(fd));<br>
> ><br>
> >       for (i = 0; i < num_queues; i++) {<br>
> >               vq = dev->virtqueue[i];<br>
> > @@ -2242,6 +2283,7 @@ vhost_user_set_log_base(struct virtio_net **pdev,<br>
> >       struct virtio_net *dev = *pdev;<br>
> >       int fd = ctx->fds[0];<br>
> >       uint64_t size, off;<br>
> > +     uint64_t alignment;<br>
> >       void *addr;<br>
> >       uint32_t i;<br>
> ><br>
> > @@ -2280,6 +2322,7 @@ vhost_user_set_log_base(struct virtio_net **pdev,<br>
> >        * fail when offset is not page size aligned.<br>
> >        */<br>
> >       addr = mmap(0, size + off, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);<br>
> > +     alignment = get_blk_size(fd);<br>
> >       close(fd);<br>
> >       if (addr == MAP_FAILED) {<br>
> >               VHOST_LOG_CONFIG(dev->ifname, ERR, "mmap log base failed!\n");<br>
> > @@ -2296,7 +2339,7 @@ vhost_user_set_log_base(struct virtio_net **pdev,<br>
> >       dev->log_addr = (uint64_t)(uintptr_t)addr;<br>
> >       dev->log_base = dev->log_addr + off;<br>
> >       dev->log_size = size;<br>
> > -     mem_set_dump(addr, size, false);<br>
> > +     mem_set_dump(addr, size + off, false, alignment);<br>
> ><br>
> >       for (i = 0; i < dev->nr_vring; i++) {<br>
> >               struct vhost_virtqueue *vq = dev->virtqueue[i];<br>
><br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt"><font color="#000000" face="Arial"><span style="font-size:13.3333px;white-space:pre-wrap">Patrick Robb</span></font></p><p style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Technical Service Manager</span></p><p dir="ltr" style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">UNH InterOperability Laboratory</span></p><p dir="ltr" style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style="font-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">21 Madbury Rd, Suite 100, Durham, NH 03824</span></p><p dir="ltr" style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style="font-size:10pt;font-family:Arial;color:rgb(17,85,204);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><a href="http://www.iol.unh.edu/" style="color:rgb(17,85,204)" target="_blank">www.iol.unh.edu</a></span></p><p dir="ltr" style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><br></p><p dir="ltr" style="color:rgb(34,34,34);line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style="font-size:10pt;font-family:Arial;color:rgb(51,51,51);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><img src="https://lh4.googleusercontent.com/7sTY8VswXadak_YT0J13osh5ockNVRX2BuYaRsKoTTpkpilBokA0WlocYHLB4q7XUgXNHka6-ns47S8R_am0sOt7MYQQ1ILQ3S-P5aezsrjp3-IsJMmMrErHWmTARNgZhpAx06n2" width="150" height="37" style="border: none;"></span></p></div></div>