[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 3/5] xen/arm: use SYMBOLS_SUBTRACT and SYMBOLS_COMPARE as required
Use SYMBOLS_SUBTRACT and SYMBOLS_COMPARE in cases of comparisons and subtractions of: _start, _end, __init_begin, __init_end, _stext, _etext, __alt_instructions, __alt_instructions_end, __per_cpu_start, __per_cpu_data_end, _splatform, _eplatform, _sdevice, _edevice, _asdevice, _aedevice. as by the C standard [1]. M3CM: Rule-18.2: Subtraction between pointers shall only be applied to pointers that address elements of the same array [1] https://wiki.sei.cmu.edu/confluence/display/c/ARR36-C.+Do+not+subtract+or+compare+two+pointers+that+do+not+refer+to+the+same+array QAVerify: 2761 Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx> CC: JBeulich@xxxxxxxx CC: andrew.cooper3@xxxxxxxxxx --- Changes in v9: - use SYMBOLS_SUBTRACT and SYMBOLS_COMPARE --- xen/arch/arm/alternative.c | 10 +++++++--- xen/arch/arm/arm32/livepatch.c | 14 +++++++++++++- xen/arch/arm/arm64/livepatch.c | 14 +++++++++++++- xen/arch/arm/device.c | 8 +++++--- xen/arch/arm/livepatch.c | 16 ++++++++++++++-- xen/arch/arm/mm.c | 9 +++++---- xen/arch/arm/percpu.c | 7 ++++--- xen/arch/arm/platform.c | 6 ++++-- xen/arch/arm/setup.c | 5 +++-- xen/include/asm-arm/grant_table.h | 3 ++- 10 files changed, 70 insertions(+), 22 deletions(-) diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c index 52ed7ed..2cb66d0 100644 --- a/xen/arch/arm/alternative.c +++ b/xen/arch/arm/alternative.c @@ -131,7 +131,10 @@ static int __apply_alternatives(const struct alt_region *region, printk(XENLOG_INFO "alternatives: Patching with alt table %p -> %p\n", region->begin, region->end); - for ( alt = region->begin; alt < region->end; alt++ ) + /* region->begin and region->end might point to different objects. */ + for ( alt = region->begin; + SYMBOLS_COMPARE(alt, region->end) < 0; + alt++ ) { int nr_inst; @@ -188,7 +191,7 @@ static int __apply_alternatives_multi_stop(void *unused) int ret; struct alt_region region; mfn_t xen_mfn = virt_to_mfn(_start); - paddr_t xen_size = _end - _start; + paddr_t xen_size = SYMBOLS_SUBTRACT(_end, _start); unsigned int xen_order = get_order_from_bytes(xen_size); void *xenmap; @@ -206,7 +209,8 @@ static int __apply_alternatives_multi_stop(void *unused) region.begin = __alt_instructions; region.end = __alt_instructions_end; - ret = __apply_alternatives(®ion, xenmap - (void *)_start); + ret = __apply_alternatives(®ion, + SYMBOLS_SUBTRACT(xenmap, _start)); /* The patching is not expected to fail during boot. */ BUG_ON(ret != 0); diff --git a/xen/arch/arm/arm32/livepatch.c b/xen/arch/arm/arm32/livepatch.c index 41378a5..03ae84b 100644 --- a/xen/arch/arm/arm32/livepatch.c +++ b/xen/arch/arm/arm32/livepatch.c @@ -56,7 +56,19 @@ void arch_livepatch_apply(struct livepatch_func *func) else insn = 0xe1a00000; /* mov r0, r0 */ - new_ptr = func->old_addr - (void *)_start + vmap_of_xen_text; + /* + * We need to calculate the offset of the address from _start, and + * apply that to our own map, to find where we have this mapped. + * Doing these kind of games directly with pointers is contrary to + * the C rules for what pointers may be compared and computed. So + * we do the offset calculation with integers, which is always + * legal. The subsequent addition of the offset to the + * vmap_of_xen_text pointer is legal because the computed pointer is + * indeed a valid part of the object referred to by vmap_of_xen_text + * - namely, the byte array of our mapping of the Xen text. + */ + new_ptr = (((uintptr_t))func->old_addr, - ((uintptr_t))_start) + + vmap_of_xen_text; len = len / sizeof(uint32_t); /* PATCH! */ diff --git a/xen/arch/arm/arm64/livepatch.c b/xen/arch/arm/arm64/livepatch.c index 2247b92..ef362c3 100644 --- a/xen/arch/arm/arm64/livepatch.c +++ b/xen/arch/arm/arm64/livepatch.c @@ -43,7 +43,19 @@ void arch_livepatch_apply(struct livepatch_func *func) /* Verified in livepatch_verify_distance. */ ASSERT(insn != AARCH64_BREAK_FAULT); - new_ptr = func->old_addr - (void *)_start + vmap_of_xen_text; + /* + * We need to calculate the offset of the address from _start, and + * apply that to our own map, to find where we have this mapped. + * Doing these kind of games directly with pointers is contrary to + * the C rules for what pointers may be compared and computed. So + * we do the offset calculation with integers, which is always + * legal. The subsequent addition of the offset to the + * vmap_of_xen_text pointer is legal because the computed pointer is + * indeed a valid part of the object referred to by vmap_of_xen_text + * - namely, the byte array of our mapping of the Xen text. + */ + new_ptr = (((uintptr_t))func->old_addr, - ((uintptr_t))_start) + + vmap_of_xen_text; len = len / sizeof(uint32_t); /* PATCH! */ diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c index 70cd6c1..0f0bb77 100644 --- a/xen/arch/arm/device.c +++ b/xen/arch/arm/device.c @@ -35,7 +35,7 @@ int __init device_init(struct dt_device_node *dev, enum device_class class, if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) ) return -ENODEV; - for ( desc = _sdevice; desc != _edevice; desc++ ) + for ( desc = _sdevice; SYMBOLS_COMPARE(desc, _edevice) != 0; desc++ ) { if ( desc->class != class ) continue; @@ -56,7 +56,9 @@ int __init acpi_device_init(enum device_class class, const void *data, int class { const struct acpi_device_desc *desc; - for ( desc = _asdevice; desc != _aedevice; desc++ ) + for ( desc = _asdevice; + SYMBOLS_COMPARE(desc, _aedevice) != 0; + desc++ ) { if ( ( desc->class != class ) || ( desc->class_type != class_type ) ) continue; @@ -75,7 +77,7 @@ enum device_class device_get_class(const struct dt_device_node *dev) ASSERT(dev != NULL); - for ( desc = _sdevice; desc != _edevice; desc++ ) + for ( desc = _sdevice; SYMBOLS_COMPARE(desc, _edevice) != 0; desc++ ) { if ( dt_match_node(desc->dt_match, dev) ) return desc->class; diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c index 279d52c..fb733a4 100644 --- a/xen/arch/arm/livepatch.c +++ b/xen/arch/arm/livepatch.c @@ -27,7 +27,7 @@ int arch_livepatch_quiesce(void) return -EINVAL; text_mfn = virt_to_mfn(_start); - text_order = get_order_from_bytes(_end - _start); + text_order = get_order_from_bytes(SYMBOLS_SUBTRACT(_end, _start)); /* * The text section is read-only. So re-map Xen to be able to patch @@ -78,7 +78,19 @@ void arch_livepatch_revert(const struct livepatch_func *func) uint32_t *new_ptr; unsigned int len; - new_ptr = func->old_addr - (void *)_start + vmap_of_xen_text; + /* + * We need to calculate the offset of the address from _start, and + * apply that to our own map, to find where we have this mapped. + * Doing these kind of games directly with pointers is contrary to + * the C rules for what pointers may be compared and computed. So + * we do the offset calculation with integers, which is always + * legal. The subsequent addition of the offset to the + * vmap_of_xen_text pointer is legal because the computed pointer is + * indeed a valid part of the object referred to by vmap_of_xen_text + * - namely, the byte array of our mapping of the Xen text. + */ + new_ptr = (((uintptr_t))func->old_addr, - ((uintptr_t))_start) + + vmap_of_xen_text; len = livepatch_insn_len(func); memcpy(new_ptr, func->opaque, len); diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 01ae2cc..bde57fd 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -1084,8 +1084,8 @@ static void set_pte_flags_on_range(const char *p, unsigned long l, enum mg mg) ASSERT(!((unsigned long) p & ~PAGE_MASK)); ASSERT(!(l & ~PAGE_MASK)); - for ( i = (p - _start) / PAGE_SIZE; - i < (p + l - _start) / PAGE_SIZE; + for ( i = (SYMBOLS_SUBTRACT(p, _start)) / PAGE_SIZE; + i < ((uintptr_t)p + l - (uintptr_t)_start) / PAGE_SIZE; i++ ) { pte = xen_xenmap[i]; @@ -1122,7 +1122,7 @@ static void set_pte_flags_on_range(const char *p, unsigned long l, enum mg mg) void free_init_memory(void) { paddr_t pa = virt_to_maddr(__init_begin); - unsigned long len = __init_end - __init_begin; + unsigned long len = SYMBOLS_SUBTRACT(__init_end, __init_begin); uint32_t insn; unsigned int i, nr = len / sizeof(insn); uint32_t *p; @@ -1140,7 +1140,8 @@ void free_init_memory(void) set_pte_flags_on_range(__init_begin, len, mg_clear); init_domheap_pages(pa, pa + len); - printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); + printk("Freed %ldkB init memory.\n", + SYMBOLS_SUBTRACT(__init_end, __init_begin) >> 10); } void arch_dump_shared_mem_info(void) diff --git a/xen/arch/arm/percpu.c b/xen/arch/arm/percpu.c index 25442c4..5733a1c 100644 --- a/xen/arch/arm/percpu.c +++ b/xen/arch/arm/percpu.c @@ -6,7 +6,8 @@ unsigned long __per_cpu_offset[NR_CPUS]; #define INVALID_PERCPU_AREA (-(long)__per_cpu_start) -#define PERCPU_ORDER (get_order_from_bytes(__per_cpu_data_end-__per_cpu_start)) +#define PERCPU_ORDER (get_order_from_bytes(SYMBOLS_SUBTRACT(__per_cpu_data_end, \ + __per_cpu_start))) void __init percpu_init_areas(void) { @@ -22,8 +23,8 @@ static int init_percpu_area(unsigned int cpu) return -EBUSY; if ( (p = alloc_xenheap_pages(PERCPU_ORDER, 0)) == NULL ) return -ENOMEM; - memset(p, 0, __per_cpu_data_end - __per_cpu_start); - __per_cpu_offset[cpu] = p - __per_cpu_start; + memset(p, 0, SYMBOLS_SUBTRACT(__per_cpu_data_end, __per_cpu_start)); + __per_cpu_offset[cpu] = SYMBOLS_SUBTRACT(p, __per_cpu_start); return 0; } diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c index 8eb0b6e..664b573 100644 --- a/xen/arch/arm/platform.c +++ b/xen/arch/arm/platform.c @@ -51,14 +51,16 @@ void __init platform_init(void) ASSERT(platform == NULL); /* Looking for the platform description */ - for ( platform = _splatform; platform != _eplatform; platform++ ) + for ( platform = _splatform; + SYMBOLS_COMPARE(platform, _eplatform) != 0; + platform++ ) { if ( platform_is_compatible(platform) ) break; } /* We don't have specific operations for this platform */ - if ( platform == _eplatform ) + if ( SYMBOLS_COMPARE(platform, _eplatform) == 0 ) { /* TODO: dump DT machine compatible node */ printk(XENLOG_INFO "Platform: Generic System\n"); diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 444857a..95fc7aa 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -772,8 +772,9 @@ void __init start_xen(unsigned long boot_phys_offset, /* Register Xen's load address as a boot module. */ xen_bootmodule = add_boot_module(BOOTMOD_XEN, - (paddr_t)(uintptr_t)(_start + boot_phys_offset), - (paddr_t)(uintptr_t)(_end - _start + 1), false); + (paddr_t)(_start + boot_phys_offset), + (paddr_t)(SYMBOLS_SUBTRACT(_end, _start) + 1), + false); BUG_ON(!xen_bootmodule); setup_pagetables(boot_phys_offset); diff --git a/xen/include/asm-arm/grant_table.h b/xen/include/asm-arm/grant_table.h index 816e3c6..fffe934 100644 --- a/xen/include/asm-arm/grant_table.h +++ b/xen/include/asm-arm/grant_table.h @@ -31,7 +31,8 @@ void gnttab_mark_dirty(struct domain *d, mfn_t mfn); * enough space for a large grant table */ #define gnttab_dom0_frames() \ - min_t(unsigned int, opt_max_grant_frames, PFN_DOWN(_etext - _stext)) + min_t(unsigned int, opt_max_grant_frames, \ + PFN_DOWN(SYMBOLS_SUBTRACT(_etext, _stext))) #define gnttab_init_arch(gt) \ ({ \ -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |