From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tamas K Lengyel Subject: [PATCH for-4.5 v8 19/19] tools/tests: Enable xen-access on ARM Date: Tue, 23 Sep 2014 15:14:30 +0200 Message-ID: <1411478070-13836-20-git-send-email-tklengyel@sec.in.tum.de> References: <1411478070-13836-1-git-send-email-tklengyel@sec.in.tum.de> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1411478070-13836-1-git-send-email-tklengyel@sec.in.tum.de> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: ian.campbell@citrix.com, tim@xen.org, julien.grall@linaro.org, ian.jackson@eu.citrix.com, stefano.stabellini@citrix.com, andres@lagarcavilla.org, jbeulich@suse.com, dgdegra@tycho.nsa.gov, Tamas K Lengyel List-Id: xen-devel@lists.xenproject.org Define the ARM specific test_and_set_bit functions and switch to use maximum gpfn as the limit to setting permissions. Also, move HAS_MEM_ACCESS definition into config. Signed-off-by: Tamas K Lengyel --- v6: - Just use xc_domain_maximum_gpfn to get max_gpfn. v5: - Use the new information returned by getdomaininfo, max_gpfn, to set access permissions. On ARM this will include the potential memory hole as well which the hypervisor just loops over. v4: - Take into account multiple guest ram banks on ARM. - Move HAS_MEM_ACCESS definition into config/*.mk and only compile xen-access when it is defined. - Pass CONFIG_X86/CONFIG_ARM flags during compilation in xen-access Makefile. --- tools/tests/xen-access/Makefile | 9 ++++- tools/tests/xen-access/xen-access.c | 79 ++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/tools/tests/xen-access/Makefile b/tools/tests/xen-access/Makefile index 65eef99..5056972 100644 --- a/tools/tests/xen-access/Makefile +++ b/tools/tests/xen-access/Makefile @@ -7,8 +7,13 @@ CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += $(CFLAGS_libxenguest) CFLAGS += $(CFLAGS_xeninclude) -TARGETS-y := -TARGETS-$(CONFIG_X86) += xen-access +CFLAGS-y := +CFLAGS-$(CONFIG_X86) := -DCONFIG_X86 +CFLAGS-$(CONFIG_ARM) := -DCONFIG_ARM +CFLAGS += $(CFLAGS-y) + +TARGETS-y := +TARGETS-$(HAS_MEM_ACCESS) := xen-access TARGETS := $(TARGETS-y) .PHONY: all diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c index 6cb382d..40a7143 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -41,22 +41,16 @@ #include #include -#define DPRINTF(a, b...) fprintf(stderr, a, ## b) -#define ERROR(a, b...) fprintf(stderr, a "\n", ## b) -#define PERROR(a, b...) fprintf(stderr, a ": %s\n", ## b, strerror(errno)) - -/* Spinlock and mem event definitions */ - -#define SPIN_LOCK_UNLOCKED 0 +#ifdef CONFIG_X86 +#define START_PFN 0ULL #define ADDR (*(volatile long *) addr) + /** * test_and_set_bit - Set a bit and return its old value * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. */ static inline int test_and_set_bit(int nr, volatile void *addr) { @@ -69,6 +63,43 @@ static inline int test_and_set_bit(int nr, volatile void *addr) return oldbit; } +#elif CONFIG_ARM + +#include + +#define PAGE_SHIFT 12 +#define START_PFN (GUEST_RAM0_BASE >> PAGE_SHIFT) +#define BITS_PER_WORD 32 +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_WORD)) +#define BIT_WORD(nr) ((nr) / BITS_PER_WORD) + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + */ +static inline int test_and_set_bit(int nr, volatile void *addr) +{ + unsigned int mask = BIT_MASK(nr); + volatile unsigned int *p = + ((volatile unsigned int *)addr) + BIT_WORD(nr); + unsigned int old = *p; + + *p = old | mask; + return (old & mask) != 0; +} + +#endif + +#define DPRINTF(a, b...) fprintf(stderr, a, ## b) +#define ERROR(a, b...) fprintf(stderr, a "\n", ## b) +#define PERROR(a, b...) fprintf(stderr, a ": %s\n", ## b, strerror(errno)) + +/* Spinlock and mem event definitions */ + +#define SPIN_LOCK_UNLOCKED 0 + typedef int spinlock_t; static inline void spin_lock(spinlock_t *lock) @@ -108,7 +139,7 @@ typedef struct mem_event { typedef struct xenaccess { xc_interface *xc_handle; - xc_domaininfo_t *domain_info; + int max_gpfn; mem_event_t mem_event; } xenaccess_t; @@ -212,7 +243,6 @@ int xenaccess_teardown(xc_interface *xch, xenaccess_t *xenaccess) } xenaccess->xc_handle = NULL; - free(xenaccess->domain_info); free(xenaccess); return 0; @@ -293,23 +323,17 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id) (mem_event_sring_t *)xenaccess->mem_event.ring_page, XC_PAGE_SIZE); - /* Get domaininfo */ - xenaccess->domain_info = malloc(sizeof(xc_domaininfo_t)); - if ( xenaccess->domain_info == NULL ) - { - ERROR("Error allocating memory for domain info"); - goto err; - } + /* Get max_gpfn */ + xenaccess->max_gpfn = xc_domain_maximum_gpfn(xenaccess->xc_handle, + xenaccess->mem_event.domain_id); - rc = xc_domain_getinfolist(xenaccess->xc_handle, domain_id, 1, - xenaccess->domain_info); - if ( rc != 1 ) + if ( xenaccess->max_gpfn < 0 ) { - ERROR("Error getting domain info"); + ERROR("Failed to get max gpfn"); goto err; } - DPRINTF("max_pages = %"PRIx64"\n", xenaccess->domain_info->max_pages); + DPRINTF("max_gpfn = %"PRIx32"\n", xenaccess->max_gpfn); return xenaccess; @@ -492,8 +516,9 @@ int main(int argc, char *argv[]) goto exit; } - rc = xc_set_mem_access(xch, domain_id, default_access, 0, - xenaccess->domain_info->max_pages); + rc = xc_set_mem_access(xch, domain_id, default_access, START_PFN, + (xenaccess->max_gpfn - START_PFN) ); + if ( rc < 0 ) { ERROR("Error %d setting all memory to access type %d\n", rc, @@ -520,8 +545,8 @@ int main(int argc, char *argv[]) /* Unregister for every event */ rc = xc_set_mem_access(xch, domain_id, XENMEM_access_rwx, ~0ull, 0); - rc = xc_set_mem_access(xch, domain_id, XENMEM_access_rwx, 0, - xenaccess->domain_info->max_pages); + rc = xc_set_mem_access(xch, domain_id, XENMEM_access_rwx, START_PFN, + (xenaccess->max_gpfn - START_PFN) ); rc = xc_hvm_param_set(xch, domain_id, HVM_PARAM_MEMORY_EVENT_INT3, HVMPME_mode_disabled); shutting_down = 1; -- 2.1.0