mirror of https://github.com/torvalds/linux.git
KVM: s390: get rid of gmap_fault()
All gmap page faults are already handled in kvm by the function kvm_s390_handle_dat_fault(); only few users of gmap_fault remained, all within kvm. Convert those calls to use kvm_s390_handle_dat_fault() instead. Remove gmap_fault() entirely since it has no more users. Acked-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com> Link: https://lore.kernel.org/r/20250123144627.312456-8-imbrenda@linux.ibm.com Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Message-ID: <20250123144627.312456-8-imbrenda@linux.ibm.com>
This commit is contained in:
parent
3762e905ec
commit
6eb84e1300
|
|
@ -113,7 +113,6 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
|
||||||
unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
|
unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
|
||||||
unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
|
unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
|
||||||
int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
|
int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
|
||||||
int gmap_fault(struct gmap *, unsigned long gaddr, unsigned int fault_flags);
|
|
||||||
void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
|
void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
|
||||||
void __gmap_zap(struct gmap *, unsigned long gaddr);
|
void __gmap_zap(struct gmap *, unsigned long gaddr);
|
||||||
void gmap_unlink(struct mm_struct *, unsigned long *table, unsigned long vmaddr);
|
void gmap_unlink(struct mm_struct *, unsigned long *table, unsigned long vmaddr);
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
|
||||||
reg2, &srcaddr, GACC_FETCH, 0);
|
reg2, &srcaddr, GACC_FETCH, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
return kvm_s390_inject_prog_cond(vcpu, rc);
|
return kvm_s390_inject_prog_cond(vcpu, rc);
|
||||||
rc = gmap_fault(vcpu->arch.gmap, srcaddr, 0);
|
rc = kvm_s390_handle_dat_fault(vcpu, srcaddr, 0);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
@ -377,7 +377,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
|
||||||
reg1, &dstaddr, GACC_STORE, 0);
|
reg1, &dstaddr, GACC_STORE, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
return kvm_s390_inject_prog_cond(vcpu, rc);
|
return kvm_s390_inject_prog_cond(vcpu, rc);
|
||||||
rc = gmap_fault(vcpu->arch.gmap, dstaddr, FAULT_FLAG_WRITE);
|
rc = kvm_s390_handle_dat_fault(vcpu, dstaddr, FOLL_WRITE);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -607,130 +607,6 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__gmap_link);
|
EXPORT_SYMBOL(__gmap_link);
|
||||||
|
|
||||||
/**
|
|
||||||
* fixup_user_fault_nowait - manually resolve a user page fault without waiting
|
|
||||||
* @mm: mm_struct of target mm
|
|
||||||
* @address: user address
|
|
||||||
* @fault_flags:flags to pass down to handle_mm_fault()
|
|
||||||
* @unlocked: did we unlock the mmap_lock while retrying
|
|
||||||
*
|
|
||||||
* This function behaves similarly to fixup_user_fault(), but it guarantees
|
|
||||||
* that the fault will be resolved without waiting. The function might drop
|
|
||||||
* and re-acquire the mm lock, in which case @unlocked will be set to true.
|
|
||||||
*
|
|
||||||
* The guarantee is that the fault is handled without waiting, but the
|
|
||||||
* function itself might sleep, due to the lock.
|
|
||||||
*
|
|
||||||
* Context: Needs to be called with mm->mmap_lock held in read mode, and will
|
|
||||||
* return with the lock held in read mode; @unlocked will indicate whether
|
|
||||||
* the lock has been dropped and re-acquired. This is the same behaviour as
|
|
||||||
* fixup_user_fault().
|
|
||||||
*
|
|
||||||
* Return: 0 on success, -EAGAIN if the fault cannot be resolved without
|
|
||||||
* waiting, -EFAULT if the fault cannot be resolved, -ENOMEM if out of
|
|
||||||
* memory.
|
|
||||||
*/
|
|
||||||
static int fixup_user_fault_nowait(struct mm_struct *mm, unsigned long address,
|
|
||||||
unsigned int fault_flags, bool *unlocked)
|
|
||||||
{
|
|
||||||
struct vm_area_struct *vma;
|
|
||||||
unsigned int test_flags;
|
|
||||||
vm_fault_t fault;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
|
|
||||||
test_flags = fault_flags & FAULT_FLAG_WRITE ? VM_WRITE : VM_READ;
|
|
||||||
|
|
||||||
vma = find_vma(mm, address);
|
|
||||||
if (unlikely(!vma || address < vma->vm_start))
|
|
||||||
return -EFAULT;
|
|
||||||
if (unlikely(!(vma->vm_flags & test_flags)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
fault = handle_mm_fault(vma, address, fault_flags, NULL);
|
|
||||||
/* the mm lock has been dropped, take it again */
|
|
||||||
if (fault & VM_FAULT_COMPLETED) {
|
|
||||||
*unlocked = true;
|
|
||||||
mmap_read_lock(mm);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* the mm lock has not been dropped */
|
|
||||||
if (fault & VM_FAULT_ERROR) {
|
|
||||||
rc = vm_fault_to_errno(fault, 0);
|
|
||||||
BUG_ON(!rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
/* the mm lock has not been dropped because of FAULT_FLAG_RETRY_NOWAIT */
|
|
||||||
if (fault & VM_FAULT_RETRY)
|
|
||||||
return -EAGAIN;
|
|
||||||
/* nothing needed to be done and the mm lock has not been dropped */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __gmap_fault - resolve a fault on a guest address
|
|
||||||
* @gmap: pointer to guest mapping meta data structure
|
|
||||||
* @gaddr: guest address
|
|
||||||
* @fault_flags: flags to pass down to handle_mm_fault()
|
|
||||||
*
|
|
||||||
* Context: Needs to be called with mm->mmap_lock held in read mode. Might
|
|
||||||
* drop and re-acquire the lock. Will always return with the lock held.
|
|
||||||
*/
|
|
||||||
static int __gmap_fault(struct gmap *gmap, unsigned long gaddr, unsigned int fault_flags)
|
|
||||||
{
|
|
||||||
unsigned long vmaddr;
|
|
||||||
bool unlocked;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
retry:
|
|
||||||
unlocked = false;
|
|
||||||
|
|
||||||
vmaddr = __gmap_translate(gmap, gaddr);
|
|
||||||
if (IS_ERR_VALUE(vmaddr))
|
|
||||||
return vmaddr;
|
|
||||||
|
|
||||||
if (fault_flags & FAULT_FLAG_RETRY_NOWAIT)
|
|
||||||
rc = fixup_user_fault_nowait(gmap->mm, vmaddr, fault_flags, &unlocked);
|
|
||||||
else
|
|
||||||
rc = fixup_user_fault(gmap->mm, vmaddr, fault_flags, &unlocked);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
/*
|
|
||||||
* In the case that fixup_user_fault unlocked the mmap_lock during
|
|
||||||
* fault-in, redo __gmap_translate() to avoid racing with a
|
|
||||||
* map/unmap_segment.
|
|
||||||
* In particular, __gmap_translate(), fixup_user_fault{,_nowait}(),
|
|
||||||
* and __gmap_link() must all be called atomically in one go; if the
|
|
||||||
* lock had been dropped in between, a retry is needed.
|
|
||||||
*/
|
|
||||||
if (unlocked)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
return __gmap_link(gmap, gaddr, vmaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gmap_fault - resolve a fault on a guest address
|
|
||||||
* @gmap: pointer to guest mapping meta data structure
|
|
||||||
* @gaddr: guest address
|
|
||||||
* @fault_flags: flags to pass down to handle_mm_fault()
|
|
||||||
*
|
|
||||||
* Returns 0 on success, -ENOMEM for out of memory conditions, -EFAULT if the
|
|
||||||
* vm address is already mapped to a different guest segment, and -EAGAIN if
|
|
||||||
* FAULT_FLAG_RETRY_NOWAIT was specified and the fault could not be processed
|
|
||||||
* immediately.
|
|
||||||
*/
|
|
||||||
int gmap_fault(struct gmap *gmap, unsigned long gaddr, unsigned int fault_flags)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
mmap_read_lock(gmap->mm);
|
|
||||||
rc = __gmap_fault(gmap, gaddr, fault_flags);
|
|
||||||
mmap_read_unlock(gmap->mm);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(gmap_fault);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this function is assumed to be called with mmap_lock held
|
* this function is assumed to be called with mmap_lock held
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue