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 > > >