[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/2] xen/mem: Expose typesafe mfns/gfns/pfns to common code
As the first step of memory management cleanup, introduce the common code to mfn_t, gfn_t and pfn_t. The typesafe construction moves to its own header file, while the declarations and sentinal values are moved to being common. No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Keir Fraser <keir@xxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> CC: Ian Campbell <ian.campbell@xxxxxxxxxx> CC: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> --- Compile tested on all architectures. arm32 is currently using unsigned long for mfns, which is why I made it all common. If this needs to change in the future, the #include <asm/mm.h> can move up and each arch can provide their own TYPE_SAFE()s. --- xen/include/asm-arm/mm.h | 2 -- xen/include/asm-x86/guest_pt.h | 9 -------- xen/include/asm-x86/mm.h | 37 -------------------------------- xen/include/asm-x86/paging.h | 1 - xen/include/xen/mm.h | 28 ++++++++++++++++++++++++ xen/include/xen/typesafe.h | 46 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 49 deletions(-) create mode 100644 xen/include/xen/typesafe.h diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index c0afcec..3601140 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -310,8 +310,6 @@ static inline int relinquish_shared_pages(struct domain *d) return 0; } -#define INVALID_MFN (~0UL) - /* Xen always owns P2M on ARM */ #define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn), (void)(pfn); } while (0) #define mfn_to_gmfn(_d, mfn) (mfn) diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h index d2a8250..cf21617 100644 --- a/xen/include/asm-x86/guest_pt.h +++ b/xen/include/asm-x86/guest_pt.h @@ -33,15 +33,6 @@ #error GUEST_PAGING_LEVELS not defined #endif -/* Type of the guest's frame numbers */ -TYPE_SAFE(unsigned long,gfn) -#define PRI_gfn "05lx" - -#ifndef gfn_t -#define gfn_t /* Grep fodder: gfn_t, _gfn() and gfn_x() are defined above */ -#undef gfn_t -#endif - #define VALID_GFN(m) (m != INVALID_GFN) static inline int diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index d1f95c8..8595c38 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -433,41 +433,6 @@ static inline int get_page_and_type(struct page_info *page, * guest L2 page), etc... */ -/* With this defined, we do some ugly things to force the compiler to - * give us type safety between mfns and gfns and other integers. - * TYPE_SAFE(int foo) defines a foo_t, and _foo() and foo_x() functions - * that translate beween int and foo_t. - * - * It does have some performance cost because the types now have - * a different storage attribute, so may not want it on all the time. */ - -#ifndef NDEBUG -#define TYPE_SAFETY 1 -#endif - -#ifdef TYPE_SAFETY -#define TYPE_SAFE(_type,_name) \ -typedef struct { _type _name; } _name##_t; \ -static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \ -static inline _type _name##_x(_name##_t n) { return n._name; } -#else -#define TYPE_SAFE(_type,_name) \ -typedef _type _name##_t; \ -static inline _name##_t _##_name(_type n) { return n; } \ -static inline _type _name##_x(_name##_t n) { return n; } -#endif - -TYPE_SAFE(unsigned long,mfn); - -#ifndef mfn_t -#define mfn_t /* Grep fodder: mfn_t, _mfn() and mfn_x() are defined above */ -#undef mfn_t -#endif - -/* Macro for printk formats: use as printk("%"PRI_mfn"\n", mfn_x(foo)); */ -#define PRI_mfn "05lx" - - /* * The MPT (machine->physical mapping table) is an array of word-sized * values, indexed on machine frame number. It is expected that guest OSes @@ -510,8 +475,6 @@ static inline int get_page_and_type(struct page_info *page, ? get_gpfn_from_mfn(mfn) \ : (mfn) ) -#define INVALID_MFN (~0UL) - #define compat_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) #define compat_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index c99324c..9c32665 100644 --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -255,7 +255,6 @@ static inline int paging_invlpg(struct vcpu *v, unsigned long va) * pfec[0] is used to determine which kind of access this is when * walking the tables. The caller should set the PFEC_page_present bit * in pfec[0]; in the failure case, that bit will be cleared if appropriate. */ -#define INVALID_GFN (-1UL) unsigned long paging_gva_to_gfn(struct vcpu *v, unsigned long va, uint32_t *pfec); diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index a7563cd..876d370 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -48,6 +48,34 @@ #include <xen/types.h> #include <xen/list.h> #include <xen/spinlock.h> +#include <xen/typesafe.h> + +TYPE_SAFE(unsigned long, mfn); +#define PRI_mfn "05lx" +#define INVALID_MFN (~0UL) + +#ifndef mfn_t +#define mfn_t /* Grep fodder: mfn_t, _mfn() and mfn_x() are defined above */ +#undef mfn_t +#endif + +TYPE_SAFE(unsigned long, gfn); +#define PRI_gfn "05lx" +#define INVALID_GFN (~0UL) + +#ifndef gfn_t +#define gfn_t /* Grep fodder: gfn_t, _gfn() and gfn_x() are defined above */ +#undef gfn_t +#endif + +TYPE_SAFE(unsigned long, pfn); +#define PRI_pfn "05lx" +#define INVALID_PFN (~0UL) + +#ifndef pfn_t +#define pfn_t /* Grep fodder: pfn_t, _pfn() and pfn_x() are defined above */ +#undef pfn_t +#endif struct domain; struct page_info; diff --git a/xen/include/xen/typesafe.h b/xen/include/xen/typesafe.h new file mode 100644 index 0000000..7ecd3b4 --- /dev/null +++ b/xen/include/xen/typesafe.h @@ -0,0 +1,46 @@ +#ifndef __XEN_TYPESAFE_H__ +#define __XEN_TYPESAFE_H__ + +/* + * Compiler games to gain type safety between different logical integers. + * + * TYPE_SAFE($TYPE, $FOO) declares: + * * $FOO_t which encapsulates $TYPE + * * _$FOO() which boxes a $TYPE as a $FOO_t + * * $FOO_x() which unboxes a $FOO_t to $TYPE + * + * This makes a $FOO_t and a $BAR_t incompatible even when the box the same + * $TYPE. + * + * It does have some performance cost because the types now have a different + * storage attribute, so type safety is only enforced in a debug build. + * Non-debug builds degrade to a simple typedef and noops for the functions. + */ + +#ifndef NDEBUG + +#define TYPE_SAFE(_type, _name) \ + typedef struct { _type _name; } _name##_t; \ + static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \ + static inline _type _name##_x(_name##_t n) { return n._name; } + +#else + +#define TYPE_SAFE(_type, _name) \ + typedef _type _name##_t; \ + static inline _name##_t _##_name(_type n) { return n; } \ + static inline _type _name##_x(_name##_t n) { return n; } + +#endif + +#endif /* __XEN_TYPESAFE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |