From: "Fenghua Yu" <fenghua.yu@intel.com>
To: "H Peter Anvin" <hpa@zytor.com>, "Ingo Molnar" <mingo@elte.hu>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Asit K Mallick" <asit.k.mallick@intel.com>,
"Tigran Aivazian" <tigran@aivazian.fsnet.co.uk>,
"Andreas Herrmann" <andreas.herrmann3@amd.com>,
"Borislav Petkov" <borislav.petkov@amd.com>,
"linux-kernel" <linux-kernel@vger.kernel.org>,
"x86" <x86@kernel.org>
Cc: "Fenghua Yu" <fenghua.yu@intel.com>
Subject: [PATCH 02/11] x86/lib/cpio.c: Find cpio data by its file name
Date: Sat, 18 Aug 2012 01:15:20 -0700 [thread overview]
Message-ID: <1345277729-8399-3-git-send-email-fenghua.yu@intel.com> (raw)
In-Reply-To: <1345277729-8399-1-git-send-email-fenghua.yu@intel.com>
From: Fenghua Yu <fenghua.yu@intel.com>
Given a file's name, find its starting point in a cpio formated area. This will
be used to find microcode in combined initrd image. But this function is
generic and could be used in other places.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpio.h | 10 +++
arch/x86/lib/Makefile | 2 +
arch/x86/lib/cpio.c | 179 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+), 0 deletions(-)
create mode 100644 arch/x86/include/asm/cpio.h
create mode 100644 arch/x86/lib/cpio.c
diff --git a/arch/x86/include/asm/cpio.h b/arch/x86/include/asm/cpio.h
new file mode 100644
index 0000000..26a4333
--- /dev/null
+++ b/arch/x86/include/asm/cpio.h
@@ -0,0 +1,10 @@
+#include <stddef.h>
+#include <stdbool.h>
+
+struct cpio_data {
+ void *data;
+ unsigned long size;
+};
+
+extern struct cpio_data
+find_cpio_data(const char *name, const void *data, size_t len);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index b00f678..452a4b5 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -45,3 +45,5 @@ else
lib-y += copy_user_64.o copy_user_nocache_64.o
lib-y += cmpxchg16b_emu.o
endif
+
+obj-y += cpio.o
diff --git a/arch/x86/lib/cpio.c b/arch/x86/lib/cpio.c
new file mode 100644
index 0000000..70ac474
--- /dev/null
+++ b/arch/x86/lib/cpio.c
@@ -0,0 +1,179 @@
+/*
+ * findcpio.c
+ *
+ * Find a specific cpio member; must precede any compressed content.
+ *
+ * Copyright (C) 2012 H Peter Anvin" <hpa@zytor.com>
+ * Fenghua Yu <fenghua.yu@intel.com>
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/bitmap.h>
+#include <linux/signal.h>
+#include <linux/printk.h>
+#include <linux/proc_fs.h>
+#include <linux/security.h>
+#include <linux/ctype.h>
+#include <linux/kmemcheck.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/net.h>
+#include <linux/sysrq.h>
+#include <linux/highuid.h>
+#include <linux/writeback.h>
+#include <linux/ratelimit.h>
+#include <linux/compaction.h>
+#include <linux/hugetlb.h>
+#include <linux/initrd.h>
+#include <linux/key.h>
+#include <linux/times.h>
+#include <linux/limits.h>
+#include <linux/dcache.h>
+#include <linux/dnotify.h>
+#include <linux/syscalls.h>
+#include <asm/cpio.h>
+
+enum cpio_fields {
+ C_MAGIC,
+ C_INO,
+ C_MODE,
+ C_UID,
+ C_GID,
+ C_NLINK,
+ C_MTIME,
+ C_FILESIZE,
+ C_MAJ,
+ C_MIN,
+ C_RMAJ,
+ C_RMIN,
+ C_NAMESIZE,
+ C_CHKSUM,
+ C_NFIELDS
+};
+
+#if defined(__i386__) || defined(__x86_64__)
+static size_t cpio_strlen(const char *name)
+{
+ size_t n = -1;
+
+ asm("repne; scasb"
+ : "+D" (name), "+c" (n)
+ : "a" (0));
+
+ return -2 - n;
+}
+
+static int cpio_memcmp(const void *p1, const void *p2, size_t n)
+{
+ unsigned char rv;
+
+ asm("repe; cmpsb; setne %0"
+ : "=r" (rv), "+S" (p1), "+D" (p2), "+c" (n));
+
+ return rv;
+}
+#else
+static size_t cpio_strlen(const char *name)
+{
+ size_t n = 0;
+
+ while (*name++)
+ n++;
+
+ return n;
+}
+
+static int cpio_memcmp(const void *p1, const void *p2, size_t n)
+{
+ const unsigned char *u1 = p1;
+ const unsigned char *u2 = p2;
+ int d;
+
+ while (n--) {
+ d = *u2++ - *u1++;
+ if (d)
+ return d;
+ }
+ return 0;
+}
+#endif
+
+#define ALIGN4(p) ((void *)(((size_t)p + 3) & ~3))
+
+struct cpio_data find_cpio_data(const char *name, const void *data, size_t len)
+{
+ const size_t cpio_header_len = 8*C_NFIELDS - 2;
+ struct cpio_data cd = { NULL, 0 };
+ const char *p, *dptr, *nptr;
+ unsigned int ch[C_NFIELDS], *chp, v;
+ unsigned char c, x;
+ size_t mynamesize = cpio_strlen(name) + 1;
+ int i, j;
+
+ p = data;
+
+ while (len > cpio_header_len) {
+ if (!*p) {
+ /* All cpio headers need to be 4-byte aligned */
+ p += 4;
+ len -= 4;
+ continue;
+ }
+
+ j = 6; /* The magic field is only 6 characters */
+ chp = ch;
+ for (i = C_NFIELDS; i; i--) {
+ v = 0;
+ while (j--) {
+ v <<= 4;
+ c = *p++;
+
+ x = c - '0';
+ if (x < 10) {
+ v += x;
+ continue;
+ }
+
+ x = (c | 0x20) - 'a';
+ if (x < 6) {
+ v += x + 10;
+ continue;
+ }
+
+ goto quit; /* Invalid hexadecimal */
+ }
+ *chp++ = v;
+ j = 8; /* All other fields are 8 characters */
+ }
+
+ if ((ch[C_MAGIC] - 0x070701) > 1)
+ goto quit; /* Invalid magic */
+
+ len -= cpio_header_len;
+
+ dptr = ALIGN4(p + ch[C_NAMESIZE]);
+ nptr = ALIGN4(dptr + ch[C_FILESIZE]);
+
+ if (nptr > p + len || dptr < p || nptr < dptr)
+ goto quit; /* Buffer overrun */
+
+ if ((ch[C_MODE] & 0170000) == 0100000 &&
+ ch[C_NAMESIZE] == mynamesize &&
+ !cpio_memcmp(p, name, mynamesize)) {
+ cd.data = (void *)dptr;
+ cd.size = ch[C_FILESIZE];
+ return cd; /* Found it! */
+ }
+
+ len -= (nptr - p);
+ p = nptr;
+ }
+
+quit:
+ return cd;
+}
--
1.7.2
next prev parent reply other threads:[~2012-08-18 8:32 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-18 8:15 [PATCH 00/11] x86/microcode: Early load microcode Fenghua Yu
2012-08-18 8:15 ` [PATCH 01/11] Documentation/x86: " Fenghua Yu
2012-08-20 12:26 ` Borislav Petkov
2012-08-18 8:15 ` Fenghua Yu [this message]
2012-08-18 22:12 ` [PATCH 02/11] x86/lib/cpio.c: Find cpio data by its file name Henrique de Moraes Holschuh
2012-08-18 23:23 ` Yu, Fenghua
2012-08-19 4:35 ` Henrique de Moraes Holschuh
2012-08-19 5:15 ` H. Peter Anvin
2012-08-20 13:29 ` Borislav Petkov
2012-08-18 8:15 ` [PATCH 03/11] x86/microcode_intel.h: Define functions and macros for early load ucode Fenghua Yu
2012-08-20 13:47 ` Borislav Petkov
2012-08-18 8:15 ` [PATCH 04/11] x86/microcode_core_early.c: Define interfaces " Fenghua Yu
2012-08-18 22:44 ` Henrique de Moraes Holschuh
2012-08-19 2:38 ` Yu, Fenghua
2012-08-19 4:43 ` Henrique de Moraes Holschuh
2012-08-19 5:24 ` H. Peter Anvin
2012-08-19 16:39 ` Yu, Fenghua
2012-08-20 14:06 ` Borislav Petkov
2012-08-20 20:08 ` H. Peter Anvin
2012-08-20 20:19 ` Borislav Petkov
2012-08-21 20:05 ` Yu, Fenghua
2012-08-21 20:13 ` H. Peter Anvin
2012-08-21 20:48 ` Borislav Petkov
2012-08-21 20:52 ` H. Peter Anvin
2012-08-21 20:52 ` Yu, Fenghua
2012-08-21 20:53 ` H. Peter Anvin
2012-08-21 20:58 ` Yu, Fenghua
2012-08-20 14:04 ` Borislav Petkov
2012-08-18 8:15 ` [PATCH 05/11] x86/microcode_intel_lib.c: Early update ucode on Intel's CPU Fenghua Yu
2012-08-20 15:31 ` Borislav Petkov
2012-08-20 16:24 ` Borislav Petkov
2012-08-18 8:15 ` [PATCH 06/11] x86/microcode_intel_early.c: " Fenghua Yu
2012-08-18 8:15 ` [PATCH 07/11] x86/head_32.S: Early update ucode in 32-bit Fenghua Yu
2012-08-18 8:15 ` [PATCH 08/11] x86/head64.c: Early update ucode in 64-bit Fenghua Yu
2012-08-18 8:15 ` [PATCH 09/11] x86/smpboot.c: Early update ucode on AP Fenghua Yu
2012-08-18 8:15 ` [PATCH 10/11] x86/mm/init.c: Copy ucode from initrd image to memory Fenghua Yu
2012-08-18 8:15 ` [PATCH 11/11] x86/Kconfig: Configurations to enable/disable the feature Fenghua Yu
2012-08-20 21:41 ` Paul Bolle
2012-08-20 15:39 ` [PATCH 00/11] x86/microcode: Early load microcode Borislav Petkov
2012-08-20 15:44 ` Yu, Fenghua
2012-08-20 18:51 ` H. Peter Anvin
2012-08-20 20:04 ` Borislav Petkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345277729-8399-3-git-send-email-fenghua.yu@intel.com \
--to=fenghua.yu@intel.com \
--cc=andreas.herrmann3@amd.com \
--cc=asit.k.mallick@intel.com \
--cc=borislav.petkov@amd.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
--cc=tigran@aivazian.fsnet.co.uk \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome