From ed48c2c71c85b00b4ed5af7acce98a7afd08523f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:24:49 +0200 Subject: [PATCH 1/8] gnttab: eliminate several explicit version checks By having nr_grant_entries() return zero when the grant table version is still unset we can reduce the number of error paths and at once fix grant_map_exists() running into the being removed ASSERT() when called for a page owned by a domain not having its grant table set up yet. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/common/grant_table.c | 51 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index e134f13dbe..829456265d 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -344,11 +344,15 @@ get_maptrack_handle( /* Number of grant table entries. Caller must hold d's grant table lock. */ static unsigned int nr_grant_entries(struct grant_table *gt) { - ASSERT(gt->gt_version != 0); - if (gt->gt_version == 1) + switch ( gt->gt_version ) + { + case 1: return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v1_t); - else + case 2: return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_v2_t); + } + + return 0; } static int _set_status_v1(domid_t domid, @@ -668,10 +672,6 @@ __gnttab_map_grant_ref( rgt = rd->grant_table; read_lock(&rgt->lock); - if ( rgt->gt_version == 0 ) - PIN_FAIL(unlock_out, GNTST_general_error, - "remote grant table not yet set up\n"); - /* Bounds check on the grant ref */ if ( unlikely(op->ref >= nr_grant_entries(rgt))) PIN_FAIL(unlock_out, GNTST_bad_gntref, "Bad ref (%d).\n", op->ref); @@ -1570,14 +1570,6 @@ gnttab_prepare_for_transfer( read_lock(&rgt->lock); - if ( rgt->gt_version == 0 ) - { - gdprintk(XENLOG_INFO, - "Grant table not ready for transfer to domain(%d).\n", - rd->domain_id); - goto fail; - } - if ( unlikely(ref >= nr_grant_entries(rgt)) ) { gdprintk(XENLOG_INFO, @@ -1977,10 +1969,6 @@ __acquire_grant_for_copy( read_lock(&rgt->lock); - if ( rgt->gt_version == 0 ) - PIN_FAIL(gt_unlock_out, GNTST_general_error, - "remote grant table not ready\n"); - if ( unlikely(gref >= nr_grant_entries(rgt)) ) PIN_FAIL(gt_unlock_out, GNTST_bad_gntref, "Bad grant reference %ld\n", gref); @@ -2482,19 +2470,15 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop) change the version number, except for the first 8 entries which are allowed to be in use (xenstore/xenconsole keeps them mapped). (You need to change the version number for e.g. kexec.) */ - if ( gt->gt_version != 0 ) + for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ ) { - for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ ) + if ( read_atomic(&_active_entry(gt, i).pin) != 0 ) { - if ( read_atomic(&_active_entry(gt, i).pin) != 0 ) - { - gdprintk(XENLOG_WARNING, - "tried to change grant table version from %d to %d, but some grant entries still in use\n", - gt->gt_version, - op.version); - res = -EBUSY; - goto out_unlock; - } + gdprintk(XENLOG_WARNING, + "tried to change grant table version from %u to %u, but some grant entries still in use\n", + gt->gt_version, op.version); + res = -EBUSY; + goto out_unlock; } } @@ -2679,9 +2663,6 @@ __gnttab_swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b) write_lock(>->lock); - if ( gt->gt_version == 0 ) - PIN_FAIL(out, GNTST_general_error, "grant table not yet set up\n"); - /* Bounds check on the grant refs */ if ( unlikely(ref_a >= nr_grant_entries(d->grant_table))) PIN_FAIL(out, GNTST_bad_gntref, "Bad ref-a (%d).\n", ref_a); @@ -3264,9 +3245,6 @@ static void gnttab_usage_print(struct domain *rd) read_lock(>->lock); - if ( gt->gt_version == 0 ) - goto out; - for ( ref = 0; ref != nr_grant_entries(gt); ref++ ) { struct active_grant_entry *act; @@ -3314,7 +3292,6 @@ static void gnttab_usage_print(struct domain *rd) active_entry_release(act); } - out: read_unlock(>->lock); if ( first ) From 9f90cce7cfc13ef87f2262196f999741e7851450 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:25:35 +0200 Subject: [PATCH 2/8] gnttab: limit mapcount() looping The function doesn't need to return counts in the first place; all its callers are after is whether at least one entry of a certain kind exists. With that there's no point for that loop to continue once the looked for condition was found to be met by one entry. Rename the function to match the changed behavior. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/common/grant_table.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 829456265d..f97539fed6 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -253,7 +253,7 @@ static inline void double_gt_lock(struct grant_table *lgt, struct grant_table *rgt) { /* - * See mapcount() for why the write lock is also required for the + * See mapkind() for why the write lock is also required for the * remote domain. */ if ( lgt < rgt ) @@ -566,14 +566,14 @@ static int grant_map_exists(const struct domain *ld, return -EINVAL; } -static void mapcount( - struct grant_table *lgt, struct domain *rd, unsigned long mfn, - unsigned int *wrc, unsigned int *rdc) +#define MAPKIND_READ 1 +#define MAPKIND_WRITE 2 +static unsigned int mapkind( + struct grant_table *lgt, const struct domain *rd, unsigned long mfn) { struct grant_mapping *map; grant_handle_t handle; - - *wrc = *rdc = 0; + unsigned int kind = 0; /* * Must have the local domain's grant table write lock when @@ -586,15 +586,19 @@ static void mapcount( */ ASSERT(rw_is_write_locked(&rd->grant_table->lock)); - for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) + for ( handle = 0; !(kind & MAPKIND_WRITE) && + handle < lgt->maptrack_limit; handle++ ) { map = &maptrack_entry(lgt, handle); if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) || map->domid != rd->domain_id ) continue; if ( _active_entry(rd->grant_table, map->ref).frame == mfn ) - (map->flags & GNTMAP_readonly) ? (*rdc)++ : (*wrc)++; + kind |= map->flags & GNTMAP_readonly ? + MAPKIND_READ : MAPKIND_WRITE; } + + return kind; } /* @@ -819,24 +823,24 @@ __gnttab_map_grant_ref( need_iommu = gnttab_need_iommu_mapping(ld); if ( need_iommu ) { - unsigned int wrc, rdc; + unsigned int kind; int err = 0; double_gt_lock(lgt, rgt); /* We're not translated, so we know that gmfns and mfns are the same things, so the IOMMU entry is always 1-to-1. */ - mapcount(lgt, rd, frame, &wrc, &rdc); + kind = mapkind(lgt, rd, frame); if ( (act_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) && !(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) ) { - if ( wrc == 0 ) + if ( !(kind & MAPKIND_WRITE) ) err = iommu_map_page(ld, frame, frame, IOMMUF_readable|IOMMUF_writable); } else if ( act_pin && !old_pin ) { - if ( (wrc + rdc) == 0 ) + if ( !kind ) err = iommu_map_page(ld, frame, frame, IOMMUF_readable); } if ( err ) @@ -1050,15 +1054,15 @@ __gnttab_unmap_common( if ( rc == GNTST_okay && gnttab_need_iommu_mapping(ld) ) { - unsigned int wrc, rdc; + unsigned int kind; int err = 0; double_gt_lock(lgt, rgt); - mapcount(lgt, rd, op->frame, &wrc, &rdc); - if ( (wrc + rdc) == 0 ) + kind = mapkind(lgt, rd, op->frame); + if ( !kind ) err = iommu_unmap_page(ld, op->frame); - else if ( wrc == 0 ) + else if ( !(kind & MAPKIND_WRITE) ) err = iommu_map_page(ld, op->frame, op->frame, IOMMUF_readable); double_gt_unlock(lgt, rgt); From f4c73bad0896f8cf6f9d9ca6754f0dda1d00ca03 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:26:03 +0200 Subject: [PATCH 3/8] gnttab: simplify shared entry v1 vs v2 handling In a number of places both v1 and v2 pointers are being obtained when none or just one suffices. Additionally in __acquire_grant_for_copy() the flow of if/else-if can be slightly improved by re-ordering. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/common/grant_table.c | 53 ++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index f97539fed6..951f651e76 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -624,8 +624,6 @@ __gnttab_map_grant_ref( unsigned int cache_flags; struct active_grant_entry *act = NULL; struct grant_mapping *mt; - grant_entry_v1_t *sha1; - grant_entry_v2_t *sha2; grant_entry_header_t *shah; uint16_t *status; bool_t need_iommu; @@ -682,15 +680,7 @@ __gnttab_map_grant_ref( act = active_entry_acquire(rgt, op->ref); shah = shared_entry_header(rgt, op->ref); - if (rgt->gt_version == 1) { - sha1 = &shared_entry_v1(rgt, op->ref); - sha2 = NULL; - status = &shah->flags; - } else { - sha2 = &shared_entry_v2(rgt, op->ref); - sha1 = NULL; - status = &status_entry(rgt, op->ref); - } + status = rgt->gt_version == 1 ? &shah->flags : &status_entry(rgt, op->ref); /* If already pinned, check the active domid and avoid refcnt overflow. */ if ( act->pin && @@ -713,8 +703,10 @@ __gnttab_map_grant_ref( if ( !act->pin ) { unsigned long frame; + unsigned long gfn = rgt->gt_version == 1 ? + shared_entry_v1(rgt, op->ref).frame : + shared_entry_v2(rgt, op->ref).full_page.frame; - unsigned long gfn = sha1 ? sha1->frame : sha2->full_page.frame; rc = __get_paged_frame(gfn, &frame, &pg, !!(op->flags & GNTMAP_readonly), rd); if ( rc != GNTST_okay ) @@ -1954,7 +1946,6 @@ __acquire_grant_for_copy( uint16_t *page_off, uint16_t *length, unsigned allow_transitive) { struct grant_table *rgt = rd->grant_table; - grant_entry_v1_t *sha1; grant_entry_v2_t *sha2; grant_entry_header_t *shah; struct active_grant_entry *act; @@ -1981,13 +1972,11 @@ __acquire_grant_for_copy( shah = shared_entry_header(rgt, gref); if ( rgt->gt_version == 1 ) { - sha1 = &shared_entry_v1(rgt, gref); sha2 = NULL; status = &shah->flags; } else { - sha1 = NULL; sha2 = &shared_entry_v2(rgt, gref); status = &status_entry(rgt, gref); } @@ -2009,7 +1998,19 @@ __acquire_grant_for_copy( td = rd; trans_gref = gref; - if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive ) + if ( !sha2 ) + { + unsigned long gfn = shared_entry_v1(rgt, gref).frame; + + rc = __get_paged_frame(gfn, &grant_frame, page, readonly, rd); + if ( rc != GNTST_okay ) + goto unlock_out_clear; + act->gfn = gfn; + is_sub_page = 0; + trans_page_off = 0; + trans_length = PAGE_SIZE; + } + else if ( (shah->flags & GTF_type_mask) == GTF_transitive ) { if ( !allow_transitive ) PIN_FAIL(unlock_out_clear, GNTST_general_error, @@ -2082,16 +2083,6 @@ __acquire_grant_for_copy( is_sub_page = 1; act->gfn = -1ul; } - else if ( sha1 ) - { - rc = __get_paged_frame(sha1->frame, &grant_frame, page, readonly, rd); - if ( rc != GNTST_okay ) - goto unlock_out_clear; - act->gfn = sha1->frame; - is_sub_page = 0; - trans_page_off = 0; - trans_length = PAGE_SIZE; - } else if ( !(sha2->hdr.flags & GTF_sub_page) ) { rc = __get_paged_frame(sha2->full_page.frame, &grant_frame, page, readonly, rd); @@ -3253,8 +3244,6 @@ static void gnttab_usage_print(struct domain *rd) { struct active_grant_entry *act; struct grant_entry_header *sha; - grant_entry_v1_t *sha1; - grant_entry_v2_t *sha2; uint16_t status; uint64_t frame; @@ -3269,16 +3258,12 @@ static void gnttab_usage_print(struct domain *rd) if ( gt->gt_version == 1 ) { - sha1 = &shared_entry_v1(gt, ref); - sha2 = NULL; status = sha->flags; - frame = sha1->frame; + frame = shared_entry_v1(gt, ref).frame; } else { - sha2 = &shared_entry_v2(gt, ref); - sha1 = NULL; - frame = sha2->full_page.frame; + frame = shared_entry_v2(gt, ref).full_page.frame; status = status_entry(gt, ref); } From 1549a9dac132d00a1e4a011e0c4e6ea5b42d23b8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:26:35 +0200 Subject: [PATCH 4/8] gnttab: simplify page copying/clearing ... by making {copy,clear}_domain_page() available also on other than x86. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/arch/x86/domain_page.c | 18 ------------------ xen/common/grant_table.c | 9 ++------- xen/common/memory.c | 20 ++++++++++++++++++++ xen/include/asm-arm/page.h | 2 ++ 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index 8f3217b5ea..d684b2f57a 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -230,24 +230,6 @@ void unmap_domain_page(const void *ptr) local_irq_restore(flags); } -void clear_domain_page(unsigned long mfn) -{ - void *ptr = map_domain_page(mfn); - - clear_page(ptr); - unmap_domain_page(ptr); -} - -void copy_domain_page(unsigned long dmfn, unsigned long smfn) -{ - const void *src = map_domain_page(smfn); - void *dst = map_domain_page(dmfn); - - copy_page(dst, src); - unmap_domain_page(dst); - unmap_domain_page(src); -} - int mapcache_domain_init(struct domain *d) { struct mapcache_domain *dcache = &d->arch.pv_domain.mapcache; diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 951f651e76..053880343f 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1712,7 +1712,6 @@ gnttab_transfer( if ( (1UL << (max_bitsize - PAGE_SHIFT)) <= mfn ) { struct page_info *new_page; - void *sp, *dp; new_page = alloc_domheap_page(e, MEMF_no_owner | MEMF_bits(max_bitsize)); @@ -1722,11 +1721,7 @@ gnttab_transfer( goto unlock_and_copyback; } - sp = map_domain_page(mfn); - dp = __map_domain_page(new_page); - memcpy(dp, sp, PAGE_SIZE); - unmap_domain_page(dp); - unmap_domain_page(sp); + copy_domain_page(page_to_mfn(new_page), mfn); page->count_info &= ~(PGC_count_mask|PGC_allocated); free_domheap_page(page); @@ -2520,7 +2515,7 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop) /* Make sure there's no crud left over in the table from the old version. */ for ( i = 0; i < nr_grant_frames(gt); i++ ) - memset(gt->shared_raw[i], 0, PAGE_SIZE); + clear_page(gt->shared_raw[i]); /* Restore the first 8 entries (toolstack reserved grants) */ if ( gt->gt_version != 0 && op.version == 1 ) diff --git a/xen/common/memory.c b/xen/common/memory.c index 063a1c5220..c84fcdd5b1 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1170,6 +1170,26 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return rc; } +#ifdef CONFIG_DOMAIN_PAGE +void clear_domain_page(unsigned long mfn) +{ + void *ptr = map_domain_page(mfn); + + clear_page(ptr); + unmap_domain_page(ptr); +} + +void copy_domain_page(unsigned long dmfn, unsigned long smfn) +{ + const void *src = map_domain_page(smfn); + void *dst = map_domain_page(dmfn); + + copy_page(dst, src); + unmap_domain_page(dst); + unmap_domain_page(src); +} +#endif + void destroy_ring_for_helper( void **_va, struct page_info *page) { diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h index 3d894941f6..5ecfd0705e 100644 --- a/xen/include/asm-arm/page.h +++ b/xen/include/asm-arm/page.h @@ -264,6 +264,8 @@ static inline lpae_t mfn_to_xen_entry(unsigned long mfn, unsigned attr) /* Actual cacheline size on the boot CPU. */ extern size_t cacheline_bytes; +#define copy_page(dp, sp) memcpy(dp, sp, PAGE_SIZE) + /* Functions for flushing medium-sized areas. * if 'range' is large enough we might want to use model-specific * full-cache flushes. */ From 213f14511446de8eb6c4756aee505e914a3e3a16 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:28:11 +0200 Subject: [PATCH 5/8] gnttab: fix/adjust gnttab_transfer() - don't update shared entry's frame number for translated domains (as MFNs shouldn't be exposed to such guests) - for v1 grant table format, force copying of the page also when the intended MFN doesn't fit in 32 bits (and the domain isn't translated) - fix an apparent off-by-one error (it's unclear to me why commit 5cc77f9098 ("32-on-64: Fix domain address-size clamping, implement") uses BITS_PER_LONG-1 here, while using BITS_PER_LONG in the two other invocations of domain_clamp_alloc_bitsize()) - adjust comments accompanying the shared entry's frame field Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/common/grant_table.c | 11 ++++++++--- xen/include/public/grant_table.h | 6 ++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 053880343f..51500bf7b7 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1708,7 +1708,8 @@ gnttab_transfer( } max_bitsize = domain_clamp_alloc_bitsize( - e, BITS_PER_LONG+PAGE_SHIFT-1); + e, e->grant_table->gt_version > 1 || paging_mode_translate(e) + ? BITS_PER_LONG + PAGE_SHIFT : 32 + PAGE_SHIFT); if ( (1UL << (max_bitsize - PAGE_SHIFT)) <= mfn ) { struct page_info *new_page; @@ -1806,14 +1807,18 @@ gnttab_transfer( if ( e->grant_table->gt_version == 1 ) { grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref); + guest_physmap_add_page(e, sha->frame, mfn, 0); - sha->frame = mfn; + if ( !paging_mode_translate(e) ) + sha->frame = mfn; } else { grant_entry_v2_t *sha = &shared_entry_v2(e->grant_table, gop.ref); + guest_physmap_add_page(e, sha->full_page.frame, mfn, 0); - sha->full_page.frame = mfn; + if ( !paging_mode_translate(e) ) + sha->full_page.frame = mfn; } smp_wmb(); shared_entry_header(e->grant_table, gop.ref)->flags |= diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h index f516a57544..e9393fdd00 100644 --- a/xen/include/public/grant_table.h +++ b/xen/include/public/grant_table.h @@ -134,8 +134,10 @@ struct grant_entry_v1 { /* The domain being granted foreign privileges. [GST] */ domid_t domid; /* - * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] - * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] + * GTF_permit_access: GFN that @domid is allowed to map and access. [GST] + * GTF_accept_transfer: GFN that @domid is allowed to transfer into. [GST] + * GTF_transfer_completed: MFN whose ownership transferred by @domid + * (non-translated guests only). [XEN] */ uint32_t frame; }; From dc6f500bc6ae6908b93f132733ff9944592be52f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 16 Jun 2015 12:29:18 +0200 Subject: [PATCH 6/8] gnttab: make struct grant_mapping private This documents that no entity outside of gnttab.c actually accesses objects of that type, which is particularly important with the now more fine grained locking in place. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- xen/common/grant_table.c | 10 ++++++++++ xen/include/xen/grant_table.h | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 51500bf7b7..a011276f2b 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -113,6 +113,16 @@ struct gnttab_unmap_common { goto _lbl; \ } while ( 0 ) +/* + * Tracks a mapping of another domain's grant reference. Each domain has a + * table of these, indexes into which are returned as a 'mapping handle'. + */ +struct grant_mapping { + u32 ref; /* grant ref */ + u16 flags; /* 0-4: GNTMAP_* ; 5-15: unused */ + domid_t domid; /* granting domain */ +}; + #define MAPTRACK_PER_PAGE (PAGE_SIZE / sizeof(struct grant_mapping)) #define maptrack_entry(t, e) \ ((t)->maptrack[(e)/MAPTRACK_PER_PAGE][(e)%MAPTRACK_PER_PAGE]) diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index f22ebd0788..9536331c07 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -52,16 +52,6 @@ /* The maximum size of a grant table. */ extern unsigned int max_grant_frames; -/* - * Tracks a mapping of another domain's grant reference. Each domain has a - * table of these, indexes into which are returned as a 'mapping handle'. - */ -struct grant_mapping { - u32 ref; /* grant ref */ - u16 flags; /* 0-4: GNTMAP_* ; 5-15: unused */ - domid_t domid; /* granting domain */ -}; - /* Per-domain grant information. */ struct grant_table { /* From 5cd431f343aba8dc10949cf807a354577f8ee93a Mon Sep 17 00:00:00 2001 From: Don Slutz Date: Tue, 16 Jun 2015 12:29:59 +0200 Subject: [PATCH 7/8] hvmloader: properly parenthesize pci_write* macros Signed-off-by: Don Slutz --- tools/firmware/hvmloader/util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index a70e4aa42b..f99c0f19a8 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -82,9 +82,9 @@ uint32_t pci_read(uint32_t devfn, uint32_t reg, uint32_t len); #define pci_readw(devfn, reg) ((uint16_t)pci_read(devfn, reg, 2)) #define pci_readl(devfn, reg) ((uint32_t)pci_read(devfn, reg, 4)) void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val); -#define pci_writeb(devfn, reg, val) (pci_write(devfn, reg, 1, (uint8_t) val)) -#define pci_writew(devfn, reg, val) (pci_write(devfn, reg, 2, (uint16_t)val)) -#define pci_writel(devfn, reg, val) (pci_write(devfn, reg, 4, (uint32_t)val)) +#define pci_writeb(devfn, reg, val) pci_write(devfn, reg, 1, (uint8_t) (val)) +#define pci_writew(devfn, reg, val) pci_write(devfn, reg, 2, (uint16_t)(val)) +#define pci_writel(devfn, reg, val) pci_write(devfn, reg, 4, (uint32_t)(val)) /* Get a pointer to the shared-info page */ struct shared_info *get_shared_info(void) __attribute__ ((const)); From a622b5ade2bdf79ad95e6088a4041e75253c43f3 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 16 Jun 2015 12:30:16 +0200 Subject: [PATCH 8/8] evtchn: factor out freeing an event channel We're going to want to free an event channel from two places. Factor out the code into a free_evtchn() function. Signed-off-by: David Vrabel --- xen/common/event_channel.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index bf9b2f8ecd..947880f8ff 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -192,6 +192,17 @@ static int get_free_port(struct domain *d) return port; } +static void free_evtchn(struct domain *d, struct evtchn *chn) +{ + /* Clear pending event to avoid unexpected behavior on re-bind. */ + evtchn_port_clear_pending(d, chn); + + /* Reset binding to vcpu0 when the channel is freed. */ + chn->state = ECS_FREE; + chn->notify_vcpu_id = 0; + + xsm_evtchn_close_post(chn); +} static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) { @@ -569,14 +580,7 @@ static long __evtchn_close(struct domain *d1, int port1) BUG(); } - /* Clear pending event to avoid unexpected behavior on re-bind. */ - evtchn_port_clear_pending(d1, chn1); - - /* Reset binding to vcpu0 when the channel is freed. */ - chn1->state = ECS_FREE; - chn1->notify_vcpu_id = 0; - - xsm_evtchn_close_post(chn1); + free_evtchn(d1, chn1); out: if ( d2 != NULL )