diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 4535c57..a699ea6 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -16,7 +16,7 @@ include_HEADERS = \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_classification.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_compiler.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_config.h \
-		  $(top_srcdir)/platform/linux-generic/include/api/odp_coremask.h \
+		  $(top_srcdir)/platform/linux-generic/include/api/odp_cpumask.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_crypto.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_debug.h \
 		  $(top_srcdir)/platform/linux-generic/include/api/odp_hints.h \
@@ -78,7 +78,7 @@ __LIB__libodp_la_SOURCES = \
 			   odp_buffer.c \
 			   odp_buffer_pool.c \
 			   odp_classification.c \
-			   odp_coremask.c \
+			   odp_cpumask.c \
 			   odp_crypto.c \
 			   odp_init.c \
 			   odp_impl.c \
diff --git a/platform/linux-generic/include/api/odp.h b/platform/linux-generic/include/api/odp.h
index b7b1ca9..1cc7ce0 100644
--- a/platform/linux-generic/include/api/odp.h
+++ b/platform/linux-generic/include/api/odp.h
@@ -27,7 +27,7 @@ extern "C" {
 #include <odp_hints.h>
 #include <odp_debug.h>
 #include <odp_byteorder.h>
-#include <odp_coremask.h>
+#include <odp_cpumask.h>
 #include <odp_barrier.h>
 #include <odp_spinlock.h>
 #include <odp_atomic.h>
diff --git a/platform/linux-generic/include/api/odp_coremask.h b/platform/linux-generic/include/api/odp_coremask.h
deleted file mode 100644
index c9331fd..0000000
--- a/platform/linux-generic/include/api/odp_coremask.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-
-/**
- * @file
- *
- * ODP core masks and enumeration
- */
-
-#ifndef ODP_COREMASK_H_
-#define ODP_COREMASK_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-#include <odp_std_types.h>
-
-/** @addtogroup odp_scheduler
- *  Core mask operations.
- *  @{
- */
-
-/** @internal */
-#define ODP_COREMASK_SIZE_U64  1
-
-/**
- * Core mask
- *
- * Don't access directly, use access functions.
- */
-typedef struct odp_coremask_t {
-	uint64_t _u64[ODP_COREMASK_SIZE_U64]; /**< @private Mask*/
-
-} odp_coremask_t;
-
-
-
-/**
- * Add core mask bits from a string
- *
- * @param str    Hexadecimal digits in a string. Core #0 is located
- *               at the least significant bit (0x1).
- * @param mask   Core mask to modify
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_from_str(const char *str, odp_coremask_t *mask);
-
-/**
- * Write core mask as a string of hexadecimal digits
- *
- * The result will be prefixed with 0x and will be in hexadecimal
- *
- * @param str    String for output
- * @param len    Size of string length (incl. ending zero)
- * @param mask   Core mask
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_to_str(char *str, int len, const odp_coremask_t *mask);
-
-
-/**
- * Add core mask bits from a u64 array
- *
- * In the array core #0 is located at the least significant bit
- * of the first word (u64[0] = 0x1).
- *
- * Examples
- * - core 0:  u64[0] = 0x1
- * - core 1:  u64[0] = 0x2
- * - ...
- * - core 63: u64[0] = 0x8000 0000 0000 0000
- * - core 64: u64[0] = 0x0, u64[1] = 0x1
- * - core 65: u64[0] = 0x0, u64[1] = 0x2
- *
- * @param u64    An array of u64 bit words
- * @param num    Number of u64 words in the array
- * @param mask   Core mask to modify
- *
- * @note Supports currently only core indexes upto 63
- */
-void odp_coremask_from_u64(const uint64_t *u64, int num, odp_coremask_t *mask);
-
-/**
- * Clear entire mask
- * @param mask	Core mask to flush with zero value
- */
-static inline void odp_coremask_zero(odp_coremask_t *mask)
-{
-	mask->_u64[0] = 0;
-}
-
-/**
- * Add core to mask
- * @param core  Core number
- * @param mask  add core number in core mask
- */
-void odp_coremask_set(int core, odp_coremask_t *mask);
-
-/**
- * Remove core from mask
- * @param core  Core number
- * @param mask  clear core number from core mask
- */
-void odp_coremask_clr(int core, odp_coremask_t *mask);
-
-/**
- * Test if core is a member of mask
- * @param core  Core number
- * @param mask  Core mask to check if core num set or not
- * @return      non-zero if set otherwise 0
- */
-int odp_coremask_isset(int core, const odp_coremask_t *mask);
-
-/**
- * Count number of cores in mask
- * @param mask  Core mask
- * @return coremask count
- */
-int odp_coremask_count(const odp_coremask_t *mask);
-
-
-
-/**
- * Logical AND over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_and(odp_coremask_t *dest, odp_coremask_t *src1,
-				    odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] & src2->_u64[0];
-}
-
-/**
- * Logical OR over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_or(odp_coremask_t *dest, odp_coremask_t *src1,
-				   odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] | src2->_u64[0];
-}
-
-/**
- * Logical XOR over two source masks.
- *
- * @param dest    Destination mask, can be one of the source masks
- * @param src1    Source mask 1
- * @param src2    Source mask 2
- */
-static inline void odp_coremask_xor(odp_coremask_t *dest, odp_coremask_t *src1,
-				    odp_coremask_t *src2)
-{
-	dest->_u64[0] = src1->_u64[0] ^ src2->_u64[0];
-}
-
-/**
- * Test if two masks contain the same cores
- */
-static inline int odp_coremask_equal(odp_coremask_t *mask1,
-				     odp_coremask_t *mask2)
-{
-	return (mask1->_u64[0] == mask2->_u64[0]);
-}
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/include/api/odp_cpumask.h b/platform/linux-generic/include/api/odp_cpumask.h
new file mode 100644
index 0000000..e421d4d
--- /dev/null
+++ b/platform/linux-generic/include/api/odp_cpumask.h
@@ -0,0 +1,137 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP CPU masks and enumeration
+ */
+
+#ifndef ODP_CPUMASK_H_
+#define ODP_CPUMASK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <sched.h>
+
+#include <odp_std_types.h>
+
+/** @addtogroup odp_scheduler
+ *  CPU mask operations.
+ *  @{
+ */
+
+/**
+ * CPU mask
+ *
+ * Don't access directly, use access functions.
+ */
+typedef struct odp_cpumask_t {
+	cpu_set_t set; /**< @private Mask*/
+} odp_cpumask_t;
+
+/**
+ * Add CPU mask bits from a string
+ *
+ * @param str    Hexadecimal digits in a string. CPU #0 is located
+ *               at the least significant bit (0x1).
+ * @param mask   CPU mask to modify
+ */
+void odp_cpumask_from_str(const char *str, odp_cpumask_t *mask);
+
+/**
+ * Write CPU mask as a string of hexadecimal digits
+ *
+ * @param str    String for output
+ * @param len    Size of string length (incl. ending zero)
+ * @param mask   CPU mask
+ */
+void odp_cpumask_to_str(char *str, int len, const odp_cpumask_t *mask);
+
+/**
+ * Clear entire mask
+ * @param mask	CPU mask to flush with zero value
+ */
+void odp_cpumask_zero(odp_cpumask_t *mask);
+
+/**
+ * Add cpu to mask
+ * @param cpu   CPU number
+ * @param mask  add cpu number in CPU mask
+ */
+void odp_cpumask_set(int cpu, odp_cpumask_t *mask);
+
+/**
+ * Remove cpu from mask
+ * @param cpu   CPU number
+ * @param mask  clear cpu number from CPU mask
+ */
+void odp_cpumask_clr(int cpu, odp_cpumask_t *mask);
+
+/**
+ * Test if cpu is a member of mask
+ * @param cpu   CPU number
+ * @param mask  CPU mask to check if cpu num set or not
+ * @return      non-zero if set otherwise 0
+ */
+int odp_cpumask_isset(int cpu, const odp_cpumask_t *mask);
+
+/**
+ * Count number of cpus in mask
+ * @param mask  CPU mask
+ * @return cpumask count
+ */
+int odp_cpumask_count(const odp_cpumask_t *mask);
+
+/**
+ * Logical AND over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_and(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		     odp_cpumask_t *src2);
+
+/**
+ * Logical OR over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_or(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		    odp_cpumask_t *src2);
+
+/**
+ * Logical XOR over two source masks.
+ *
+ * @param dest    Destination mask, can be one of the source masks
+ * @param src1    Source mask 1
+ * @param src2    Source mask 2
+ */
+void odp_cpumask_xor(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		     odp_cpumask_t *src2);
+
+/**
+ * Test if two masks contain the same cpus
+ */
+int odp_cpumask_equal(const odp_cpumask_t *mask1,
+		      const odp_cpumask_t *mask2);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/odp_coremask.c b/platform/linux-generic/odp_coremask.c
deleted file mode 100644
index 54cd333..0000000
--- a/platform/linux-generic/odp_coremask.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier:     BSD-3-Clause
- */
-
-#include <odp_coremask.h>
-#include <odp_debug_internal.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#define MAX_CORE_NUM	64
-
-
-void odp_coremask_from_str(const char *str, odp_coremask_t *mask)
-{
-	uint64_t mask_u64;
-
-	if (strlen(str) > 18) {
-		/* more than 64 bits */
-		return;
-	}
-
-	mask_u64 = strtoull(str, NULL, 16);
-
-	odp_coremask_from_u64(&mask_u64, 1, mask);
-}
-
-
-void odp_coremask_to_str(char *str, int len, const odp_coremask_t *mask)
-{
-	int ret;
-
-	ret = snprintf(str, len, "0x%"PRIx64"", mask->_u64[0]);
-
-	if (ret >= 0 && ret < len) {
-		/* force trailing zero */
-		str[len-1] = '\0';
-	}
-}
-
-
-void odp_coremask_from_u64(const uint64_t *u64, int num, odp_coremask_t *mask)
-{
-	int i;
-
-	if (num > ODP_COREMASK_SIZE_U64) {
-		/* force max size */
-		num = ODP_COREMASK_SIZE_U64;
-	}
-
-	for (i = 0; i < num; i++)
-		mask->_u64[0] |= u64[i];
-}
-
-void odp_coremask_set(int core, odp_coremask_t *mask)
-{
-	/* should not be more than 63
-	 * core no. should be from 0..63= 64bit
-	 */
-	if (core >= MAX_CORE_NUM) {
-		ODP_ERR("invalid core count\n");
-		return;
-	}
-
-	mask->_u64[0] |=  (1ULL << core);
-}
-
-void odp_coremask_clr(int core, odp_coremask_t *mask)
-{
-	/* should not be more than 63
-	 * core no. should be from 0..63= 64bit
-	 */
-	if (core >= MAX_CORE_NUM) {
-		ODP_ERR("invalid core count\n");
-		return;
-	}
-
-	mask->_u64[0] &= ~(1ULL << core);
-}
-
-
-int odp_coremask_isset(int core, const odp_coremask_t *mask)
-{
-	/* should not be more than 63
-	 * core no. should be from 0..63= 64bit
-	 */
-	if (core >= MAX_CORE_NUM) {
-		ODP_ERR("invalid core count\n");
-		return -1;
-	}
-
-	return (mask->_u64[0] >> core) & 1;
-}
-
-int odp_coremask_count(const odp_coremask_t *mask)
-{
-	uint64_t coremask = mask->_u64[0];
-	int cnt = 0;
-
-	while (coremask != 0) {
-		coremask >>= 1;
-		if (coremask & 1)
-			cnt++;
-	}
-
-	return cnt;
-}
diff --git a/platform/linux-generic/odp_cpumask.c b/platform/linux-generic/odp_cpumask.c
new file mode 100644
index 0000000..1f9d73b
--- /dev/null
+++ b/platform/linux-generic/odp_cpumask.c
@@ -0,0 +1,175 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+
+#include <odp_cpumask.h>
+#include <odp_debug_internal.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_CORE_NUM	64
+
+
+void odp_cpumask_from_str(const char *str_in, odp_cpumask_t *mask)
+{
+	cpu_set_t cpuset;
+	const char *str = str_in;
+	const char *p;
+	int cpu = 0;
+	int len = strlen(str);
+
+	CPU_ZERO(&cpuset);
+	odp_cpumask_zero(mask);
+
+	/* Strip leading "0x"/"0X" if present and verify length */
+	if ((len >= 2) && ((str[1] == 'x') || (str[1] == 'X'))) {
+		str += 2;
+		len -= 2;
+	}
+	if (!len)
+		return;
+
+	/* Walk string from LSB setting cpu bits */
+	for (p = str + len - 1; (len > 0) && (cpu < CPU_SETSIZE); p--, len--) {
+		char c = *p;
+		int value;
+		int idx;
+
+		/* Convert hex nibble, abort when invalid value found */
+		if ((c >= '0') && (c <= '9'))
+			value = c - '0';
+		else if ((c >= 'A') && (c <= 'F'))
+			value = c - 'A' + 10;
+		else if ((c >= 'a') && (c <= 'f'))
+			value = c - 'a' + 10;
+		else
+			return;
+
+		/* Walk converted nibble and set bits in mask */
+		for (idx = 0; idx < 4; idx++, cpu++)
+			if (value & (1 << idx))
+				CPU_SET(cpu, &cpuset);
+	}
+
+	/* Copy the computed mask */
+	memcpy(&mask->set, &cpuset, sizeof(cpuset));
+}
+
+static int _odp_cpumask_last(const odp_cpumask_t *mask)
+{
+	int cpu;
+
+	for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--)
+		if (odp_cpumask_isset(cpu, mask))
+			return cpu;
+	return -1;
+}
+
+void odp_cpumask_to_str(char *str, int len, const odp_cpumask_t *mask)
+{
+	char *p = str;
+	int cpu = _odp_cpumask_last(mask);
+	int nibbles;
+	int value;
+
+	/* Quickly handle bad string length or empty mask */
+	if (len <= 0)
+		return;
+	*str = 0;
+	if (cpu < 0) {
+		if (len >= 4)
+			strcpy(str, "0x0");
+		return;
+	}
+
+	/* Compute number nibbles in cpumask that have bits set */
+	nibbles = (cpu / 4) + 1;
+
+	/* Verify minimum space (account for "0x" and termination) */
+	if (len < (3 + nibbles))
+		return;
+
+	/* Prefix */
+	*p++ = '0';
+	*p++ = 'x';
+
+	/*
+	 * Now we can scan the cpus down to zero and
+	 * build the string one nibble at a time
+	 */
+	value = 0;
+	do {
+		/* Set bit to go into the current nibble */
+		if (CPU_ISSET(cpu, &mask->set))
+			value |= 1 << (cpu % 4);
+
+		/* If we are on a nibble boundary flush value to string */
+		if (0 == (cpu % 4)) {
+			if (value < 0xA)
+				*p++ = '0' + value;
+			else
+				*p++ = 'A' + value - 0xA;
+			value = 0;
+		}
+	} while (cpu--);
+
+	/* Terminate the string */
+	*p++ = 0;
+}
+
+void odp_cpumask_zero(odp_cpumask_t *mask)
+{
+	CPU_ZERO(&mask->set);
+}
+
+void odp_cpumask_set(int cpu, odp_cpumask_t *mask)
+{
+	CPU_SET(cpu, &mask->set);
+}
+
+void odp_cpumask_clr(int cpu, odp_cpumask_t *mask)
+{
+	CPU_CLR(cpu, &mask->set);
+}
+
+int odp_cpumask_isset(int cpu, const odp_cpumask_t *mask)
+{
+	return CPU_ISSET(cpu, &mask->set);
+}
+
+int odp_cpumask_count(const odp_cpumask_t *mask)
+{
+	return CPU_COUNT(&mask->set);
+}
+
+void odp_cpumask_and(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		     odp_cpumask_t *src2)
+{
+	CPU_AND(&dest->set, &src1->set, &src2->set);
+}
+
+void odp_cpumask_or(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		    odp_cpumask_t *src2)
+{
+	CPU_OR(&dest->set, &src1->set, &src2->set);
+}
+
+void odp_cpumask_xor(odp_cpumask_t *dest, odp_cpumask_t *src1,
+		     odp_cpumask_t *src2)
+{
+	CPU_XOR(&dest->set, &src1->set, &src2->set);
+}
+
+int odp_cpumask_equal(const odp_cpumask_t *mask1,
+		      const odp_cpumask_t *mask2)
+{
+	return CPU_EQUAL(&mask1->set, &mask2->set);
+}
diff --git a/test/api_test/odp_common.c b/test/api_test/odp_common.c
index e585ef5..7449a52 100644
--- a/test/api_test/odp_common.c
+++ b/test/api_test/odp_common.c
@@ -29,15 +29,15 @@ __thread test_shared_data_t *test_shared_data;	    /**< pointer to shared data *
  */
 void odp_print_system_info(void)
 {
-	odp_coremask_t coremask;
+	odp_cpumask_t cpumask;
 	char str[32];
 
 	memset(str, 1, sizeof(str));
 
-	odp_coremask_zero(&coremask);
+	odp_cpumask_zero(&cpumask);
 
-	odp_coremask_from_str("0x1", &coremask);
-	odp_coremask_to_str(str, sizeof(str), &coremask);
+	odp_cpumask_from_str("0x1", &cpumask);
+	odp_cpumask_to_str(str, sizeof(str), &cpumask);
 
 	printf("\n");
 	printf("ODP system info\n");
