mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
It's possible for domains to generate unaligned PCI config space accesses
when using ECAM, and hence vPCI should support those at least for the
hardware domain. Such unaligned accesses to the PCI config space have been
reported to come from ACPI logic.
Relax the checking in vpci_access_allowed() to allow such accesses for the
hardware domain, and fix the handling in pci_conf_{read,write}{16,32}() to
fulfill them using MMCFG.
MMCFG regions are identity exposed to the hardware domain, and hence such
unaligned accesses can only come as a result of the host having MMCFG in the
first place, as otherwise MMCFG won't be exposed to the hardware domain
either.
Note that vpci_ecam_{read,write}() already refuse accesses that cross a
device boundary unconditionally.
Reported-by: Jason Andryuk <jason.andryuk@amd.com>
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stewart Hildebrand <stewart.hildebrand@amd.com>
121 lines
3.5 KiB
C
121 lines
3.5 KiB
C
#ifndef __XEN_TOOLS_COMMON_MACROS__
|
|
#define __XEN_TOOLS_COMMON_MACROS__
|
|
|
|
/*
|
|
* Caution:
|
|
*
|
|
* This header must be completely self-contained. There are no external
|
|
* references to variables or functions allowed, as the file might be included
|
|
* for different runtime environments, such as firmware or target and build
|
|
* host programs.
|
|
*/
|
|
|
|
#ifndef BUILD_BUG_ON
|
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
|
#define BUILD_BUG_ON(p) ({ _Static_assert(!(p), "!(" #p ")"); })
|
|
#else
|
|
#define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef ARRAY_SIZE
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
|
#endif
|
|
|
|
#ifndef MIN
|
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
|
#endif
|
|
|
|
#ifndef min
|
|
#define min(x, y) \
|
|
({ \
|
|
const typeof(x) _x = (x); \
|
|
const typeof(y) _y = (y); \
|
|
(void) (&_x == &_y); \
|
|
(_x < _y) ? _x : _y; \
|
|
})
|
|
#endif
|
|
|
|
#ifndef max
|
|
#define max(x, y) \
|
|
({ \
|
|
const typeof(x) _x = (x); \
|
|
const typeof(y) _y = (y); \
|
|
(void)(&_x == &_y); \
|
|
(_x > _y) ? _x : _y; \
|
|
})
|
|
#endif
|
|
|
|
#ifndef min_t
|
|
#define min_t(type, x, y) \
|
|
({ \
|
|
const type _x = (x); \
|
|
const type _y = (y); \
|
|
(_x < _y) ? _x: _y; \
|
|
})
|
|
#endif
|
|
|
|
#ifndef max_t
|
|
#define max_t(type, x, y) \
|
|
({ \
|
|
const type _x = (x); \
|
|
const type _y = (y); \
|
|
(_x > _y) ? _x: _y; \
|
|
})
|
|
#endif
|
|
|
|
#define IS_ALIGNED(val, align) (!((val) & ((align) - 1)))
|
|
|
|
#define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
|
#define ROUNDDOWN(x, a) ((x) & ~((a) - 1))
|
|
|
|
#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m)))
|
|
#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m))
|
|
|
|
#ifndef __must_check
|
|
#define __must_check __attribute__((__warn_unused_result__))
|
|
#endif
|
|
|
|
#ifndef __packed
|
|
#define __packed __attribute__((__packed__))
|
|
#endif
|
|
|
|
#define sizeof_field(type, member) sizeof(((type *)NULL)->member)
|
|
|
|
#define endof_field(type, member) \
|
|
(offsetof(type, member) + sizeof_field(type, member))
|
|
|
|
#define container_of(ptr, type, member) ({ \
|
|
typeof(((type *)0)->member) *mptr__ = (ptr); \
|
|
(type *)((char *)mptr__ - offsetof(type, member)); \
|
|
})
|
|
|
|
#define __STR(...) #__VA_ARGS__
|
|
#define STR(...) __STR(__VA_ARGS__)
|
|
|
|
#define __AC(X, Y) (X ## Y)
|
|
#define _AC(X, Y) __AC(X, Y)
|
|
|
|
/* Size macros. */
|
|
#define MB(_mb) (_AC(_mb, ULL) << 20)
|
|
#define GB(_gb) (_AC(_gb, ULL) << 30)
|
|
|
|
#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)
|
|
|
|
#endif /* __XEN_TOOLS_COMMON_MACROS__ */
|