Snap for 5271050 from 1a1e0cf369fcc171782d3b20ec044f7616033d4a to pie-vts-release

Change-Id: I22bb9a3cecf9e4a50ecb8fc447a66804870483f2
diff --git a/lib/tst_kernel.c b/lib/tst_kernel.c
index 42d64cb..8edafb8 100644
--- a/lib/tst_kernel.c
+++ b/lib/tst_kernel.c
@@ -15,21 +15,28 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/personality.h>
 #include <sys/utsname.h>
 #include "test.h"
 #include "tst_kernel.h"
 
-int tst_kernel_bits(void)
+static int get_kernel_bits_from_uname(struct utsname *buf)
 {
-	struct utsname buf;
-	int kernel_bits;
-
-	if (uname(&buf)) {
+	if (uname(buf)) {
 		tst_brkm(TBROK | TERRNO, NULL, "uname()");
 		return -1;
 	}
 
-	kernel_bits = strstr(buf.machine, "64") ? 64 : 32;
+	return strstr(buf->machine, "64") ? 64 : 32;
+}
+
+int tst_kernel_bits(void)
+{
+	struct utsname buf;
+	int kernel_bits = get_kernel_bits_from_uname(&buf);
+
+	if (kernel_bits == -1)
+		return -1;
 
 	/*
 	 * ARM64 (aarch64) defines 32-bit compatibility modes as
@@ -40,6 +47,34 @@
 			|| !strcmp(buf.machine, "s390x"))
 		kernel_bits = 64;
 
+#ifdef __ANDROID__
+	/* Android's bionic libc sets the PER_LINUX32 personality for all 32-bit
+	 * programs. This will cause buf.machine to report as i686 even though
+	 * the kernel itself is 64-bit.
+	 */
+	if (!strcmp(buf.machine, "i686") &&
+			(personality(0xffffffff) & PER_MASK) == PER_LINUX32) {
+		/* Set the personality back to the default. */
+		if (personality(PER_LINUX) == -1) {
+			tst_brkm(TBROK | TERRNO, NULL, "personality()");
+			return -1;
+		}
+
+		/* Redo the uname check without the PER_LINUX32 personality to
+		 * determine the actual kernel bits value.
+		 */
+		kernel_bits = get_kernel_bits_from_uname(&buf);
+		if (kernel_bits == -1)
+			return -1;
+
+		/* Set the personality back to PER_LINUX32. */
+		if (personality(PER_LINUX32) == -1) {
+			tst_brkm(TBROK | TERRNO, NULL, "personality()");
+			return -1;
+		}
+	}
+#endif  /* __ANDROID__ */
+
 	tst_resm(TINFO, "uname.machine=%s kernel is %ibit",
 	         buf.machine, kernel_bits);