Excerpts from Haren Myneni's message of February 20, 2022 5:55 am:
> 
> The user space opens VAS windows and issues NX requests by pasting
> CRB on the corresponding paste address mmap. When the system lost
> credits due to core removal, the kernel has to close the window in
> the hypervisor and make the window inactive by unmapping this paste
> address. Also the OS has to handle NX request page faults if the user
> space issue NX requests.
> 
> This handler maps the new paste address with the same VMA when the
> window is active again (due to core add with DLPAR). Otherwise
> returns paste failure.
> 

Reviewed-by: Nicholas Piggin <npig...@gmail.com>

> Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
> ---
>  arch/powerpc/include/asm/vas.h          | 10 ++++
>  arch/powerpc/platforms/book3s/vas-api.c | 68 +++++++++++++++++++++++++
>  2 files changed, 78 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h
> index 57573d9c1e09..27251af18c65 100644
> --- a/arch/powerpc/include/asm/vas.h
> +++ b/arch/powerpc/include/asm/vas.h
> @@ -29,6 +29,12 @@
>  #define VAS_THRESH_FIFO_GT_QTR_FULL  2
>  #define VAS_THRESH_FIFO_GT_EIGHTH_FULL       3
>  
> +/*
> + * VAS window Linux status bits
> + */
> +#define VAS_WIN_ACTIVE               0x0     /* Used in platform independent 
> */
> +                                     /* vas mmap() */
> +
>  /*
>   * Get/Set bit fields
>   */
> @@ -59,6 +65,9 @@ struct vas_user_win_ref {
>       struct pid *pid;        /* PID of owner */
>       struct pid *tgid;       /* Thread group ID of owner */
>       struct mm_struct *mm;   /* Linux process mm_struct */
> +     struct mutex mmap_mutex;        /* protects paste address mmap() */
> +                                     /* with DLPAR close/open windows */
> +     struct vm_area_struct *vma;     /* Save VMA and used in DLPAR ops */
>  };
>  
>  /*
> @@ -67,6 +76,7 @@ struct vas_user_win_ref {
>  struct vas_window {
>       u32 winid;
>       u32 wcreds_max; /* Window credits */
> +     u32 status;     /* Window status used in OS */
>       enum vas_cop_type cop;
>       struct vas_user_win_ref task_ref;
>       char *dbgname;
> diff --git a/arch/powerpc/platforms/book3s/vas-api.c 
> b/arch/powerpc/platforms/book3s/vas-api.c
> index 4d82c92ddd52..f359e7b2bf90 100644
> --- a/arch/powerpc/platforms/book3s/vas-api.c
> +++ b/arch/powerpc/platforms/book3s/vas-api.c
> @@ -316,6 +316,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, 
> unsigned long arg)
>               return PTR_ERR(txwin);
>       }
>  
> +     mutex_init(&txwin->task_ref.mmap_mutex);
>       cp_inst->txwin = txwin;
>  
>       return 0;
> @@ -350,6 +351,70 @@ static int coproc_release(struct inode *inode, struct 
> file *fp)
>       return 0;
>  }
>  
> +/*
> + * This fault handler is invoked when the core generates page fault on
> + * the paste address. Happens if the kernel closes window in hypervisor
> + * (on pseries) due to lost credit or the paste address is not mapped.
> + */
> +static vm_fault_t vas_mmap_fault(struct vm_fault *vmf)
> +{
> +     struct vm_area_struct *vma = vmf->vma;
> +     struct file *fp = vma->vm_file;
> +     struct coproc_instance *cp_inst = fp->private_data;
> +     struct vas_window *txwin;
> +     u64 paste_addr;
> +     int ret;
> +
> +     /*
> +      * window is not opened. Shouldn't expect this error.
> +      */
> +     if (!cp_inst || !cp_inst->txwin) {
> +             pr_err("%s(): Unexpected fault on paste address with TX window 
> closed\n",
> +                             __func__);
> +             return VM_FAULT_SIGBUS;
> +     }
> +
> +     txwin = cp_inst->txwin;
> +     /*
> +      * When the LPAR lost credits due to core removal or during
> +      * migration, invalidate the existing mapping for the current
> +      * paste addresses and set windows in-active (zap_page_range in
> +      * reconfig_close_windows()).
> +      * New mapping will be done later after migration or new credits
> +      * available. So continue to receive faults if the user space
> +      * issue NX request.
> +      */
> +     if (txwin->task_ref.vma != vmf->vma) {
> +             pr_err("%s(): No previous mapping with paste address\n",
> +                     __func__);
> +             return VM_FAULT_SIGBUS;
> +     }
> +
> +     mutex_lock(&txwin->task_ref.mmap_mutex);
> +     /*
> +      * The window may be inactive due to lost credit (Ex: core
> +      * removal with DLPAR). If the window is active again when
> +      * the credit is available, map the new paste address at the
> +      * the window virtual address.
> +      */
> +     if (txwin->status == VAS_WIN_ACTIVE) {
> +             paste_addr = cp_inst->coproc->vops->paste_addr(txwin);
> +             if (paste_addr) {
> +                     ret = vmf_insert_pfn(vma, vma->vm_start,
> +                                     (paste_addr >> PAGE_SHIFT));
> +                     mutex_unlock(&txwin->task_ref.mmap_mutex);
> +                     return ret;
> +             }
> +     }
> +     mutex_unlock(&txwin->task_ref.mmap_mutex);
> +
> +     return VM_FAULT_SIGBUS;
> +
> +}
> +static const struct vm_operations_struct vas_vm_ops = {
> +     .fault = vas_mmap_fault,
> +};
> +
>  static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
>  {
>       struct coproc_instance *cp_inst = fp->private_data;
> @@ -398,6 +463,9 @@ static int coproc_mmap(struct file *fp, struct 
> vm_area_struct *vma)
>       pr_devel("%s(): paste addr %llx at %lx, rc %d\n", __func__,
>                       paste_addr, vma->vm_start, rc);
>  
> +     txwin->task_ref.vma = vma;
> +     vma->vm_ops = &vas_vm_ops;
> +
>       return rc;
>  }
>  
> -- 
> 2.27.0
> 
> 
> 

Reply via email to