Am 08.02.2012 06:53, schrieb David Gibson:
> For the pseries machine, TCE (IOMMU) tables can either be directly
> malloc()ed in qemu or, when running on a KVM which supports it, mmap()ed
> from a KVM ioctl.  The latter option is used when available, because it
> allows the (frequent bottlenext) H_PUT_TCE hypercall to be KVM accelerated.
> However, even when KVM is persent, TCE acceleration is not always possible.
> Only KVM HV supports this ioctl(), not KVM PR, or the kernel could run out
> of contiguous memory to allocate the new table.  In this case we need to
> fall back on the malloc()ed table.
> 
> When a device is removed, and we need to remove the TCE table, we need to
> either munmap() or free() the table as appropriate for how it was
> allocated.  The code is supposed to do that, but we buggily fail to
> initialize the tcet->fd variable in the malloc() case, which is used as a
> flag to determine which is the right choice.
> 
> This patch fixes the bug, and cleans up error messages relating to this
> path while we're at it.
> 
> Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org>
> Signed-off-by: David Gibson <da...@gibson.dropbear.id.au>

Looks okay except that your fprintf()s should use PRIx32 for uint32_t
liobn for safety (no difference on Linux).

Andreas

> ---
>  target-ppc/kvm.c |   12 ++++++++++--
>  1 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 50cfa02..90c6941 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -843,12 +843,18 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t 
> window_size, int *pfd)
>      int fd;
>      void *table;
>  
> +    /* Must set fd to -1 so we don't try to munmap when called for
> +     * destroying the table, which the upper layers -will- do
> +     */
> +    *pfd = -1;
>      if (!cap_spapr_tce) {
>          return NULL;
>      }
>  
>      fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
>      if (fd < 0) {
> +        fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
> +                liobn);
>          return NULL;
>      }
>  
> @@ -857,6 +863,8 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t 
> window_size, int *pfd)
>  
>      table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
>      if (table == MAP_FAILED) {
> +        fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n",
> +                liobn);
>          close(fd);
>          return NULL;
>      }
> @@ -876,8 +884,8 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t 
> window_size)
>      len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE);
>      if ((munmap(table, len) < 0) ||
>          (close(fd) < 0)) {
> -        fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE "
> -                "table: %s", strerror(errno));
> +        fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
> +                strerror(errno));
>          /* Leak the table */
>      }
>  

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

Reply via email to