From: Jan Beulich Date: Thu, 15 May 2014 13:26:12 +0000 (+0200) Subject: switch internal hypercall restart indication from -EAGAIN to -ERESTART X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~5005 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f5118cae0a7f7748c6f08f557e2cfbbae686434a;p=xen.git switch internal hypercall restart indication from -EAGAIN to -ERESTART -EAGAIN being a return value we want to return to the actual caller in a couple of cases makes this unsuitable for restart indication, and x86 already developed two cases where -EAGAIN could not be returned as intended due to this (which is being fixed here at once). Signed-off-by: Jan Beulich Acked-by: Ian Campbell Reviewed-by: Tim Deegan --- diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 0b77c59df6..2ae6941a63 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -682,7 +682,7 @@ static int relinquish_memory(struct domain *d, struct page_list_head *list) if ( hypercall_preempt_check() ) { - ret = -EAGAIN; + ret = -ERESTART; goto out; } } diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 816da21a30..b85143b17a 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -454,7 +454,7 @@ static int apply_p2m_changes(struct domain *d, if ( hypercall_preempt_check() ) { p2m->lowest_mapped_gfn = addr >> PAGE_SHIFT; - rc = -EAGAIN; + rc = -ERESTART; goto out; } count = 0; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 1436aee483..e89621074f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -929,8 +929,8 @@ int arch_set_info_guest( switch ( rc ) { case -EINTR: - rc = -EAGAIN; - case -EAGAIN: + rc = -ERESTART; + case -ERESTART: case 0: break; default: @@ -957,8 +957,8 @@ int arch_set_info_guest( switch ( rc ) { case -EINTR: - rc = -EAGAIN; - case -EAGAIN: + rc = -ERESTART; + case -ERESTART: v->arch.old_guest_table = pagetable_get_page(v->arch.guest_table); v->arch.guest_table = pagetable_null(); @@ -1808,9 +1808,9 @@ static int relinquish_memory( { case 0: break; - case -EAGAIN: + case -ERESTART: case -EINTR: - ret = -EAGAIN; + ret = -ERESTART; page_list_add(page, list); set_bit(_PGT_pinned, &page->u.inuse.type_info); put_page(page); @@ -1855,9 +1855,9 @@ static int relinquish_memory( if ( x & PGT_partial ) put_page(page); put_page(page); - ret = -EAGAIN; + ret = -ERESTART; goto out; - case -EAGAIN: + case -ERESTART: page_list_add(page, list); page->u.inuse.type_info |= PGT_partial; if ( x & PGT_partial ) @@ -1881,7 +1881,7 @@ static int relinquish_memory( if ( hypercall_preempt_check() ) { - ret = -EAGAIN; + ret = -ERESTART; goto out; } } diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index b69f164c16..d2190be19e 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4449,7 +4449,7 @@ static int hvmop_flush_tlb_all(void) /* Avoid deadlock if more than one vcpu tries this at the same time. */ if ( !spin_trylock(&d->hypercall_deadlock_mutex) ) - return -EAGAIN; + return -ERESTART; /* Pause all other vcpus. */ for_each_vcpu ( d, v ) @@ -4557,7 +4557,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) * All foreign updates to guest state must synchronise on * the domctl_lock. */ - rc = -EAGAIN; + rc = -ERESTART; if ( !domctl_lock_acquire() ) break; @@ -4819,7 +4819,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( a.nr > ++start_iter && !(start_iter & HVMOP_op_mask) && hypercall_preempt_check() ) { - rc = -EAGAIN; + rc = -ERESTART; break; } } @@ -4919,13 +4919,13 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) { put_gfn(d, pfn); p2m_mem_paging_populate(d, pfn); - rc = -EINVAL; /* XXX EAGAIN */ + rc = -EAGAIN; goto param_fail4; } if ( p2m_is_shared(t) ) { put_gfn(d, pfn); - rc = -EINVAL; /* XXX EAGAIN */ + rc = -EAGAIN; goto param_fail4; } if ( !p2m_is_ram(t) && @@ -4944,7 +4944,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) if ( a.nr > ++start_iter && !(start_iter & HVMOP_op_mask) && hypercall_preempt_check() ) { - rc = -EAGAIN; + rc = -ERESTART; goto param_fail4; } } @@ -5059,7 +5059,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) } } - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { ASSERT(!(start_iter & HVMOP_op_mask)); rc = hypercall_create_continuation(__HYPERVISOR_hvm_op, "lh", diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index d3920582fe..870e4ee354 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1827,7 +1827,7 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content) switch ( wrmsr_hypervisor_regs(msr, msr_content) ) { - case -EAGAIN: + case -ERESTART: result = X86EMUL_RETRY; break; case 0: diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b6c022b21d..d45fb7f352 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2289,7 +2289,7 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content) !is_last_branch_msr(msr) ) switch ( wrmsr_hypervisor_regs(msr, msr_content) ) { - case -EAGAIN: + case -ERESTART: return X86EMUL_RETRY; case 0: case 1: diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 1a8a5e0037..d3459f480c 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1285,7 +1285,7 @@ static int alloc_l2_table(struct page_info *page, unsigned long type, && hypercall_preempt_check() ) { page->nr_validated_ptes = i; - rc = -EAGAIN; + rc = -ERESTART; break; } @@ -1356,7 +1356,7 @@ static int alloc_l3_table(struct page_info *page) (rc = get_page_from_l3e(pl3e[i], pfn, d, partial)) > 0 ) continue; - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { page->nr_validated_ptes = i; page->partial_pte = partial ?: 1; @@ -1365,7 +1365,7 @@ static int alloc_l3_table(struct page_info *page) { page->nr_validated_ptes = i; page->partial_pte = 0; - rc = -EAGAIN; + rc = -ERESTART; } if ( rc < 0 ) break; @@ -1375,7 +1375,7 @@ static int alloc_l3_table(struct page_info *page) if ( rc >= 0 && !create_pae_xen_mappings(d, pl3e) ) rc = -EINVAL; - if ( rc < 0 && rc != -EAGAIN && rc != -EINTR ) + if ( rc < 0 && rc != -ERESTART && rc != -EINTR ) { MEM_LOG("Failure in alloc_l3_table: entry %d", i); if ( i ) @@ -1428,7 +1428,7 @@ static int alloc_l4_table(struct page_info *page) (rc = get_page_from_l4e(pl4e[i], pfn, d, partial)) > 0 ) continue; - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { page->nr_validated_ptes = i; page->partial_pte = partial ?: 1; @@ -1442,7 +1442,7 @@ static int alloc_l4_table(struct page_info *page) page->nr_validated_ptes = i; page->partial_pte = 0; if ( rc == -EINTR ) - rc = -EAGAIN; + rc = -ERESTART; else { if ( current->arch.old_guest_table ) @@ -1500,7 +1500,7 @@ static int free_l2_table(struct page_info *page, int preemptible) preemptible && i && hypercall_preempt_check() ) { page->nr_validated_ptes = i; - err = -EAGAIN; + err = -ERESTART; } } while ( !err && i-- ); @@ -1537,7 +1537,7 @@ static int free_l3_table(struct page_info *page) unmap_domain_page(pl3e); - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { page->nr_validated_ptes = i; page->partial_pte = partial ?: -1; @@ -1546,7 +1546,7 @@ static int free_l3_table(struct page_info *page) { page->nr_validated_ptes = i + 1; page->partial_pte = 0; - rc = -EAGAIN; + rc = -ERESTART; } return rc > 0 ? 0 : rc; } @@ -1567,7 +1567,7 @@ static int free_l4_table(struct page_info *page) partial = 0; } while ( i-- ); - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { page->nr_validated_ptes = i; page->partial_pte = partial ?: -1; @@ -1576,7 +1576,7 @@ static int free_l4_table(struct page_info *page) { page->nr_validated_ptes = i + 1; page->partial_pte = 0; - rc = -EAGAIN; + rc = -ERESTART; } unmap_domain_page(pl4e); @@ -2104,7 +2104,7 @@ static int alloc_page_type(struct page_info *page, unsigned long type, { ASSERT((page->u.inuse.type_info & (PGT_count_mask | PGT_validated)) == 1); - case -EAGAIN: + case -ERESTART: get_page_light(page); page->u.inuse.type_info |= PGT_partial; } @@ -2203,7 +2203,7 @@ static int __put_final_page_type( } else { - BUG_ON(rc != -EAGAIN); + BUG_ON(rc != -ERESTART); wmb(); get_page_light(page); page->u.inuse.type_info |= PGT_partial; @@ -2421,7 +2421,7 @@ int get_page_type(struct page_info *page, unsigned long type) int rc = __get_page_type(page, type, 0); if ( likely(rc == 0) ) return 1; - ASSERT(rc != -EINTR && rc != -EAGAIN); + ASSERT(rc != -EINTR && rc != -ERESTART); return 0; } @@ -2633,8 +2633,8 @@ int put_old_guest_table(struct vcpu *v) switch ( rc = put_page_and_type_preemptible(v->arch.old_guest_table) ) { case -EINTR: - case -EAGAIN: - return -EAGAIN; + case -ERESTART: + return -ERESTART; } v->arch.old_guest_table = NULL; @@ -2722,8 +2722,8 @@ int new_guest_cr3(unsigned long mfn) case 0: break; case -EINTR: - case -EAGAIN: - return -EAGAIN; + case -ERESTART: + return -ERESTART; default: MEM_LOG("Error while installing new compat baseptr %lx", mfn); return rc; @@ -2758,8 +2758,8 @@ int new_guest_cr3(unsigned long mfn) case 0: break; case -EINTR: - case -EAGAIN: - return -EAGAIN; + case -ERESTART: + return -ERESTART; default: MEM_LOG("Error while installing new baseptr %lx", mfn); return rc; @@ -2782,8 +2782,8 @@ int new_guest_cr3(unsigned long mfn) switch ( rc = put_page_and_type_preemptible(page) ) { case -EINTR: - rc = -EAGAIN; - case -EAGAIN: + rc = -ERESTART; + case -ERESTART: curr->arch.old_guest_table = page; break; default: @@ -2896,7 +2896,7 @@ long do_mmuext_op( if ( unlikely(rc) ) { - if ( likely(rc == -EAGAIN) ) + if ( likely(rc == -ERESTART) ) rc = hypercall_create_continuation( __HYPERVISOR_mmuext_op, "hihi", uops, count, pdone, foreigndom); @@ -2937,7 +2937,7 @@ long do_mmuext_op( { if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) ) { - rc = -EAGAIN; + rc = -ERESTART; break; } @@ -2991,8 +2991,8 @@ long do_mmuext_op( if ( unlikely(!okay) ) { if ( rc == -EINTR ) - rc = -EAGAIN; - else if ( rc != -EAGAIN ) + rc = -ERESTART; + else if ( rc != -ERESTART ) MEM_LOG("Error while pinning mfn %lx", page_to_mfn(page)); if ( page != curr->arch.old_guest_table ) put_page(page); @@ -3061,7 +3061,7 @@ long do_mmuext_op( switch ( rc = put_page_and_type_preemptible(page) ) { case -EINTR: - case -EAGAIN: + case -ERESTART: curr->arch.old_guest_table = page; rc = 0; break; @@ -3117,8 +3117,8 @@ long do_mmuext_op( if ( unlikely(!okay) ) { if ( rc == -EINTR ) - rc = -EAGAIN; - else if ( rc != -EAGAIN ) + rc = -ERESTART; + else if ( rc != -ERESTART ) MEM_LOG("Error while installing new mfn %lx", op.arg1.mfn); break; @@ -3137,8 +3137,8 @@ long do_mmuext_op( switch ( rc = put_page_and_type_preemptible(page) ) { case -EINTR: - rc = -EAGAIN; - case -EAGAIN: + rc = -ERESTART; + case -ERESTART: curr->arch.old_guest_table = page; okay = 0; break; @@ -3373,7 +3373,7 @@ long do_mmuext_op( guest_handle_add_offset(uops, 1); } - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { ASSERT(i < count); rc = hypercall_create_continuation( @@ -3430,7 +3430,7 @@ long do_mmu_update( if ( unlikely(rc) ) { - if ( likely(rc == -EAGAIN) ) + if ( likely(rc == -ERESTART) ) rc = hypercall_create_continuation( __HYPERVISOR_mmu_update, "hihi", ureqs, count, pdone, foreigndom); @@ -3484,7 +3484,7 @@ long do_mmu_update( { if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) ) { - rc = -EAGAIN; + rc = -ERESTART; break; } @@ -3614,7 +3614,7 @@ long do_mmu_update( } page_unlock(page); if ( rc == -EINTR ) - rc = -EAGAIN; + rc = -ERESTART; } else if ( get_page_type(page, PGT_writable_page) ) { @@ -3676,7 +3676,7 @@ long do_mmu_update( guest_handle_add_offset(ureqs, 1); } - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { ASSERT(i < count); rc = hypercall_create_continuation( @@ -4830,7 +4830,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) rc = p2m_pod_set_mem_target(d, target.target_pages); } - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) { rc = hypercall_create_continuation( __HYPERVISOR_memory_op, "lh", op, arg); diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 3e627f0d86..178fe688b7 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -1297,7 +1297,7 @@ int relinquish_shared_pages(struct domain *d) if ( hypercall_preempt_check() ) { p2m->next_shared_gfn_to_relinquish = gfn + 1; - rc = -EAGAIN; + rc = -ERESTART; break; } count = 0; diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c index 68db9373c9..bd4c7c8921 100644 --- a/xen/arch/x86/mm/p2m-pod.c +++ b/xen/arch/x86/mm/p2m-pod.c @@ -245,7 +245,7 @@ p2m_pod_set_cache_target(struct p2m_domain *p2m, unsigned long pod_target, int p if ( preemptible && pod_target != p2m->pod.count && hypercall_preempt_check() ) { - ret = -EAGAIN; + ret = -ERESTART; goto out; } } @@ -290,7 +290,7 @@ p2m_pod_set_cache_target(struct p2m_domain *p2m, unsigned long pod_target, int p if ( preemptible && pod_target != p2m->pod.count && hypercall_preempt_check() ) { - ret = -EAGAIN; + ret = -ERESTART; goto out; } } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 40366f15b6..2cb3174b7b 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -653,7 +653,7 @@ int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val) if ( p2m_is_paging(t) ) { p2m_mem_paging_populate(d, gmfn); - return -EAGAIN; + return -ERESTART; } gdprintk(XENLOG_WARNING, @@ -2385,7 +2385,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) { case 0: break; - case -EAGAIN: /* retry after preemption */ + case -ERESTART: /* retry after preemption */ goto skip; default: /* not okay */ goto fail; diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c index e756f54c68..b4be3b3df3 100644 --- a/xen/common/compat/domain.c +++ b/xen/common/compat/domain.c @@ -58,7 +58,7 @@ int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt); domain_unlock(d); - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih", cmd, vcpuid, arg); diff --git a/xen/common/domain.c b/xen/common/domain.c index 4291e299ec..bd46a983aa 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -590,6 +590,8 @@ int domain_kill(struct domain *d) rc = domain_relinquish_resources(d); if ( rc != 0 ) { + if ( rc == -ERESTART ) + rc = -EAGAIN; BUG_ON(rc != -EAGAIN); break; } @@ -1067,7 +1069,7 @@ long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) free_vcpu_guest_context(ctxt); - if ( rc == -EAGAIN ) + if ( rc == -ERESTART ) rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih", cmd, vcpuid, arg); diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 2ba5daa65f..4774277da1 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -342,7 +342,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( guest_handle_is_null(op->u.vcpucontext.ctxt) ) { ret = vcpu_reset(v); - if ( ret == -EAGAIN ) + if ( ret == -ERESTART ) ret = hypercall_create_continuation( __HYPERVISOR_domctl, "h", u_domctl); break; @@ -374,7 +374,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) ret = arch_set_info_guest(v, c); domain_unpause(d); - if ( ret == -EAGAIN ) + if ( ret == -ERESTART ) ret = hypercall_create_continuation( __HYPERVISOR_domctl, "h", u_domctl); } diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 7059adc9b0..d25311794c 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -125,7 +125,7 @@ struct page_info * PGT_partial gets set, and it must be dropped when the flag gets * cleared. This is so that a get() leaving a page in partially * validated state (where the caller would drop the reference acquired - * due to the getting of the type [apparently] failing [-EAGAIN]) + * due to the getting of the type [apparently] failing [-ERESTART]) * would not accidentally result in a page left with zero general * reference count, but non-zero type reference count (possible when * the partial get() is followed immediately by domain destruction).