diff --git a/tools/libs/guest/xg_dom_decompress_unsafe_zstd.c b/tools/libs/guest/xg_dom_decompress_unsafe_zstd.c index 01eafaaaa69d..7cd266444bb1 100644 --- a/tools/libs/guest/xg_dom_decompress_unsafe_zstd.c +++ b/tools/libs/guest/xg_dom_decompress_unsafe_zstd.c @@ -26,13 +26,13 @@ typedef uint64_t __be64; #define __force #define always_inline #define noinline +#define __packed __attribute__((__packed__)) #undef ERROR #define __BYTEORDER_HAS_U64__ #define __TYPES_H__ /* xen/types.h guard */ #include "../../xen/include/xen/byteorder/little_endian.h" -#define __ASM_UNALIGNED_H__ /* asm/unaligned.h guard */ #include "../../xen/include/xen/unaligned.h" #include "../../xen/include/xen/xxhash.h" #include "../../xen/lib/xxhash64.c" diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h index 0a2b16d05d92..3eda0ece1199 100644 --- a/xen/include/xen/unaligned.h +++ b/xen/include/xen/unaligned.h @@ -1,12 +1,4 @@ -/* - * This header can be used by architectures where unaligned accesses work - * without faulting, and at least reasonably efficiently. Other architectures - * will need to have a custom asm/unaligned.h. - */ -#ifndef __ASM_UNALIGNED_H__ -#error "xen/unaligned.h should not be included directly - include asm/unaligned.h instead" -#endif - +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __XEN_UNALIGNED_H__ #define __XEN_UNALIGNED_H__ @@ -15,67 +7,82 @@ #include #endif -#define get_unaligned(p) (*(p)) -#define put_unaligned(val, p) (*(p) = (val)) +/* + * This is the most generic implementation of unaligned accesses + * and should work almost anywhere. + */ + +#define get_unaligned_t(type, ptr) ({ \ + const struct { type x; } __packed *ptr_ = (typeof(ptr_))(ptr); \ + ptr_->x; \ +}) + +#define put_unaligned_t(type, val, ptr) do { \ + struct { type x; } __packed *ptr_ = (typeof(ptr_))(ptr); \ + ptr_->x = val; \ +} while (0) + +#define get_unaligned(ptr) get_unaligned_t(typeof(*(ptr)), ptr) +#define put_unaligned(val, ptr) put_unaligned_t(typeof(*(ptr)), val, ptr) static inline uint16_t get_unaligned_be16(const void *p) { - return be16_to_cpup(p); + return be16_to_cpu(get_unaligned_t(__be16, p)); } static inline void put_unaligned_be16(uint16_t val, void *p) { - *(__force __be16*)p = cpu_to_be16(val); + put_unaligned_t(__be16, cpu_to_be16(val), p); } static inline uint32_t get_unaligned_be32(const void *p) { - return be32_to_cpup(p); + return be32_to_cpu(get_unaligned_t(__be32, p)); } static inline void put_unaligned_be32(uint32_t val, void *p) { - *(__force __be32*)p = cpu_to_be32(val); + put_unaligned_t(__be32, cpu_to_be32(val), p); } static inline uint64_t get_unaligned_be64(const void *p) { - return be64_to_cpup(p); + return be64_to_cpu(get_unaligned_t(__be64, p)); } static inline void put_unaligned_be64(uint64_t val, void *p) { - *(__force __be64*)p = cpu_to_be64(val); + put_unaligned_t(__be64, cpu_to_be64(val), p); } static inline uint16_t get_unaligned_le16(const void *p) { - return le16_to_cpup(p); + return le16_to_cpu(get_unaligned_t(__le16, p)); } static inline void put_unaligned_le16(uint16_t val, void *p) { - *(__force __le16*)p = cpu_to_le16(val); + put_unaligned_t(__le16, cpu_to_le16(val), p); } static inline uint32_t get_unaligned_le32(const void *p) { - return le32_to_cpup(p); + return le32_to_cpu(get_unaligned_t(__le32, p)); } static inline void put_unaligned_le32(uint32_t val, void *p) { - *(__force __le32*)p = cpu_to_le32(val); + put_unaligned_t(__le32, cpu_to_le32(val), p); } static inline uint64_t get_unaligned_le64(const void *p) { - return le64_to_cpup(p); + return le64_to_cpu(get_unaligned_t(__le64, p)); } static inline void put_unaligned_le64(uint64_t val, void *p) { - *(__force __le64*)p = cpu_to_le64(val); + put_unaligned_t(__le64, cpu_to_le64(val), p); } #endif /* __XEN_UNALIGNED_H__ */