return NULL;
 }
 
-static const char *__perf_magic = "PERFFILE";
+/*
+ * magic2 = "PERFILE2"
+ * must be a numerical value to let the endianness
+ * determine the memory layout. That way we are able
+ * to detect endianness when reading the perf.data file
+ * back.
+ *
+ * we check for legacy (PERFFILE) format.
+ */
+static const char *__perf_magic1 = "PERFFILE";
+static const u64 __perf_magic2    = 0x32454c4946524550ULL;
+static const u64 __perf_magic2_sw = 0x50455246494c4532ULL;
 
-#define PERF_MAGIC     (*(u64 *)__perf_magic)
+#define PERF_MAGIC     __perf_magic2
 
 struct perf_file_attr {
        struct perf_event_attr  attr;
        return err;
 }
 
+static int check_magic_endian(u64 *magic, struct perf_file_header *header,
+                             struct perf_header *ph)
+{
+       int ret;
+
+       /* check for legacy format */
+       ret = memcmp(magic, __perf_magic1, sizeof(*magic));
+       if (ret == 0) {
+               pr_debug("legacy perf.data format\n");
+               if (!header)
+                       return -1;
+
+               if (header->attr_size != sizeof(struct perf_file_attr)) {
+                       u64 attr_size = bswap_64(header->attr_size);
+
+                       if (attr_size != sizeof(struct perf_file_attr))
+                               return -1;
+
+                       ph->needs_swap = true;
+               }
+               return 0;
+       }
+
+       /* check magic number with same endianness */
+       if (*magic == __perf_magic2)
+               return 0;
+
+       /* check magic number but opposite endianness */
+       if (*magic != __perf_magic2_sw)
+               return -1;
+
+       ph->needs_swap = true;
+
+       return 0;
+}
+
 int perf_file_header__read(struct perf_file_header *header,
                           struct perf_header *ph, int fd)
 {
+       int ret;
+
        lseek(fd, 0, SEEK_SET);
 
-       if (readn(fd, header, sizeof(*header)) <= 0 ||
-           memcmp(&header->magic, __perf_magic, sizeof(header->magic)))
+       ret = readn(fd, header, sizeof(*header));
+       if (ret <= 0)
                return -1;
 
-       if (header->attr_size != sizeof(struct perf_file_attr)) {
-               u64 attr_size = bswap_64(header->attr_size);
-
-               if (attr_size != sizeof(struct perf_file_attr))
-                       return -1;
+       if (check_magic_endian(&header->magic, header, ph) < 0)
+               return -1;
 
+       if (ph->needs_swap) {
                mem_bswap_64(header, offsetof(struct perf_file_header,
-                                           adds_features));
-               ph->needs_swap = true;
+                            adds_features));
        }
 
        if (header->size != sizeof(*header)) {
                                       struct perf_header *ph, int fd,
                                       bool repipe)
 {
-       if (readn(fd, header, sizeof(*header)) <= 0 ||
-           memcmp(&header->magic, __perf_magic, sizeof(header->magic)))
+       int ret;
+
+       ret = readn(fd, header, sizeof(*header));
+       if (ret <= 0)
+               return -1;
+
+        if (check_magic_endian(&header->magic, NULL, ph) < 0)
                return -1;
 
        if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0)