summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f18
diff options
context:
space:
mode:
authorAlexandre Oliva <lxoliva@fsfla.org>2013-01-05 18:48:45 +0000
committerAlexandre Oliva <lxoliva@fsfla.org>2013-01-05 18:48:45 +0000
commitb733a20157eb03343cd0e20b3e1c119eb3a8d768 (patch)
treededa1050199a88091192f83823c4dd6343094453 /freed-ora/current/f18
parent88569ffc3f146f903103a0ef04fd744b656494bd (diff)
downloadlinux-libre-raptor-b733a20157eb03343cd0e20b3e1c119eb3a8d768.tar.gz
linux-libre-raptor-b733a20157eb03343cd0e20b3e1c119eb3a8d768.zip
3.7.1-2.fc18.gnu
Diffstat (limited to 'freed-ora/current/f18')
-rw-r--r--freed-ora/current/f18/0001-ext4-ext4_inode_info-diet.patch121
-rw-r--r--freed-ora/current/f18/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch97
-rw-r--r--freed-ora/current/f18/0003-ext4-fix-unwritten-counter-leakage.patch112
-rw-r--r--freed-ora/current/f18/0004-ext4-completed_io-locking-cleanup.patch520
-rw-r--r--freed-ora/current/f18/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch144
-rw-r--r--freed-ora/current/f18/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch65
-rw-r--r--freed-ora/current/f18/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch41
-rw-r--r--freed-ora/current/f18/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch61
-rw-r--r--freed-ora/current/f18/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch125
-rw-r--r--freed-ora/current/f18/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch60
-rw-r--r--freed-ora/current/f18/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch176
-rw-r--r--freed-ora/current/f18/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch46
-rw-r--r--freed-ora/current/f18/Bluetooth-Add-support-for-BCM20702A0.patch64
-rw-r--r--freed-ora/current/f18/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch102
-rw-r--r--freed-ora/current/f18/arm-fix_radio_shark.patch15
-rw-r--r--freed-ora/current/f18/arm-highbank-sata-fix.patch599
-rw-r--r--freed-ora/current/f18/block-fix-a-crash-when-block-device-is.patch214
-rw-r--r--freed-ora/current/f18/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch290
-rw-r--r--freed-ora/current/f18/config-arm-generic47
-rw-r--r--freed-ora/current/f18/config-arm-highbank3
-rw-r--r--freed-ora/current/f18/config-arm-imx10
-rw-r--r--freed-ora/current/f18/config-arm-kirkwood5
-rw-r--r--freed-ora/current/f18/config-arm-omap45
-rw-r--r--freed-ora/current/f18/config-arm-tegra1
-rw-r--r--freed-ora/current/f18/config-arm-versatile5
-rw-r--r--freed-ora/current/f18/config-generic120
-rw-r--r--freed-ora/current/f18/config-powerpc-generic8
-rw-r--r--freed-ora/current/f18/config-powerpc645
-rw-r--r--freed-ora/current/f18/config-powerpc64p75
-rw-r--r--freed-ora/current/f18/config-s390x9
-rw-r--r--freed-ora/current/f18/config-sparc64-generic14
-rw-r--r--freed-ora/current/f18/config-x86-32-generic4
-rw-r--r--freed-ora/current/f18/config-x86-generic3
-rw-r--r--freed-ora/current/f18/config-x86_64-generic3
-rwxr-xr-xfreed-ora/current/f18/deblob-3.7 (renamed from freed-ora/current/f18/deblob-3.6)756
-rwxr-xr-xfreed-ora/current/f18/deblob-check501
-rwxr-xr-xfreed-ora/current/f18/deblob-main11
-rw-r--r--freed-ora/current/f18/efivarfs-3.7.patch1630
-rw-r--r--freed-ora/current/f18/exec-do-not-leave-bprm-interp-on-stack.patch12
-rw-r--r--freed-ora/current/f18/exec-use-eloop-for-max-recursion-depth.patch14
-rw-r--r--freed-ora/current/f18/fs-lock-splice_read-and-splice_write-functions.patch74
-rw-r--r--freed-ora/current/f18/handle-efi-roms.patch94
-rw-r--r--freed-ora/current/f18/kernel.spec148
-rw-r--r--freed-ora/current/f18/linux-2.6-serial-460800.patch4
-rw-r--r--freed-ora/current/f18/linux-libre-3.6-gnu.tar.xz.sign7
-rw-r--r--freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xzbin76460 -> 0 bytes
-rw-r--r--freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz.sign7
-rw-r--r--freed-ora/current/f18/linux-libre-3.7-gnu.tar.xz.sign7
-rw-r--r--freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xzbin0 -> 79404 bytes
-rw-r--r--freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz.sign7
-rw-r--r--freed-ora/current/f18/lis3-improve-handling-of-null-rate.patch2
-rw-r--r--freed-ora/current/f18/modsign-upstream-3.7.patch10997
-rw-r--r--freed-ora/current/f18/patch-3.6-gnu-3.6.11-gnu.xz.sign7
-rw-r--r--freed-ora/current/f18/secure-boot-20121212.patch122
-rw-r--r--freed-ora/current/f18/smp_irq_move_cleanup_interrupt.patch50
-rw-r--r--freed-ora/current/f18/sources4
-rw-r--r--freed-ora/current/f18/team-net-next-20120808.patch499
-rw-r--r--freed-ora/current/f18/team-net-next-20121205.patch60
-rw-r--r--freed-ora/current/f18/team-net-next-update-20120927.patch335
-rw-r--r--freed-ora/current/f18/uprobes-upstream-backport.patch1376
-rw-r--r--freed-ora/current/f18/vt-Drop-K_OFF-for-VC_MUTE.patch8
61 files changed, 2927 insertions, 16944 deletions
diff --git a/freed-ora/current/f18/0001-ext4-ext4_inode_info-diet.patch b/freed-ora/current/f18/0001-ext4-ext4_inode_info-diet.patch
deleted file mode 100644
index c7858ecc6..000000000
--- a/freed-ora/current/f18/0001-ext4-ext4_inode_info-diet.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 50b61634cf8d09f9ef334919b859735d381cbe39 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Fri, 28 Sep 2012 23:21:09 -0400
-Subject: [PATCH 01/13] ext4: ext4_inode_info diet
-
-Generic inode has unused i_private pointer which may be used as cur_aio_dio
-storage.
-
-TODO: If cur_aio_dio will be passed as an argument to get_block_t this allow
- to have concurent AIO_DIO requests.
-
-Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit f45ee3a1ea438af96e4fd2c0b16d195e67ef235f)
----
- fs/ext4/ext4.h | 12 ++++++++++--
- fs/ext4/extents.c | 4 ++--
- fs/ext4/inode.c | 6 +++---
- fs/ext4/super.c | 1 -
- 4 files changed, 15 insertions(+), 8 deletions(-)
-
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index c3411d4..80afc8f 100644
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -912,8 +912,6 @@ struct ext4_inode_info {
- struct list_head i_completed_io_list;
- spinlock_t i_completed_io_lock;
- atomic_t i_ioend_count; /* Number of outstanding io_end structs */
-- /* current io_end structure for async DIO write*/
-- ext4_io_end_t *cur_aio_dio;
- atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
-
- spinlock_t i_block_reservation_lock;
-@@ -1332,6 +1330,16 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
- }
- }
-
-+static inline ext4_io_end_t *ext4_inode_aio(struct inode *inode)
-+{
-+ return inode->i_private;
-+}
-+
-+static inline void ext4_inode_aio_set(struct inode *inode, ext4_io_end_t *io)
-+{
-+ inode->i_private = io;
-+}
-+
- /*
- * Inode dynamic state flags
- */
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index aabbb3f..51fbef1 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -3600,7 +3600,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
- {
- int ret = 0;
- int err = 0;
-- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
-+ ext4_io_end_t *io = ext4_inode_aio(inode);
-
- ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical "
- "block %llu, max_blocks %u, flags %x, allocated %u\n",
-@@ -3858,7 +3858,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
- unsigned int allocated = 0, offset = 0;
- unsigned int allocated_clusters = 0;
- struct ext4_allocation_request ar;
-- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
-+ ext4_io_end_t *io = ext4_inode_aio(inode);
- ext4_lblk_t cluster_offset;
-
- ext_debug("blocks %u/%u requested for inode %lu\n",
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index dff171c..acadd2b 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -3054,7 +3054,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
- * hook to the iocb.
- */
- iocb->private = NULL;
-- EXT4_I(inode)->cur_aio_dio = NULL;
-+ ext4_inode_aio_set(inode, NULL);
- if (!is_sync_kiocb(iocb)) {
- ext4_io_end_t *io_end =
- ext4_init_io_end(inode, GFP_NOFS);
-@@ -3071,7 +3071,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
- * is a unwritten extents needs to be converted
- * when IO is completed.
- */
-- EXT4_I(inode)->cur_aio_dio = iocb->private;
-+ ext4_inode_aio_set(inode, io_end);
- }
-
- if (overwrite)
-@@ -3091,7 +3091,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
- NULL,
- DIO_LOCKING);
- if (iocb->private)
-- EXT4_I(inode)->cur_aio_dio = NULL;
-+ ext4_inode_aio_set(inode, NULL);
- /*
- * The io_end structure takes a reference to the inode,
- * that structure needs to be destroyed and the
-diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index c6e0cb3..270e58f 100644
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -956,7 +956,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
- ei->jinode = NULL;
- INIT_LIST_HEAD(&ei->i_completed_io_list);
- spin_lock_init(&ei->i_completed_io_lock);
-- ei->cur_aio_dio = NULL;
- ei->i_sync_tid = 0;
- ei->i_datasync_tid = 0;
- atomic_set(&ei->i_ioend_count, 0);
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch b/freed-ora/current/f18/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
deleted file mode 100644
index cfd13f386..000000000
--- a/freed-ora/current/f18/0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 027d1aa67e32c2c80851105c6d962f3db46eb476 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Fri, 28 Sep 2012 23:24:52 -0400
-Subject: [PATCH 02/13] ext4: give i_aiodio_unwritten a more appropriate name
-
-AIO/DIO prefix is wrong because it account unwritten extents which
-also may be scheduled from buffered write endio
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit e27f41e1b789e60e7d8cc9c81fd93ca49ef31f13)
----
- fs/ext4/ext4.h | 4 ++--
- fs/ext4/file.c | 6 +++---
- fs/ext4/page-io.c | 2 +-
- fs/ext4/super.c | 2 +-
- 4 files changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 80afc8f..28dfd9b 100644
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -912,7 +912,7 @@ struct ext4_inode_info {
- struct list_head i_completed_io_list;
- spinlock_t i_completed_io_lock;
- atomic_t i_ioend_count; /* Number of outstanding io_end structs */
-- atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
-+ atomic_t i_unwritten; /* Nr. of inflight conversions pending */
-
- spinlock_t i_block_reservation_lock;
-
-@@ -1326,7 +1326,7 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
- {
- if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
- io_end->flag |= EXT4_IO_END_UNWRITTEN;
-- atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
-+ atomic_inc(&EXT4_I(inode)->i_unwritten);
- }
- }
-
-diff --git a/fs/ext4/file.c b/fs/ext4/file.c
-index 3b0e3bd..39335bd 100644
---- a/fs/ext4/file.c
-+++ b/fs/ext4/file.c
-@@ -55,11 +55,11 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
- return 0;
- }
-
--static void ext4_aiodio_wait(struct inode *inode)
-+static void ext4_unwritten_wait(struct inode *inode)
- {
- wait_queue_head_t *wq = ext4_ioend_wq(inode);
-
-- wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0));
-+ wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
- }
-
- /*
-@@ -116,7 +116,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
- "performance will be poor.",
- inode->i_ino, current->comm);
- mutex_lock(ext4_aio_mutex(inode));
-- ext4_aiodio_wait(inode);
-+ ext4_unwritten_wait(inode);
- }
-
- BUG_ON(iocb->ki_pos != pos);
-diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
-index dcdeef1..de77e31 100644
---- a/fs/ext4/page-io.c
-+++ b/fs/ext4/page-io.c
-@@ -113,7 +113,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
- if (io->flag & EXT4_IO_END_DIRECT)
- inode_dio_done(inode);
- /* Wake up anyone waiting on unwritten extent conversion */
-- if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
-+ if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
- wake_up_all(ext4_ioend_wq(io->inode));
- return ret;
- }
-diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index 270e58f..1b6b425 100644
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -959,7 +959,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
- ei->i_sync_tid = 0;
- ei->i_datasync_tid = 0;
- atomic_set(&ei->i_ioend_count, 0);
-- atomic_set(&ei->i_aiodio_unwritten, 0);
-+ atomic_set(&ei->i_unwritten, 0);
-
- return &ei->vfs_inode;
- }
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0003-ext4-fix-unwritten-counter-leakage.patch b/freed-ora/current/f18/0003-ext4-fix-unwritten-counter-leakage.patch
deleted file mode 100644
index 2f1d0d813..000000000
--- a/freed-ora/current/f18/0003-ext4-fix-unwritten-counter-leakage.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 6a0e905bb7320571ed5fdd2d5efa3d642630b4f7 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Fri, 28 Sep 2012 23:36:25 -0400
-Subject: [PATCH 03/13] ext4: fix unwritten counter leakage
-
-ext4_set_io_unwritten_flag() will increment i_unwritten counter, so
-once we mark end_io with EXT4_END_IO_UNWRITTEN we have to revert it back
-on error path.
-
- - add missed error checks to prevent counter leakage
- - ext4_end_io_nolock() will clear EXT4_END_IO_UNWRITTEN flag to signal
- that conversion finished.
- - add BUG_ON to ext4_free_end_io() to prevent similar leakage in future.
-
-Visible effect of this bug is that unaligned aio_stress may deadlock
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 82e54229118785badffb4ef5ba4803df25fe007f)
----
- fs/ext4/extents.c | 21 ++++++++++++++-------
- fs/ext4/page-io.c | 6 +++++-
- 2 files changed, 19 insertions(+), 8 deletions(-)
-
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 51fbef1..e04eb4f 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -3615,6 +3615,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
- if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
- ret = ext4_split_unwritten_extents(handle, inode, map,
- path, flags);
-+ if (ret <= 0)
-+ goto out;
- /*
- * Flag the inode(non aio case) or end_io struct (aio case)
- * that this IO needs to conversion to written when IO is
-@@ -3860,6 +3862,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
- struct ext4_allocation_request ar;
- ext4_io_end_t *io = ext4_inode_aio(inode);
- ext4_lblk_t cluster_offset;
-+ int set_unwritten = 0;
-
- ext_debug("blocks %u/%u requested for inode %lu\n",
- map->m_lblk, map->m_len, inode->i_ino);
-@@ -4082,13 +4085,8 @@ got_allocated_blocks:
- * For non asycn direct IO case, flag the inode state
- * that we need to perform conversion when IO is done.
- */
-- if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
-- if (io)
-- ext4_set_io_unwritten_flag(inode, io);
-- else
-- ext4_set_inode_state(inode,
-- EXT4_STATE_DIO_UNWRITTEN);
-- }
-+ if ((flags & EXT4_GET_BLOCKS_PRE_IO))
-+ set_unwritten = 1;
- if (ext4_should_dioread_nolock(inode))
- map->m_flags |= EXT4_MAP_UNINIT;
- }
-@@ -4100,6 +4098,15 @@ got_allocated_blocks:
- if (!err)
- err = ext4_ext_insert_extent(handle, inode, path,
- &newex, flags);
-+
-+ if (!err && set_unwritten) {
-+ if (io)
-+ ext4_set_io_unwritten_flag(inode, io);
-+ else
-+ ext4_set_inode_state(inode,
-+ EXT4_STATE_DIO_UNWRITTEN);
-+ }
-+
- if (err && free_on_err) {
- int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
- EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;
-diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
-index de77e31..9970022 100644
---- a/fs/ext4/page-io.c
-+++ b/fs/ext4/page-io.c
-@@ -71,6 +71,8 @@ void ext4_free_io_end(ext4_io_end_t *io)
- int i;
-
- BUG_ON(!io);
-+ BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
-+
- if (io->page)
- put_page(io->page);
- for (i = 0; i < io->num_io_pages; i++)
-@@ -94,6 +96,8 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
- ssize_t size = io->size;
- int ret = 0;
-
-+ BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
-+
- ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
- "list->prev 0x%p\n",
- io, inode->i_ino, io->list.next, io->list.prev);
-@@ -106,7 +110,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
- "(inode %lu, offset %llu, size %zd, error %d)",
- inode->i_ino, offset, size, ret);
- }
--
-+ io->flag &= ~EXT4_IO_END_UNWRITTEN;
- if (io->iocb)
- aio_complete(io->iocb, io->result, 0);
-
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0004-ext4-completed_io-locking-cleanup.patch b/freed-ora/current/f18/0004-ext4-completed_io-locking-cleanup.patch
deleted file mode 100644
index a358a7952..000000000
--- a/freed-ora/current/f18/0004-ext4-completed_io-locking-cleanup.patch
+++ /dev/null
@@ -1,520 +0,0 @@
-From e23394806df0768ed2dac87484590d2f3a730d55 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sat, 29 Sep 2012 00:14:55 -0400
-Subject: [PATCH 04/13] ext4: completed_io locking cleanup
-
-Current unwritten extent conversion state-machine is very fuzzy.
-- For unknown reason it performs conversion under i_mutex. What for?
- My diagnosis:
- We already protect extent tree with i_data_sem, truncate and punch_hole
- should wait for DIO, so the only data we have to protect is end_io->flags
- modification, but only flush_completed_IO and end_io_work modified this
- flags and we can serialize them via i_completed_io_lock.
-
- Currently all these games with mutex_trylock result in the following deadlock
- truncate: kworker:
- ext4_setattr ext4_end_io_work
- mutex_lock(i_mutex)
- inode_dio_wait(inode) ->BLOCK
- DEADLOCK<- mutex_trylock()
- inode_dio_done()
- #TEST_CASE1_BEGIN
- MNT=/mnt_scrach
- unlink $MNT/file
- fallocate -l $((1024*1024*1024)) $MNT/file
- aio-stress -I 100000 -O -s 100m -n -t 1 -c 10 -o 2 -o 3 $MNT/file
- sleep 2
- truncate -s 0 $MNT/file
- #TEST_CASE1_END
-
-Or use 286's xfstests https://github.com/dmonakhov/xfstests/blob/devel/286
-
-This patch makes state machine simple and clean:
-
-(1) xxx_end_io schedule final extent conversion simply by calling
- ext4_add_complete_io(), which append it to ei->i_completed_io_list
- NOTE1: because of (2A) work should be queued only if
- ->i_completed_io_list was empty, otherwise the work is scheduled already.
-
-(2) ext4_flush_completed_IO is responsible for handling all pending
- end_io from ei->i_completed_io_list
- Flushing sequence consists of following stages:
- A) LOCKED: Atomically drain completed_io_list to local_list
- B) Perform extents conversion
- C) LOCKED: move converted io's to to_free list for final deletion
- This logic depends on context which we was called from.
- D) Final end_io context destruction
- NOTE1: i_mutex is no longer required because end_io->flags modification
- is protected by ei->ext4_complete_io_lock
-
-Full list of changes:
-- Move all completion end_io related routines to page-io.c in order to improve
- logic locality
-- Move open coded logic from various xx_end_xx routines to ext4_add_complete_io()
-- remove EXT4_IO_END_FSYNC
-- Improve SMP scalability by removing useless i_mutex which does not
- protect io->flags anymore.
-- Reduce lock contention on i_completed_io_lock by optimizing list walk.
-- Rename ext4_end_io_nolock to end4_end_io and make it static
-- Check flush completion status to ext4_ext_punch_hole(). Because it is
- not good idea to punch blocks from corrupted inode.
-
-Changes since V3 (in request to Jan's comments):
- Fall back to active flush_completed_IO() approach in order to prevent
- performance issues with nolocked DIO reads.
-Changes since V2:
- Fix use-after-free caused by race truncate vs end_io_work
-
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 28a535f9a0df060569dcc786e5bc2e1de43d7dc7)
----
- fs/ext4/ext4.h | 3 +-
- fs/ext4/extents.c | 4 +-
- fs/ext4/fsync.c | 81 -------------------------
- fs/ext4/indirect.c | 6 +-
- fs/ext4/inode.c | 25 +-------
- fs/ext4/page-io.c | 171 +++++++++++++++++++++++++++++++++++------------------
- 6 files changed, 121 insertions(+), 169 deletions(-)
-
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 28dfd9b..7687d15 100644
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -186,7 +186,6 @@ struct mpage_da_data {
- #define EXT4_IO_END_ERROR 0x0002
- #define EXT4_IO_END_QUEUED 0x0004
- #define EXT4_IO_END_DIRECT 0x0008
--#define EXT4_IO_END_IN_FSYNC 0x0010
-
- struct ext4_io_page {
- struct page *p_page;
-@@ -2408,11 +2407,11 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
-
- /* page-io.c */
- extern int __init ext4_init_pageio(void);
-+extern void ext4_add_complete_io(ext4_io_end_t *io_end);
- extern void ext4_exit_pageio(void);
- extern void ext4_ioend_wait(struct inode *);
- extern void ext4_free_io_end(ext4_io_end_t *io);
- extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
--extern int ext4_end_io_nolock(ext4_io_end_t *io);
- extern void ext4_io_submit(struct ext4_io_submit *io);
- extern int ext4_bio_write_page(struct ext4_io_submit *io,
- struct page *page,
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index e04eb4f..1fbf2ff 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -4815,7 +4815,9 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
- }
-
- /* finish any pending end_io work */
-- ext4_flush_completed_IO(inode);
-+ err = ext4_flush_completed_IO(inode);
-+ if (err)
-+ return err;
-
- credits = ext4_writepage_trans_blocks(inode);
- handle = ext4_journal_start(inode, credits);
-diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
-index 2a1dcea..520b058 100644
---- a/fs/ext4/fsync.c
-+++ b/fs/ext4/fsync.c
-@@ -34,87 +34,6 @@
-
- #include <trace/events/ext4.h>
-
--static void dump_completed_IO(struct inode * inode)
--{
--#ifdef EXT4FS_DEBUG
-- struct list_head *cur, *before, *after;
-- ext4_io_end_t *io, *io0, *io1;
-- unsigned long flags;
--
-- if (list_empty(&EXT4_I(inode)->i_completed_io_list)){
-- ext4_debug("inode %lu completed_io list is empty\n", inode->i_ino);
-- return;
-- }
--
-- ext4_debug("Dump inode %lu completed_io list \n", inode->i_ino);
-- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-- list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list){
-- cur = &io->list;
-- before = cur->prev;
-- io0 = container_of(before, ext4_io_end_t, list);
-- after = cur->next;
-- io1 = container_of(after, ext4_io_end_t, list);
--
-- ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
-- io, inode->i_ino, io0, io1);
-- }
-- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
--#endif
--}
--
--/*
-- * This function is called from ext4_sync_file().
-- *
-- * When IO is completed, the work to convert unwritten extents to
-- * written is queued on workqueue but may not get immediately
-- * scheduled. When fsync is called, we need to ensure the
-- * conversion is complete before fsync returns.
-- * The inode keeps track of a list of pending/completed IO that
-- * might needs to do the conversion. This function walks through
-- * the list and convert the related unwritten extents for completed IO
-- * to written.
-- * The function return the number of pending IOs on success.
-- */
--int ext4_flush_completed_IO(struct inode *inode)
--{
-- ext4_io_end_t *io;
-- struct ext4_inode_info *ei = EXT4_I(inode);
-- unsigned long flags;
-- int ret = 0;
-- int ret2 = 0;
--
-- dump_completed_IO(inode);
-- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-- while (!list_empty(&ei->i_completed_io_list)){
-- io = list_entry(ei->i_completed_io_list.next,
-- ext4_io_end_t, list);
-- list_del_init(&io->list);
-- io->flag |= EXT4_IO_END_IN_FSYNC;
-- /*
-- * Calling ext4_end_io_nolock() to convert completed
-- * IO to written.
-- *
-- * When ext4_sync_file() is called, run_queue() may already
-- * about to flush the work corresponding to this io structure.
-- * It will be upset if it founds the io structure related
-- * to the work-to-be schedule is freed.
-- *
-- * Thus we need to keep the io structure still valid here after
-- * conversion finished. The io structure has a flag to
-- * avoid double converting from both fsync and background work
-- * queue work.
-- */
-- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-- ret = ext4_end_io_nolock(io);
-- if (ret < 0)
-- ret2 = ret;
-- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-- io->flag &= ~EXT4_IO_END_IN_FSYNC;
-- }
-- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-- return (ret2 < 0) ? ret2 : 0;
--}
--
- /*
- * If we're not journaling and this is a just-created file, we have to
- * sync our parent directory (if it was freshly created) since
-diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
-index 830e1b2..61f13e5 100644
---- a/fs/ext4/indirect.c
-+++ b/fs/ext4/indirect.c
-@@ -807,11 +807,9 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
-
- retry:
- if (rw == READ && ext4_should_dioread_nolock(inode)) {
-- if (unlikely(!list_empty(&ei->i_completed_io_list))) {
-- mutex_lock(&inode->i_mutex);
-+ if (unlikely(!list_empty(&ei->i_completed_io_list)))
- ext4_flush_completed_IO(inode);
-- mutex_unlock(&inode->i_mutex);
-- }
-+
- ret = __blockdev_direct_IO(rw, iocb, inode,
- inode->i_sb->s_bdev, iov,
- offset, nr_segs,
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index acadd2b..dd3fd23 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -2879,9 +2879,6 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
- {
- struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
- ext4_io_end_t *io_end = iocb->private;
-- struct workqueue_struct *wq;
-- unsigned long flags;
-- struct ext4_inode_info *ei;
-
- /* if not async direct IO or dio with 0 bytes write, just return */
- if (!io_end || !size)
-@@ -2910,24 +2907,14 @@ out:
- io_end->iocb = iocb;
- io_end->result = ret;
- }
-- wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
--
-- /* Add the io_end to per-inode completed aio dio list*/
-- ei = EXT4_I(io_end->inode);
-- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-- list_add_tail(&io_end->list, &ei->i_completed_io_list);
-- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-
-- /* queue the work to convert unwritten extents to written */
-- queue_work(wq, &io_end->work);
-+ ext4_add_complete_io(io_end);
- }
-
- static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
- {
- ext4_io_end_t *io_end = bh->b_private;
-- struct workqueue_struct *wq;
- struct inode *inode;
-- unsigned long flags;
-
- if (!test_clear_buffer_uninit(bh) || !io_end)
- goto out;
-@@ -2946,15 +2933,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
- */
- inode = io_end->inode;
- ext4_set_io_unwritten_flag(inode, io_end);
--
-- /* Add the io_end to per-inode completed io list*/
-- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
-- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
--
-- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
-- /* queue the work to convert unwritten extents to written */
-- queue_work(wq, &io_end->work);
-+ ext4_add_complete_io(io_end);
- out:
- bh->b_private = NULL;
- bh->b_end_io = NULL;
-diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
-index 9970022..5b24c40 100644
---- a/fs/ext4/page-io.c
-+++ b/fs/ext4/page-io.c
-@@ -71,6 +71,7 @@ void ext4_free_io_end(ext4_io_end_t *io)
- int i;
-
- BUG_ON(!io);
-+ BUG_ON(!list_empty(&io->list));
- BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
-
- if (io->page)
-@@ -83,21 +84,14 @@ void ext4_free_io_end(ext4_io_end_t *io)
- kmem_cache_free(io_end_cachep, io);
- }
-
--/*
-- * check a range of space and convert unwritten extents to written.
-- *
-- * Called with inode->i_mutex; we depend on this when we manipulate
-- * io->flag, since we could otherwise race with ext4_flush_completed_IO()
-- */
--int ext4_end_io_nolock(ext4_io_end_t *io)
-+/* check a range of space and convert unwritten extents to written. */
-+static int ext4_end_io(ext4_io_end_t *io)
- {
- struct inode *inode = io->inode;
- loff_t offset = io->offset;
- ssize_t size = io->size;
- int ret = 0;
-
-- BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
--
- ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
- "list->prev 0x%p\n",
- io, inode->i_ino, io->list.next, io->list.prev);
-@@ -110,7 +104,6 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
- "(inode %lu, offset %llu, size %zd, error %d)",
- inode->i_ino, offset, size, ret);
- }
-- io->flag &= ~EXT4_IO_END_UNWRITTEN;
- if (io->iocb)
- aio_complete(io->iocb, io->result, 0);
-
-@@ -122,51 +115,122 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
- return ret;
- }
-
--/*
-- * work on completed aio dio IO, to convert unwritten extents to extents
-- */
--static void ext4_end_io_work(struct work_struct *work)
-+static void dump_completed_IO(struct inode *inode)
-+{
-+#ifdef EXT4FS_DEBUG
-+ struct list_head *cur, *before, *after;
-+ ext4_io_end_t *io, *io0, *io1;
-+ unsigned long flags;
-+
-+ if (list_empty(&EXT4_I(inode)->i_completed_io_list)) {
-+ ext4_debug("inode %lu completed_io list is empty\n",
-+ inode->i_ino);
-+ return;
-+ }
-+
-+ ext4_debug("Dump inode %lu completed_io list\n", inode->i_ino);
-+ list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list) {
-+ cur = &io->list;
-+ before = cur->prev;
-+ io0 = container_of(before, ext4_io_end_t, list);
-+ after = cur->next;
-+ io1 = container_of(after, ext4_io_end_t, list);
-+
-+ ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
-+ io, inode->i_ino, io0, io1);
-+ }
-+#endif
-+}
-+
-+/* Add the io_end to per-inode completed end_io list. */
-+void ext4_add_complete_io(ext4_io_end_t *io_end)
- {
-- ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
-- struct inode *inode = io->inode;
-- struct ext4_inode_info *ei = EXT4_I(inode);
-- unsigned long flags;
-+ struct ext4_inode_info *ei = EXT4_I(io_end->inode);
-+ struct workqueue_struct *wq;
-+ unsigned long flags;
-+
-+ BUG_ON(!(io_end->flag & EXT4_IO_END_UNWRITTEN));
-+ wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
-
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-- if (io->flag & EXT4_IO_END_IN_FSYNC)
-- goto requeue;
-- if (list_empty(&io->list)) {
-- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-- goto free;
-+ if (list_empty(&ei->i_completed_io_list)) {
-+ io_end->flag |= EXT4_IO_END_QUEUED;
-+ queue_work(wq, &io_end->work);
- }
-+ list_add_tail(&io_end->list, &ei->i_completed_io_list);
-+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-+}
-
-- if (!mutex_trylock(&inode->i_mutex)) {
-- bool was_queued;
--requeue:
-- was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
-- io->flag |= EXT4_IO_END_QUEUED;
-- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-- /*
-- * Requeue the work instead of waiting so that the work
-- * items queued after this can be processed.
-- */
-- queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
-- /*
-- * To prevent the ext4-dio-unwritten thread from keeping
-- * requeueing end_io requests and occupying cpu for too long,
-- * yield the cpu if it sees an end_io request that has already
-- * been requeued.
-- */
-- if (was_queued)
-- yield();
-- return;
-+static int ext4_do_flush_completed_IO(struct inode *inode,
-+ ext4_io_end_t *work_io)
-+{
-+ ext4_io_end_t *io;
-+ struct list_head unwritten, complete, to_free;
-+ unsigned long flags;
-+ struct ext4_inode_info *ei = EXT4_I(inode);
-+ int err, ret = 0;
-+
-+ INIT_LIST_HEAD(&complete);
-+ INIT_LIST_HEAD(&to_free);
-+
-+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-+ dump_completed_IO(inode);
-+ list_replace_init(&ei->i_completed_io_list, &unwritten);
-+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-+
-+ while (!list_empty(&unwritten)) {
-+ io = list_entry(unwritten.next, ext4_io_end_t, list);
-+ BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
-+ list_del_init(&io->list);
-+
-+ err = ext4_end_io(io);
-+ if (unlikely(!ret && err))
-+ ret = err;
-+
-+ list_add_tail(&io->list, &complete);
-+ }
-+ /* It is important to update all flags for all end_io in one shot w/o
-+ * dropping the lock.*/
-+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-+ while (!list_empty(&complete)) {
-+ io = list_entry(complete.next, ext4_io_end_t, list);
-+ io->flag &= ~EXT4_IO_END_UNWRITTEN;
-+ /* end_io context can not be destroyed now because it still
-+ * used by queued worker. Worker thread will destroy it later */
-+ if (io->flag & EXT4_IO_END_QUEUED)
-+ list_del_init(&io->list);
-+ else
-+ list_move(&io->list, &to_free);
-+ }
-+ /* If we are called from worker context, it is time to clear queued
-+ * flag, and destroy it's end_io if it was converted already */
-+ if (work_io) {
-+ work_io->flag &= ~EXT4_IO_END_QUEUED;
-+ if (!(work_io->flag & EXT4_IO_END_UNWRITTEN))
-+ list_add_tail(&work_io->list, &to_free);
- }
-- list_del_init(&io->list);
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-- (void) ext4_end_io_nolock(io);
-- mutex_unlock(&inode->i_mutex);
--free:
-- ext4_free_io_end(io);
-+
-+ while (!list_empty(&to_free)) {
-+ io = list_entry(to_free.next, ext4_io_end_t, list);
-+ list_del_init(&io->list);
-+ ext4_free_io_end(io);
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * work on completed aio dio IO, to convert unwritten extents to extents
-+ */
-+static void ext4_end_io_work(struct work_struct *work)
-+{
-+ ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
-+ ext4_do_flush_completed_IO(io->inode, io);
-+}
-+
-+int ext4_flush_completed_IO(struct inode *inode)
-+{
-+ return ext4_do_flush_completed_IO(inode, NULL);
- }
-
- ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
-@@ -199,9 +263,7 @@ static void buffer_io_error(struct buffer_head *bh)
- static void ext4_end_bio(struct bio *bio, int error)
- {
- ext4_io_end_t *io_end = bio->bi_private;
-- struct workqueue_struct *wq;
- struct inode *inode;
-- unsigned long flags;
- int i;
- sector_t bi_sector = bio->bi_sector;
-
-@@ -259,14 +321,7 @@ static void ext4_end_bio(struct bio *bio, int error)
- return;
- }
-
-- /* Add the io_end to per-inode completed io list*/
-- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
-- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
--
-- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
-- /* queue the work to convert unwritten extents to written */
-- queue_work(wq, &io_end->work);
-+ ext4_add_complete_io(io_end);
- }
-
- void ext4_io_submit(struct ext4_io_submit *io)
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch b/freed-ora/current/f18/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
deleted file mode 100644
index cf53b8dab..000000000
--- a/freed-ora/current/f18/0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 994f567b2e99c82913a279ff438269c771b68a4b Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sat, 29 Sep 2012 00:41:21 -0400
-Subject: [PATCH 05/13] ext4: serialize dio nonlocked reads with defrag
- workers
-
-Inode's block defrag and ext4_change_inode_journal_flag() may
-affect nonlocked DIO reads result, so proper synchronization
-required.
-
-- Add missed inode_dio_wait() calls where appropriate
-- Check inode state under extra i_dio_count reference.
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 17335dcc471199717839b2fa3492ca36f70f1168)
-
-Conflicts:
- fs/ext4/move_extent.c
----
- fs/ext4/ext4.h | 17 +++++++++++++++++
- fs/ext4/indirect.c | 14 ++++++++++++++
- fs/ext4/inode.c | 5 +++++
- fs/ext4/move_extent.c | 8 ++++++++
- 4 files changed, 44 insertions(+)
-
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 7687d15..3e740e9 100644
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -1352,6 +1352,8 @@ enum {
- EXT4_STATE_DIO_UNWRITTEN, /* need convert on dio done*/
- EXT4_STATE_NEWENTRY, /* File just added to dir */
- EXT4_STATE_DELALLOC_RESERVED, /* blks already reserved for delalloc */
-+ EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
-+ nolocking */
- };
-
- #define EXT4_INODE_BIT_FNS(name, field, offset) \
-@@ -2459,6 +2461,21 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
- set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
- }
-
-+/*
-+ * Disable DIO read nolock optimization, so new dioreaders will be forced
-+ * to grab i_mutex
-+ */
-+static inline void ext4_inode_block_unlocked_dio(struct inode *inode)
-+{
-+ ext4_set_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
-+ smp_mb();
-+}
-+static inline void ext4_inode_resume_unlocked_dio(struct inode *inode)
-+{
-+ smp_mb();
-+ ext4_clear_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
-+}
-+
- #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-
- /* For ioend & aio unwritten conversion wait queues */
-diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
-index 61f13e5..8d849da 100644
---- a/fs/ext4/indirect.c
-+++ b/fs/ext4/indirect.c
-@@ -810,11 +810,25 @@ retry:
- if (unlikely(!list_empty(&ei->i_completed_io_list)))
- ext4_flush_completed_IO(inode);
-
-+ /*
-+ * Nolock dioread optimization may be dynamically disabled
-+ * via ext4_inode_block_unlocked_dio(). Check inode's state
-+ * while holding extra i_dio_count ref.
-+ */
-+ atomic_inc(&inode->i_dio_count);
-+ smp_mb();
-+ if (unlikely(ext4_test_inode_state(inode,
-+ EXT4_STATE_DIOREAD_LOCK))) {
-+ inode_dio_done(inode);
-+ goto locked;
-+ }
- ret = __blockdev_direct_IO(rw, iocb, inode,
- inode->i_sb->s_bdev, iov,
- offset, nr_segs,
- ext4_get_block, NULL, NULL, 0);
-+ inode_dio_done(inode);
- } else {
-+locked:
- ret = blockdev_direct_IO(rw, iocb, inode, iov,
- offset, nr_segs, ext4_get_block);
-
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index dd3fd23..2bd7526 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -4706,6 +4706,10 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
- return err;
- }
-
-+ /* Wait for all existing dio workers */
-+ ext4_inode_block_unlocked_dio(inode);
-+ inode_dio_wait(inode);
-+
- jbd2_journal_lock_updates(journal);
-
- /*
-@@ -4725,6 +4729,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
- ext4_set_aops(inode);
-
- jbd2_journal_unlock_updates(journal);
-+ ext4_inode_resume_unlocked_dio(inode);
-
- /* Finally we can mark the inode as dirty. */
-
-diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
-index c5826c6..fd1e32e 100644
---- a/fs/ext4/move_extent.c
-+++ b/fs/ext4/move_extent.c
-@@ -1214,6 +1214,12 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
- /* Protect orig and donor inodes against a truncate */
- mext_inode_double_lock(orig_inode, donor_inode);
-
-+ /* Wait for all existing dio workers */
-+ ext4_inode_block_unlocked_dio(orig_inode);
-+ ext4_inode_block_unlocked_dio(donor_inode);
-+ inode_dio_wait(orig_inode);
-+ inode_dio_wait(donor_inode);
-+
- /* Protect extent tree against block allocations via delalloc */
- double_down_write_data_sem(orig_inode, donor_inode);
- /* Check the filesystem environment whether move_extent can be done */
-@@ -1413,6 +1419,8 @@ out:
- kfree(holecheck_path);
- }
- double_up_write_data_sem(orig_inode, donor_inode);
-+ ext4_inode_resume_unlocked_dio(orig_inode);
-+ ext4_inode_resume_unlocked_dio(donor_inode);
- mext_inode_double_unlock(orig_inode, donor_inode);
-
- return ret;
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch b/freed-ora/current/f18/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
deleted file mode 100644
index bddcc6024..000000000
--- a/freed-ora/current/f18/0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 4c4679fc02744ec3955e88faf5e8b6844fa8cbd3 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sat, 29 Sep 2012 00:55:23 -0400
-Subject: [PATCH 06/13] ext4: serialize unlocked dio reads with truncate
-
-Current serialization will works only for DIO which holds
-i_mutex, but nonlocked DIO following race is possible:
-
-dio_nolock_read_task truncate_task
- ->ext4_setattr()
- ->inode_dio_wait()
-->ext4_ext_direct_IO
- ->ext4_ind_direct_IO
- ->__blockdev_direct_IO
- ->ext4_get_block
- ->truncate_setsize()
- ->ext4_truncate()
- #alloc truncated blocks
- #to other inode
- ->submit_io()
- #INFORMATION LEAK
-
-In order to serialize with unlocked DIO reads we have to
-rearrange wait sequence
-1) update i_size first
-2) if i_size about to be reduced wait for outstanding DIO requests
-3) and only after that truncate inode blocks
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 1c9114f9c0f10f58dd7e568a7152025af47b27e5)
----
- fs/ext4/inode.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index 2bd7526..b84322d 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -4277,7 +4277,6 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
- }
-
- if (attr->ia_valid & ATTR_SIZE) {
-- inode_dio_wait(inode);
-
- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
-@@ -4326,8 +4325,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
- }
-
- if (attr->ia_valid & ATTR_SIZE) {
-- if (attr->ia_size != i_size_read(inode))
-+ if (attr->ia_size != i_size_read(inode)) {
- truncate_setsize(inode, attr->ia_size);
-+ /* Inode size will be reduced, wait for dio in flight */
-+ if (orphan)
-+ inode_dio_wait(inode);
-+ }
- ext4_truncate(inode);
- }
-
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch b/freed-ora/current/f18/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
deleted file mode 100644
index 768215f48..000000000
--- a/freed-ora/current/f18/0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From ab7b8a329e12369d58e5fa59ba2e2c90370f12ef Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sat, 29 Sep 2012 00:56:15 -0400
-Subject: [PATCH 07/13] ext4: endless truncate due to nonlocked dio readers
-
-If we have enough aggressive DIO readers, truncate and other dio
-waiters will wait forever inside inode_dio_wait(). It is reasonable
-to disable nonlock DIO read optimization during truncate.
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 1b65007e9870e0021397b548e8cd6bbc584f9152)
----
- fs/ext4/inode.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index b84322d..3b03dd6 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -4327,9 +4327,14 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
- if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size != i_size_read(inode)) {
- truncate_setsize(inode, attr->ia_size);
-- /* Inode size will be reduced, wait for dio in flight */
-- if (orphan)
-+ /* Inode size will be reduced, wait for dio in flight.
-+ * Temporarily disable dioread_nolock to prevent
-+ * livelock. */
-+ if (orphan) {
-+ ext4_inode_block_unlocked_dio(inode);
- inode_dio_wait(inode);
-+ ext4_inode_resume_unlocked_dio(inode);
-+ }
- }
- ext4_truncate(inode);
- }
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch b/freed-ora/current/f18/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
deleted file mode 100644
index c7733ed74..000000000
--- a/freed-ora/current/f18/0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 69e4026a2d104ffcf1b935bc889f8abcbfbb29ec Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sat, 29 Sep 2012 00:58:26 -0400
-Subject: [PATCH 08/13] ext4: serialize truncate with owerwrite DIO workers
-
-Jan Kara have spotted interesting issue:
-There are potential data corruption issue with direct IO overwrites
-racing with truncate:
- Like:
- dio write truncate_task
- ->ext4_ext_direct_IO
- ->overwrite == 1
- ->down_read(&EXT4_I(inode)->i_data_sem);
- ->mutex_unlock(&inode->i_mutex);
- ->ext4_setattr()
- ->inode_dio_wait()
- ->truncate_setsize()
- ->ext4_truncate()
- ->down_write(&EXT4_I(inode)->i_data_sem);
- ->__blockdev_direct_IO
- ->ext4_get_block
- ->submit_io()
- ->up_read(&EXT4_I(inode)->i_data_sem);
- # truncate data blocks, allocate them to
- # other inode - bad stuff happens because
- # dio is still in flight.
-
-In order to serialize with truncate dio worker should grab extra i_dio_count
-reference before drop i_mutex.
-
-Reviewed-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 1f555cfa29e8f787d675e8390f88ce517a37271a)
----
- fs/ext4/inode.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index 3b03dd6..484a327 100644
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -3008,6 +3008,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
- overwrite = *((int *)iocb->private);
-
- if (overwrite) {
-+ atomic_inc(&inode->i_dio_count);
- down_read(&EXT4_I(inode)->i_data_sem);
- mutex_unlock(&inode->i_mutex);
- }
-@@ -3105,6 +3106,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
- retake_lock:
- /* take i_mutex locking again if we do a ovewrite dio */
- if (overwrite) {
-+ inode_dio_done(inode);
- up_read(&EXT4_I(inode)->i_data_sem);
- mutex_lock(&inode->i_mutex);
- }
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch b/freed-ora/current/f18/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
deleted file mode 100644
index 4d7636668..000000000
--- a/freed-ora/current/f18/0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 71a6398a4b59ddcf920dfb68872b5a771c606e3a Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sun, 30 Sep 2012 23:03:42 -0400
-Subject: [PATCH 09/13] ext4: punch_hole should wait for DIO writers
-
-punch_hole is the place where we have to wait for all existing writers
-(writeback, aio, dio), but currently we simply flush pended end_io request
-which is not sufficient. Other issue is that punch_hole performed w/o i_mutex
-held which obviously result in dangerous data corruption due to
-write-after-free.
-
-This patch performs following changes:
-- Guard punch_hole with i_mutex
-- Recheck inode flags under i_mutex
-- Block all new dio readers in order to prevent information leak caused by
- read-after-free pattern.
-- punch_hole now wait for all writers in flight
- NOTE: XXX write-after-free race is still possible because new dirty pages
- may appear due to mmap(), and currently there is no easy way to stop
- writeback while punch_hole is in progress.
-
-[ Fixed error return from ext4_ext_punch_hole() to make sure that we
- release i_mutex before returning EPERM or ETXTBUSY -- Ted ]
-
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 02d262dffcf4c74e5c4612ee736bdb94f18ed5b9)
----
- fs/ext4/extents.c | 53 ++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 36 insertions(+), 17 deletions(-)
-
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 1fbf2ff..202eb4d 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -4776,9 +4776,32 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
- loff_t first_page_offset, last_page_offset;
- int credits, err = 0;
-
-+ /*
-+ * Write out all dirty pages to avoid race conditions
-+ * Then release them.
-+ */
-+ if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
-+ err = filemap_write_and_wait_range(mapping,
-+ offset, offset + length - 1);
-+
-+ if (err)
-+ return err;
-+ }
-+
-+ mutex_lock(&inode->i_mutex);
-+ /* It's not possible punch hole on append only file */
-+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
-+ err = -EPERM;
-+ goto out_mutex;
-+ }
-+ if (IS_SWAPFILE(inode)) {
-+ err = -ETXTBSY;
-+ goto out_mutex;
-+ }
-+
- /* No need to punch hole beyond i_size */
- if (offset >= inode->i_size)
-- return 0;
-+ goto out_mutex;
-
- /*
- * If the hole extends beyond i_size, set the hole
-@@ -4796,33 +4819,25 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
- first_page_offset = first_page << PAGE_CACHE_SHIFT;
- last_page_offset = last_page << PAGE_CACHE_SHIFT;
-
-- /*
-- * Write out all dirty pages to avoid race conditions
-- * Then release them.
-- */
-- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
-- err = filemap_write_and_wait_range(mapping,
-- offset, offset + length - 1);
--
-- if (err)
-- return err;
-- }
--
- /* Now release the pages */
- if (last_page_offset > first_page_offset) {
- truncate_pagecache_range(inode, first_page_offset,
- last_page_offset - 1);
- }
-
-- /* finish any pending end_io work */
-+ /* Wait all existing dio workers, newcomers will block on i_mutex */
-+ ext4_inode_block_unlocked_dio(inode);
-+ inode_dio_wait(inode);
- err = ext4_flush_completed_IO(inode);
- if (err)
-- return err;
-+ goto out_dio;
-
- credits = ext4_writepage_trans_blocks(inode);
- handle = ext4_journal_start(inode, credits);
-- if (IS_ERR(handle))
-- return PTR_ERR(handle);
-+ if (IS_ERR(handle)) {
-+ err = PTR_ERR(handle);
-+ goto out_dio;
-+ }
-
- err = ext4_orphan_add(handle, inode);
- if (err)
-@@ -4916,6 +4931,10 @@ out:
- inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
- ext4_journal_stop(handle);
-+out_dio:
-+ ext4_inode_resume_unlocked_dio(inode);
-+out_mutex:
-+ mutex_unlock(&inode->i_mutex);
- return err;
- }
- int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch b/freed-ora/current/f18/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
deleted file mode 100644
index d161bb765..000000000
--- a/freed-ora/current/f18/0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 66d08dd92b82dabfd64853aa4edde1547fdf9ef7 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Sun, 30 Sep 2012 23:03:50 -0400
-Subject: [PATCH 10/13] ext4: fix ext_remove_space for punch_hole case
-
-Inode is allowed to have empty leaf only if it this is blockless inode.
-
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 6f2080e64487b9963f9c6ff8a252e1abce98f2d4)
----
- fs/ext4/extents.c | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
-
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 202eb4d..b1c92c0 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -2572,7 +2572,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
- struct ext4_ext_path *path = NULL;
- ext4_fsblk_t partial_cluster = 0;
- handle_t *handle;
-- int i = 0, err;
-+ int i = 0, err = 0;
-
- ext_debug("truncate since %u to %u\n", start, end);
-
-@@ -2604,12 +2604,16 @@ again:
- return PTR_ERR(path);
- }
- depth = ext_depth(inode);
-+ /* Leaf not may not exist only if inode has no blocks at all */
- ex = path[depth].p_ext;
- if (!ex) {
-- ext4_ext_drop_refs(path);
-- kfree(path);
-- path = NULL;
-- goto cont;
-+ if (depth) {
-+ EXT4_ERROR_INODE(inode,
-+ "path[%d].p_hdr == NULL",
-+ depth);
-+ err = -EIO;
-+ }
-+ goto out;
- }
-
- ee_block = le32_to_cpu(ex->ee_block);
-@@ -2641,8 +2645,6 @@ again:
- goto out;
- }
- }
--cont:
--
- /*
- * We start scanning from right side, freeing all the blocks
- * after i_size and walking into the tree depth-wise.
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch b/freed-ora/current/f18/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
deleted file mode 100644
index 517b20129..000000000
--- a/freed-ora/current/f18/0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From ca6d3910cbf8854f3f3b9846391f669733899101 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Fri, 5 Oct 2012 11:31:55 -0400
-Subject: [PATCH 11/13] ext4: fix ext4_flush_completed_IO wait semantics
-
-BUG #1) All places where we call ext4_flush_completed_IO are broken
- because buffered io and DIO/AIO goes through three stages
- 1) submitted io,
- 2) completed io (in i_completed_io_list) conversion pended
- 3) finished io (conversion done)
- And by calling ext4_flush_completed_IO we will flush only
- requests which were in (2) stage, which is wrong because:
- 1) punch_hole and truncate _must_ wait for all outstanding unwritten io
- regardless to it's state.
- 2) fsync and nolock_dio_read should also wait because there is
- a time window between end_page_writeback() and ext4_add_complete_io()
- As result integrity fsync is broken in case of buffered write
- to fallocated region:
- fsync blkdev_completion
- ->filemap_write_and_wait_range
- ->ext4_end_bio
- ->end_page_writeback
- <-- filemap_write_and_wait_range return
- ->ext4_flush_completed_IO
- sees empty i_completed_io_list but pended
- conversion still exist
- ->ext4_add_complete_io
-
-BUG #2) Race window becomes wider due to the 'ext4: completed_io
-locking cleanup V4' patch series
-
-This patch make following changes:
-1) ext4_flush_completed_io() now first try to flush completed io and when
- wait for any outstanding unwritten io via ext4_unwritten_wait()
-2) Rename function to more appropriate name.
-3) Assert that all callers of ext4_flush_unwritten_io should hold i_mutex to
- prevent endless wait
-
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-Reviewed-by: Jan Kara <jack@suse.cz>
-(cherry picked from commit c278531d39f3158bfee93dc67da0b77e09776de2)
----
- fs/ext4/ext4.h | 3 ++-
- fs/ext4/extents.c | 6 +++---
- fs/ext4/file.c | 2 +-
- fs/ext4/fsync.c | 2 +-
- fs/ext4/indirect.c | 8 +++++---
- fs/ext4/page-io.c | 11 +++++++----
- 6 files changed, 19 insertions(+), 13 deletions(-)
-
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 3e740e9..7f13292 100644
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -1941,7 +1941,7 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
-
- /* fsync.c */
- extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
--extern int ext4_flush_completed_IO(struct inode *);
-+extern int ext4_flush_unwritten_io(struct inode *);
-
- /* hash.c */
- extern int ext4fs_dirhash(const char *name, int len, struct
-@@ -2361,6 +2361,7 @@ extern const struct file_operations ext4_dir_operations;
- extern const struct inode_operations ext4_file_inode_operations;
- extern const struct file_operations ext4_file_operations;
- extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
-+extern void ext4_unwritten_wait(struct inode *inode);
-
- /* namei.c */
- extern const struct inode_operations ext4_dir_inode_operations;
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index b1c92c0..37f46eb 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -4250,7 +4250,7 @@ void ext4_ext_truncate(struct inode *inode)
- * finish any pending end_io work so we won't run the risk of
- * converting any truncated blocks to initialized later
- */
-- ext4_flush_completed_IO(inode);
-+ ext4_flush_unwritten_io(inode);
-
- /*
- * probably first extent we're gonna free will be last in block
-@@ -4829,10 +4829,10 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
-
- /* Wait all existing dio workers, newcomers will block on i_mutex */
- ext4_inode_block_unlocked_dio(inode);
-- inode_dio_wait(inode);
-- err = ext4_flush_completed_IO(inode);
-+ err = ext4_flush_unwritten_io(inode);
- if (err)
- goto out_dio;
-+ inode_dio_wait(inode);
-
- credits = ext4_writepage_trans_blocks(inode);
- handle = ext4_journal_start(inode, credits);
-diff --git a/fs/ext4/file.c b/fs/ext4/file.c
-index 39335bd..ca6f07a 100644
---- a/fs/ext4/file.c
-+++ b/fs/ext4/file.c
-@@ -55,7 +55,7 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
- return 0;
- }
-
--static void ext4_unwritten_wait(struct inode *inode)
-+void ext4_unwritten_wait(struct inode *inode)
- {
- wait_queue_head_t *wq = ext4_ioend_wq(inode);
-
-diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
-index 520b058..76051c6 100644
---- a/fs/ext4/fsync.c
-+++ b/fs/ext4/fsync.c
-@@ -138,7 +138,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
- if (inode->i_sb->s_flags & MS_RDONLY)
- goto out;
-
-- ret = ext4_flush_completed_IO(inode);
-+ ret = ext4_flush_unwritten_io(inode);
- if (ret < 0)
- goto out;
-
-diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
-index 8d849da..792e388 100644
---- a/fs/ext4/indirect.c
-+++ b/fs/ext4/indirect.c
-@@ -807,9 +807,11 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
-
- retry:
- if (rw == READ && ext4_should_dioread_nolock(inode)) {
-- if (unlikely(!list_empty(&ei->i_completed_io_list)))
-- ext4_flush_completed_IO(inode);
--
-+ if (unlikely(atomic_read(&EXT4_I(inode)->i_unwritten))) {
-+ mutex_lock(&inode->i_mutex);
-+ ext4_flush_unwritten_io(inode);
-+ mutex_unlock(&inode->i_mutex);
-+ }
- /*
- * Nolock dioread optimization may be dynamically disabled
- * via ext4_inode_block_unlocked_dio(). Check inode's state
-diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
-index 5b24c40..68e896e 100644
---- a/fs/ext4/page-io.c
-+++ b/fs/ext4/page-io.c
-@@ -189,8 +189,6 @@ static int ext4_do_flush_completed_IO(struct inode *inode,
-
- list_add_tail(&io->list, &complete);
- }
-- /* It is important to update all flags for all end_io in one shot w/o
-- * dropping the lock.*/
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- while (!list_empty(&complete)) {
- io = list_entry(complete.next, ext4_io_end_t, list);
-@@ -228,9 +226,14 @@ static void ext4_end_io_work(struct work_struct *work)
- ext4_do_flush_completed_IO(io->inode, io);
- }
-
--int ext4_flush_completed_IO(struct inode *inode)
-+int ext4_flush_unwritten_io(struct inode *inode)
- {
-- return ext4_do_flush_completed_IO(inode, NULL);
-+ int ret;
-+ WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
-+ !(inode->i_state & I_FREEING));
-+ ret = ext4_do_flush_completed_IO(inode, NULL);
-+ ext4_unwritten_wait(inode);
-+ return ret;
- }
-
- ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch b/freed-ora/current/f18/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
deleted file mode 100644
index 3fcaef1f2..000000000
--- a/freed-ora/current/f18/0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 9f00d109efeaf4d12d56c8e46cd13af80e344f97 Mon Sep 17 00:00:00 2001
-From: Dmitry Monakhov <dmonakhov@openvz.org>
-Date: Fri, 5 Oct 2012 11:32:02 -0400
-Subject: [PATCH 12/13] ext4: serialize fallocate with
- ext4_convert_unwritten_extents
-
-Fallocate should wait for pended ext4_convert_unwritten_extents()
-otherwise following race may happen:
-
-ftruncate( ,12288);
-fallocate( ,0, 4096)
-io_sibmit( ,0, 4096); /* Write to fallocated area, split extent if needed */
-fallocate( ,0, 8192); /* Grow extent and broke assumption about extent */
-
-Later kwork completion will do:
- ->ext4_convert_unwritten_extents (0, 4096)
- ->ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_IO_CONVERT_EXT);
- ->ext4_ext_map_blocks() /* Will find new extent: ex = [0,2] !!!!!! */
- ->ext4_ext_handle_uninitialized_extents()
- ->ext4_convert_unwritten_extents_endio()
- /* convert [0,2] extent to initialized, but only[0,1] was written */
-
-Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-(cherry picked from commit 60d4616f3dc63371b3dc367e5e88fd4b4f037f65)
----
- fs/ext4/extents.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 37f46eb..ea2db86 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -4410,6 +4410,9 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
- */
- if (len <= EXT_UNINIT_MAX_LEN << blkbits)
- flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
-+
-+ /* Prevent race condition between unwritten */
-+ ext4_flush_unwritten_io(inode);
- retry:
- while (ret >= 0 && ret < max_blocks) {
- map.m_lblk = map.m_lblk + ret;
---
-1.7.12.rc0.22.gcdd159b
-
diff --git a/freed-ora/current/f18/Bluetooth-Add-support-for-BCM20702A0.patch b/freed-ora/current/f18/Bluetooth-Add-support-for-BCM20702A0.patch
index 73f00fc43..99178d757 100644
--- a/freed-ora/current/f18/Bluetooth-Add-support-for-BCM20702A0.patch
+++ b/freed-ora/current/f18/Bluetooth-Add-support-for-BCM20702A0.patch
@@ -1,67 +1,3 @@
-From 7f198e1cc6d4fda9c84c0da4fc3aafb441342f78 Mon Sep 17 00:00:00 2001
-From: Jaroslav Resler <resler@cs.cas.cz>
-Date: Tue, 11 Sep 2012 17:25:32 +0800
-Subject: [PATCH 1/2] Bluetooth: Add support for BCM20702A0 [04ca, 2003]
-
-Add another vendor specific ID for BCM20702A0.
-
-output of usb-devices:
-T: Bus=01 Lev=02 Prnt=02 Port=03 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
-D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
-P: Vendor=04ca ProdID=2003 Rev= 1.12
-S: Manufacturer=Broadcom Corp
-S: Product=BCM20702A0
-S: SerialNumber=446D57861623
-C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA
-I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
-E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
-E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
-I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
-I: If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
-I: If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
-I: If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
-I: If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
-E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
-I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
-E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms
-E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms
-I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
-
-Signed-off-by: Cho, Yu-Chen <acho@suse.com>
-Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
----
- drivers/bluetooth/btusb.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
-index 654e248..b167944 100644
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
- { USB_DEVICE(0x0c10, 0x0000) },
-
- /* Broadcom BCM20702A0 */
-+ { USB_DEVICE(0x04ca, 0x2003) },
- { USB_DEVICE(0x0489, 0xe042) },
- { USB_DEVICE(0x413c, 0x8197) },
-
---
-1.8.0
-
-
From a5f86c3423428c8e28b6501d0e9c3929ca91f07d Mon Sep 17 00:00:00 2001
From: Jeff Cook <jeff@deserettechnology.com>
Date: Fri, 9 Nov 2012 16:39:48 -0700
diff --git a/freed-ora/current/f18/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch b/freed-ora/current/f18/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
deleted file mode 100644
index 0d83e8d03..000000000
--- a/freed-ora/current/f18/SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 95ab000388974d8ffef8257306b4be6e8778b768 Mon Sep 17 00:00:00 2001
-From: Jianpeng Ma <majianpeng@gmail.com>
-Date: Sat, 4 Aug 2012 10:34:14 +0800
-Subject: [PATCH] [SCSI] mvsas: Fix oops when ata commond timeout.
-
-Kernel message follows:
-
-[ 511.712011] sd 11:0:0:0: [sdf] command ffff8800a4e81400 timed out
-[ 511.712022] sas: Enter sas_scsi_recover_host busy: 1 failed: 1
-[ 511.712024] sas: trying to find task 0xffff8800a4d24c80
-[ 511.712026] sas: sas_scsi_find_task: aborting task 0xffff8800a4d24c80
-[ 511.712029] drivers/scsi/mvsas/mv_sas.c 1631:mvs_abort_task()
-mvi=ffff8800b5300000 task=ffff8800a4d24c80 slot=ffff8800b5325038
-slot_idx=x0
-[ 511.712035] BUG: unable to handle kernel NULL pointer dereference at
-0000000000000058
-[ 511.712040] IP: [<ffffffff815f8c0c>] _raw_spin_lock_irqsave+0xc/0x30
-[ 511.712047] PGD 0
-[ 511.712049] Oops: 0002 [#1] SMP
-[ 511.712052] Modules linked in: mvsas libsas scsi_transport_sas
-raid456 async_pq async_xor xor async_memcpy async_raid6_recov raid6_pq
-async_tx [last unloaded: mvsas]
-[ 511.712062] CPU 3
-[ 511.712066] Pid: 7322, comm: scsi_eh_11 Not tainted 3.5.0+ #106 To Be
-Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M.
-[ 511.712068] RIP: 0010:[<ffffffff815f8c0c>] [<ffffffff815f8c0c>]
-_raw_spin_lock_irqsave+0xc/0x30
-[ 511.712073] RSP: 0018:ffff880098d3bcb0 EFLAGS: 00010086
-[ 511.712074] RAX: 0000000000000286 RBX: 0000000000000058 RCX:
-00000000000000c3
-[ 511.712076] RDX: 0000000000000100 RSI: 0000000000000046 RDI:
-0000000000000058
-[ 511.712078] RBP: ffff880098d3bcb0 R08: 000000000000000a R09:
-0000000000000000
-[ 511.712080] R10: 00000000000004e8 R11: 00000000000004e7 R12:
-ffff8800a4d24c80
-[ 511.712082] R13: 0000000000000050 R14: ffff8800b5325038 R15:
-ffff8800a4eafe00
-[ 511.712084] FS: 0000000000000000(0000) GS:ffff8800bdb80000(0000)
-knlGS:0000000000000000
-[ 511.712086] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
-[ 511.712088] CR2: 0000000000000058 CR3: 00000000a4ce6000 CR4:
-00000000000407e0
-[ 511.712090] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
-0000000000000000
-[ 511.712091] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
-0000000000000400
-[ 511.712093] Process scsi_eh_11 (pid: 7322, threadinfo
-ffff880098d3a000, task ffff8800a61dde40)
-[ 511.712095] Stack:
-[ 511.712096] ffff880098d3bce0 ffffffff81060683 ffff880000000000
-0000000000000000
-[ 511.712099] ffff8800a4d24c80 ffff8800b5300000 ffff880098d3bcf0
-ffffffffa0076a88
-[ 511.712102] ffff880098d3bd50 ffffffffa0079bb5 ffff880000000000
-ffff880000000018
-[ 511.712106] Call Trace:
-[ 511.712110] [<ffffffff81060683>] complete+0x23/0x60
-[ 511.712115] [<ffffffffa0076a88>] mvs_tmf_timedout+0x18/0x20 [mvsas]
-[ 511.712119] [<ffffffffa0079bb5>] mvs_slot_complete+0x765/0x7d0
-[mvsas]
-[ 511.712125] [<ffffffffa005a17d>] sas_scsi_recover_host+0x55d/0xdb0
-[libsas]
-[ 511.712128] [<ffffffff8106d600>] ? idle_balance+0xe0/0x130
-[ 511.712133] [<ffffffff813b150c>] scsi_error_handler+0xcc/0x470
-[ 511.712136] [<ffffffff815f7ad0>] ? __schedule+0x370/0x730
-[ 511.712139] [<ffffffff8105f728>] ? __wake_up_common+0x58/0x90
-[ 511.712142] [<ffffffff813b1440>] ? scsi_eh_get_sense+0x110/0x110
-[ 511.712146] [<ffffffff810571be>] kthread+0x8e/0xa0
-[ 511.712150] [<ffffffff816015f4>] kernel_thread_helper+0x4/0x10
-[ 511.712153] [<ffffffff81057130>] ? flush_kthread_work+0x120/0x120
-[ 511.712156] [<ffffffff816015f0>] ? gs_change+0xb/0xb
-[ 511.712157] Code: 8a 00 01 00 00 89 d0 f0 66 0f b1 0f 66 39 d0 0f 94
-c0 0f b6 c0 5d c3 0f 1f 84 00 00 00 00 00 55 48 89 e5 9c 58 fa ba 00 01
-00 00 <f0> 66 0f c1 17 0f b6 ce 38 d1 74 11 0f 1f 84 00 00 00 00 00 f3
-[ 511.712191] RIP [<ffffffff815f8c0c>] _raw_spin_lock_irqsave+0xc/0x30
-[ 511.712194] RSP <ffff880098d3bcb0>
-[ 511.712196] CR2: 0000000000000058
-[ 511.712198] ---[ end trace a781c7b1e65db92c ]---
-
-Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
-Signed-off-by: James Bottomley <JBottomley@Parallels.com>
----
- drivers/scsi/mvsas/mv_sas.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
-index 4539d59..a3776d6 100644
---- a/drivers/scsi/mvsas/mv_sas.c
-+++ b/drivers/scsi/mvsas/mv_sas.c
-@@ -1629,7 +1629,7 @@ int mvs_abort_task(struct sas_task *task)
- mv_dprintk("mvs_abort_task() mvi=%p task=%p "
- "slot=%p slot_idx=x%x\n",
- mvi, task, slot, slot_idx);
-- mvs_tmf_timedout((unsigned long)task);
-+ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
- mvs_slot_task_free(mvi, task, slot, slot_idx);
- rc = TMF_RESP_FUNC_COMPLETE;
- goto out;
---
-1.8.0
-
diff --git a/freed-ora/current/f18/arm-fix_radio_shark.patch b/freed-ora/current/f18/arm-fix_radio_shark.patch
deleted file mode 100644
index 63296a90e..000000000
--- a/freed-ora/current/f18/arm-fix_radio_shark.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
-index ff3af6e..f99fa25 100644
---- a/sound/pci/Kconfig
-+++ b/sound/pci/Kconfig
-@@ -2,8 +2,8 @@
-
- config SND_TEA575X
- tristate
-- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
-- default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
-+ depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
-+ default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
-
- menuconfig SND_PCI
- bool "PCI sound devices"
diff --git a/freed-ora/current/f18/arm-highbank-sata-fix.patch b/freed-ora/current/f18/arm-highbank-sata-fix.patch
deleted file mode 100644
index fda7b219e..000000000
--- a/freed-ora/current/f18/arm-highbank-sata-fix.patch
+++ /dev/null
@@ -1,599 +0,0 @@
-From: Mark Langsdorf <mark.langsdorf@calxeda.com>
-Date: Thu, 6 Sep 2012 21:03:30 +0000 (-0500)
-Subject: ata: add platform driver for Calxeda AHCI controller
-X-Git-Tag: next-20121002~68^2~5
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fnext%2Flinux-next.git;a=commitdiff_plain;h=8996b89d6bc98ae2f6d6e6e624a42a3f89d06949;hp=100f586bd0959fe0e52b8a0b8cb49a3df1c6b044
-
-ata: add platform driver for Calxeda AHCI controller
-
-Calxeda highbank SATA phy has intermittent problems bringing up a link
-with Gen3 drives. Retrying the phy hard reset can work-around this issue,
-but each reset also disables spread spectrum support. The reset function
-also needs to reprogram the phy to enable spread spectrum support.
-
-Create a new driver based on ahci_platform to support the Calxeda Highbank
-SATA controller.
-
-Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
-Signed-off-by: Rob Herring <rob.herring@calxeda.com>
-Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
----
-
-diff --git a/Documentation/devicetree/bindings/arm/calxeda/combophy.txt b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
-new file mode 100644
-index 0000000..6622bdb
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
-@@ -0,0 +1,17 @@
-+Calxeda Highbank Combination Phys for SATA
-+
-+Properties:
-+- compatible : Should be "calxeda,hb-combophy"
-+- #phy-cells: Should be 1.
-+- reg : Address and size for Combination Phy registers.
-+- phydev: device ID for programming the combophy.
-+
-+Example:
-+
-+ combophy5: combo-phy@fff5d000 {
-+ compatible = "calxeda,hb-combophy";
-+ #phy-cells = <1>;
-+ reg = <0xfff5d000 0x1000>;
-+ phydev = <31>;
-+ };
-+
-diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-index 8bb8a76..147c1f6 100644
---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
-+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-@@ -8,9 +8,17 @@ Required properties:
- - interrupts : <interrupt mapping for SATA IRQ>
- - reg : <registers mapping>
-
-+Optional properties:
-+- calxeda,port-phys: phandle-combophy and lane assignment, which maps each
-+ SATA port to a combophy and a lane within that
-+ combophy
-+
- Example:
- sata@ffe08000 {
- compatible = "calxeda,hb-ahci";
- reg = <0xffe08000 0x1000>;
- interrupts = <115>;
-+ calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
-+ &combophy0 2 &combophy0 3>;
-+
- };
-diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
-index 9fecf1a..5204cf7 100644
---- a/arch/arm/boot/dts/highbank.dts
-+++ b/arch/arm/boot/dts/highbank.dts
-@@ -121,6 +121,9 @@
- compatible = "calxeda,hb-ahci";
- reg = <0xffe08000 0x10000>;
- interrupts = <0 83 4>;
-+ calxeda,port-phys = <&combophy5 0 &combophy0 0
-+ &combophy0 1 &combophy0 2
-+ &combophy0 3>;
- };
-
- sdhci@ffe0e000 {
-@@ -306,5 +309,19 @@
- reg = <0xfff51000 0x1000>;
- interrupts = <0 80 4 0 81 4 0 82 4>;
- };
-+
-+ combophy0: combo-phy@fff58000 {
-+ compatible = "calxeda,hb-combophy";
-+ #phy-cells = <1>;
-+ reg = <0xfff58000 0x1000>;
-+ phydev = <5>;
-+ };
-+
-+ combophy5: combo-phy@fff5d000 {
-+ compatible = "calxeda,hb-combophy";
-+ #phy-cells = <1>;
-+ reg = <0xfff5d000 0x1000>;
-+ phydev = <31>;
-+ };
- };
- };
-diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
-index 27cecd3..e08d322 100644
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -214,6 +214,14 @@ config SATA_DWC_VDEBUG
- help
- This option enables the taskfile dumping and NCQ debugging.
-
-+config SATA_HIGHBANK
-+ tristate "Calxeda Highbank SATA support"
-+ help
-+ This option enables support for the Calxeda Highbank SoC's
-+ onboard SATA.
-+
-+ If unsure, say N.
-+
- config SATA_MV
- tristate "Marvell SATA support"
- help
-diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
-index a454a13..8b384f1 100644
---- a/drivers/ata/Makefile
-+++ b/drivers/ata/Makefile
-@@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o
- obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
- obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
- obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
-+obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o
-
- # SFF w/ custom DMA
- obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
-diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
-index 09728e0..dc187c7 100644
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -277,7 +277,6 @@ static int ahci_resume(struct device *dev)
- SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
-
- static const struct of_device_id ahci_of_match[] = {
-- { .compatible = "calxeda,hb-ahci", },
- { .compatible = "snps,spear-ahci", },
- {},
- };
-diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
-new file mode 100644
-index 0000000..0d7c4c2
---- /dev/null
-+++ b/drivers/ata/sata_highbank.c
-@@ -0,0 +1,450 @@
-+/*
-+ * Calxeda Highbank AHCI SATA platform driver
-+ * Copyright 2012 Calxeda, Inc.
-+ *
-+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ * more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along with
-+ * this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/spinlock.h>
-+#include <linux/device.h>
-+#include <linux/of_device.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+#include <linux/libata.h>
-+#include <linux/ahci_platform.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/export.h>
-+#include "ahci.h"
-+
-+#define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f))
-+#define CPHY_ADDR(addr) (((addr) & 0x1ff) << 2)
-+#define SERDES_CR_CTL 0x80a0
-+#define SERDES_CR_ADDR 0x80a1
-+#define SERDES_CR_DATA 0x80a2
-+#define CR_BUSY 0x0001
-+#define CR_START 0x0001
-+#define CR_WR_RDN 0x0002
-+#define CPHY_RX_INPUT_STS 0x2002
-+#define CPHY_SATA_OVERRIDE 0x4000
-+#define CPHY_OVERRIDE 0x2005
-+#define SPHY_LANE 0x100
-+#define SPHY_HALF_RATE 0x0001
-+#define CPHY_SATA_DPLL_MODE 0x0700
-+#define CPHY_SATA_DPLL_SHIFT 8
-+#define CPHY_SATA_DPLL_RESET (1 << 11)
-+#define CPHY_PHY_COUNT 6
-+#define CPHY_LANE_COUNT 4
-+#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
-+
-+static DEFINE_SPINLOCK(cphy_lock);
-+/* Each of the 6 phys can have up to 4 sata ports attached to i. Map 0-based
-+ * sata ports to their phys and then to their lanes within the phys
-+ */
-+struct phy_lane_info {
-+ void __iomem *phy_base;
-+ u8 lane_mapping;
-+ u8 phy_devs;
-+};
-+static struct phy_lane_info port_data[CPHY_PORT_COUNT];
-+
-+static u32 __combo_phy_reg_read(u8 sata_port, u32 addr)
-+{
-+ u32 data;
-+ u8 dev = port_data[sata_port].phy_devs;
-+ spin_lock(&cphy_lock);
-+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
-+ data = readl(port_data[sata_port].phy_base + CPHY_ADDR(addr));
-+ spin_unlock(&cphy_lock);
-+ return data;
-+}
-+
-+static void __combo_phy_reg_write(u8 sata_port, u32 addr, u32 data)
-+{
-+ u8 dev = port_data[sata_port].phy_devs;
-+ spin_lock(&cphy_lock);
-+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
-+ writel(data, port_data[sata_port].phy_base + CPHY_ADDR(addr));
-+ spin_unlock(&cphy_lock);
-+}
-+
-+static void combo_phy_wait_for_ready(u8 sata_port)
-+{
-+ while (__combo_phy_reg_read(sata_port, SERDES_CR_CTL) & CR_BUSY)
-+ udelay(5);
-+}
-+
-+static u32 combo_phy_read(u8 sata_port, u32 addr)
-+{
-+ combo_phy_wait_for_ready(sata_port);
-+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
-+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_START);
-+ combo_phy_wait_for_ready(sata_port);
-+ return __combo_phy_reg_read(sata_port, SERDES_CR_DATA);
-+}
-+
-+static void combo_phy_write(u8 sata_port, u32 addr, u32 data)
-+{
-+ combo_phy_wait_for_ready(sata_port);
-+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
-+ __combo_phy_reg_write(sata_port, SERDES_CR_DATA, data);
-+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_WR_RDN | CR_START);
-+}
-+
-+static void highbank_cphy_disable_overrides(u8 sata_port)
-+{
-+ u8 lane = port_data[sata_port].lane_mapping;
-+ u32 tmp;
-+ if (unlikely(port_data[sata_port].phy_base == NULL))
-+ return;
-+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
-+ tmp &= ~CPHY_SATA_OVERRIDE;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+}
-+
-+static void cphy_override_rx_mode(u8 sata_port, u32 val)
-+{
-+ u8 lane = port_data[sata_port].lane_mapping;
-+ u32 tmp;
-+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
-+ tmp &= ~CPHY_SATA_OVERRIDE;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+
-+ tmp |= CPHY_SATA_OVERRIDE;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+
-+ tmp &= ~CPHY_SATA_DPLL_MODE;
-+ tmp |= val << CPHY_SATA_DPLL_SHIFT;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+
-+ tmp |= CPHY_SATA_DPLL_RESET;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+
-+ tmp &= ~CPHY_SATA_DPLL_RESET;
-+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
-+
-+ msleep(15);
-+}
-+
-+static void highbank_cphy_override_lane(u8 sata_port)
-+{
-+ u8 lane = port_data[sata_port].lane_mapping;
-+ u32 tmp, k = 0;
-+
-+ if (unlikely(port_data[sata_port].phy_base == NULL))
-+ return;
-+ do {
-+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS +
-+ lane * SPHY_LANE);
-+ } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
-+ cphy_override_rx_mode(sata_port, 3);
-+}
-+
-+static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
-+{
-+ struct device_node *sata_node = dev->of_node;
-+ int phy_count = 0, phy, port = 0;
-+ void __iomem *cphy_base[CPHY_PHY_COUNT];
-+ struct device_node *phy_nodes[CPHY_PHY_COUNT];
-+ memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
-+ memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
-+
-+ do {
-+ u32 tmp;
-+ struct of_phandle_args phy_data;
-+ if (of_parse_phandle_with_args(sata_node,
-+ "calxeda,port-phys", "#phy-cells",
-+ port, &phy_data))
-+ break;
-+ for (phy = 0; phy < phy_count; phy++) {
-+ if (phy_nodes[phy] == phy_data.np)
-+ break;
-+ }
-+ if (phy_nodes[phy] == NULL) {
-+ phy_nodes[phy] = phy_data.np;
-+ cphy_base[phy] = of_iomap(phy_nodes[phy], 0);
-+ if (cphy_base[phy] == NULL) {
-+ return 0;
-+ }
-+ phy_count += 1;
-+ }
-+ port_data[port].lane_mapping = phy_data.args[0];
-+ of_property_read_u32(phy_nodes[phy], "phydev", &tmp);
-+ port_data[port].phy_devs = tmp;
-+ port_data[port].phy_base = cphy_base[phy];
-+ of_node_put(phy_data.np);
-+ port += 1;
-+ } while (port < CPHY_PORT_COUNT);
-+ return 0;
-+}
-+
-+static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
-+ unsigned long deadline)
-+{
-+ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-+ struct ata_port *ap = link->ap;
-+ struct ahci_port_priv *pp = ap->private_data;
-+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
-+ struct ata_taskfile tf;
-+ bool online;
-+ u32 sstatus;
-+ int rc;
-+ int retry = 10;
-+
-+ ahci_stop_engine(ap);
-+
-+ /* clear D2H reception area to properly wait for D2H FIS */
-+ ata_tf_init(link->device, &tf);
-+ tf.command = 0x80;
-+ ata_tf_to_fis(&tf, 0, 0, d2h_fis);
-+
-+ do {
-+ highbank_cphy_disable_overrides(link->ap->port_no);
-+ rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
-+ highbank_cphy_override_lane(link->ap->port_no);
-+
-+ /* If the status is 1, we are connected, but the link did not
-+ * come up. So retry resetting the link again.
-+ */
-+ if (sata_scr_read(link, SCR_STATUS, &sstatus))
-+ break;
-+ if (!(sstatus & 0x3))
-+ break;
-+ } while (!online && retry--);
-+
-+ ahci_start_engine(ap);
-+
-+ if (online)
-+ *class = ahci_dev_classify(ap);
-+
-+ return rc;
-+}
-+
-+static struct ata_port_operations ahci_highbank_ops = {
-+ .inherits = &ahci_ops,
-+ .hardreset = ahci_highbank_hardreset,
-+};
-+
-+static const struct ata_port_info ahci_highbank_port_info = {
-+ .flags = AHCI_FLAG_COMMON,
-+ .pio_mask = ATA_PIO4,
-+ .udma_mask = ATA_UDMA6,
-+ .port_ops = &ahci_highbank_ops,
-+};
-+
-+static struct scsi_host_template ahci_highbank_platform_sht = {
-+ AHCI_SHT("highbank-ahci"),
-+};
-+
-+static const struct of_device_id ahci_of_match[] = {
-+ { .compatible = "calxeda,hb-ahci" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ahci_of_match);
-+
-+static int __init ahci_highbank_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ahci_host_priv *hpriv;
-+ struct ata_host *host;
-+ struct resource *mem;
-+ int irq;
-+ int n_ports;
-+ int i;
-+ int rc;
-+ struct ata_port_info pi = ahci_highbank_port_info;
-+ const struct ata_port_info *ppi[] = { &pi, NULL };
-+
-+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!mem) {
-+ dev_err(dev, "no mmio space\n");
-+ return -EINVAL;
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq <= 0) {
-+ dev_err(dev, "no irq\n");
-+ return -EINVAL;
-+ }
-+
-+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
-+ if (!hpriv) {
-+ dev_err(dev, "can't alloc ahci_host_priv\n");
-+ return -ENOMEM;
-+ }
-+
-+ hpriv->flags |= (unsigned long)pi.private_data;
-+
-+ hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
-+ if (!hpriv->mmio) {
-+ dev_err(dev, "can't map %pR\n", mem);
-+ return -ENOMEM;
-+ }
-+
-+ rc = highbank_initialize_phys(dev, hpriv->mmio);
-+ if (rc)
-+ return rc;
-+
-+
-+ ahci_save_initial_config(dev, hpriv, 0, 0);
-+
-+ /* prepare host */
-+ if (hpriv->cap & HOST_CAP_NCQ)
-+ pi.flags |= ATA_FLAG_NCQ;
-+
-+ if (hpriv->cap & HOST_CAP_PMP)
-+ pi.flags |= ATA_FLAG_PMP;
-+
-+ ahci_set_em_messages(hpriv, &pi);
-+
-+ /* CAP.NP sometimes indicate the index of the last enabled
-+ * port, at other times, that of the last possible port, so
-+ * determining the maximum port number requires looking at
-+ * both CAP.NP and port_map.
-+ */
-+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
-+
-+ host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-+ if (!host) {
-+ rc = -ENOMEM;
-+ goto err0;
-+ }
-+
-+ host->private_data = hpriv;
-+
-+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
-+ host->flags |= ATA_HOST_PARALLEL_SCAN;
-+
-+ if (pi.flags & ATA_FLAG_EM)
-+ ahci_reset_em(host);
-+
-+ for (i = 0; i < host->n_ports; i++) {
-+ struct ata_port *ap = host->ports[i];
-+
-+ ata_port_desc(ap, "mmio %pR", mem);
-+ ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
-+
-+ /* set enclosure management message type */
-+ if (ap->flags & ATA_FLAG_EM)
-+ ap->em_message_type = hpriv->em_msg_type;
-+
-+ /* disabled/not-implemented port */
-+ if (!(hpriv->port_map & (1 << i)))
-+ ap->ops = &ata_dummy_port_ops;
-+ }
-+
-+ rc = ahci_reset_controller(host);
-+ if (rc)
-+ goto err0;
-+
-+ ahci_init_controller(host);
-+ ahci_print_info(host, "platform");
-+
-+ rc = ata_host_activate(host, irq, ahci_interrupt, 0,
-+ &ahci_highbank_platform_sht);
-+ if (rc)
-+ goto err0;
-+
-+ return 0;
-+err0:
-+ return rc;
-+}
-+
-+static int __devexit ahci_highbank_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ata_host *host = dev_get_drvdata(dev);
-+
-+ ata_host_detach(host);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int ahci_highbank_suspend(struct device *dev)
-+{
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+ void __iomem *mmio = hpriv->mmio;
-+ u32 ctl;
-+ int rc;
-+
-+ if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
-+ dev_err(dev, "firmware update required for suspend/resume\n");
-+ return -EIO;
-+ }
-+
-+ /*
-+ * AHCI spec rev1.1 section 8.3.3:
-+ * Software must disable interrupts prior to requesting a
-+ * transition of the HBA to D3 state.
-+ */
-+ ctl = readl(mmio + HOST_CTL);
-+ ctl &= ~HOST_IRQ_EN;
-+ writel(ctl, mmio + HOST_CTL);
-+ readl(mmio + HOST_CTL); /* flush */
-+
-+ rc = ata_host_suspend(host, PMSG_SUSPEND);
-+ if (rc)
-+ return rc;
-+
-+ return 0;
-+}
-+
-+static int ahci_highbank_resume(struct device *dev)
-+{
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ int rc;
-+
-+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-+ rc = ahci_reset_controller(host);
-+ if (rc)
-+ return rc;
-+
-+ ahci_init_controller(host);
-+ }
-+
-+ ata_host_resume(host);
-+
-+ return 0;
-+}
-+#endif
-+
-+SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
-+ ahci_highbank_suspend, ahci_highbank_resume);
-+
-+static struct platform_driver ahci_highbank_driver = {
-+ .remove = __devexit_p(ahci_highbank_remove),
-+ .driver = {
-+ .name = "highbank-ahci",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ahci_of_match,
-+ .pm = &ahci_highbank_pm_ops,
-+ },
-+ .probe = ahci_highbank_probe,
-+};
-+
-+module_platform_driver(ahci_highbank_driver);
-+
-+MODULE_DESCRIPTION("Calxeda Highbank AHCI SATA platform driver");
-+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("sata:highbank");
diff --git a/freed-ora/current/f18/block-fix-a-crash-when-block-device-is.patch b/freed-ora/current/f18/block-fix-a-crash-when-block-device-is.patch
deleted file mode 100644
index af992830e..000000000
--- a/freed-ora/current/f18/block-fix-a-crash-when-block-device-is.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-Fix a crash when block device is read and block size is changed at the same time
-
-commit b87570f5d349661814b262dd5fc40787700f80d6
-Author: Mikulas Patocka <mpatocka@redhat.com>
-Date: Wed Sep 26 07:46:40 2012 +0200
-
- Fix a crash when block device is read and block size is changed at the same time
-
- The kernel may crash when block size is changed and I/O is issued
- simultaneously.
-
- Because some subsystems (udev or lvm) may read any block device anytime,
- the bug actually puts any code that changes a block device size in
- jeopardy.
-
- The crash can be reproduced if you place "msleep(1000)" to
- blkdev_get_blocks just before "bh->b_size = max_blocks <<
- inode->i_blkbits;".
- Then, run "dd if=/dev/ram0 of=/dev/null bs=4k count=1 iflag=direct"
- While it is waiting in msleep, run "blockdev --setbsz 2048 /dev/ram0"
- You get a BUG.
-
- The direct and non-direct I/O is written with the assumption that block
- size does not change. It doesn't seem practical to fix these crashes
- one-by-one there may be many crash possibilities when block size changes
- at a certain place and it is impossible to find them all and verify the
- code.
-
- This patch introduces a new rw-lock bd_block_size_semaphore. The lock is
- taken for read during I/O. It is taken for write when changing block
- size. Consequently, block size can't be changed while I/O is being
- submitted.
-
- For asynchronous I/O, the patch only prevents block size change while
- the I/O is being submitted. The block size can change when the I/O is in
- progress or when the I/O is being finished. This is acceptable because
- there are no accesses to block size when asynchronous I/O is being
- finished.
-
- The patch prevents block size changing while the device is mapped with
- mmap.
-
- Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
- Signed-off-by: Jens Axboe <axboe@kernel.dk>
-
-Index: linux-3.6.x86_64/drivers/char/raw.c
-===================================================================
---- linux-3.6.x86_64.orig/drivers/char/raw.c 2012-11-16 17:12:35.127010280 -0500
-+++ linux-3.6.x86_64/drivers/char/raw.c 2012-11-16 17:12:37.381002516 -0500
-@@ -285,7 +285,7 @@
-
- static const struct file_operations raw_fops = {
- .read = do_sync_read,
-- .aio_read = generic_file_aio_read,
-+ .aio_read = blkdev_aio_read,
- .write = do_sync_write,
- .aio_write = blkdev_aio_write,
- .fsync = blkdev_fsync,
-Index: linux-3.6.x86_64/fs/block_dev.c
-===================================================================
---- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:35.127010280 -0500
-+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:12:37.381002516 -0500
-@@ -116,6 +116,8 @@
-
- int set_blocksize(struct block_device *bdev, int size)
- {
-+ struct address_space *mapping;
-+
- /* Size must be a power of two, and between 512 and PAGE_SIZE */
- if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
- return -EINVAL;
-@@ -124,6 +126,20 @@
- if (size < bdev_logical_block_size(bdev))
- return -EINVAL;
-
-+ /* Prevent starting I/O or mapping the device */
-+ down_write(&bdev->bd_block_size_semaphore);
-+
-+ /* Check that the block device is not memory mapped */
-+ mapping = bdev->bd_inode->i_mapping;
-+ mutex_lock(&mapping->i_mmap_mutex);
-+ if (!prio_tree_empty(&mapping->i_mmap) ||
-+ !list_empty(&mapping->i_mmap_nonlinear)) {
-+ mutex_unlock(&mapping->i_mmap_mutex);
-+ up_write(&bdev->bd_block_size_semaphore);
-+ return -EBUSY;
-+ }
-+ mutex_unlock(&mapping->i_mmap_mutex);
-+
- /* Don't change the size if it is same as current */
- if (bdev->bd_block_size != size) {
- sync_blockdev(bdev);
-@@ -131,6 +147,9 @@
- bdev->bd_inode->i_blkbits = blksize_bits(size);
- kill_bdev(bdev);
- }
-+
-+ up_write(&bdev->bd_block_size_semaphore);
-+
- return 0;
- }
-
-@@ -472,6 +491,7 @@
- inode_init_once(&ei->vfs_inode);
- /* Initialize mutex for freeze. */
- mutex_init(&bdev->bd_fsfreeze_mutex);
-+ init_rwsem(&bdev->bd_block_size_semaphore);
- }
-
- static inline void __bd_forget(struct inode *inode)
-@@ -1567,6 +1587,22 @@
- return blkdev_ioctl(bdev, mode, cmd, arg);
- }
-
-+ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
-+ unsigned long nr_segs, loff_t pos)
-+{
-+ ssize_t ret;
-+ struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
-+
-+ down_read(&bdev->bd_block_size_semaphore);
-+
-+ ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
-+
-+ up_read(&bdev->bd_block_size_semaphore);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(blkdev_aio_read);
-+
- /*
- * Write data to the block device. Only intended for the block device itself
- * and the raw driver which basically is a fake block device.
-@@ -1578,12 +1614,16 @@
- unsigned long nr_segs, loff_t pos)
- {
- struct file *file = iocb->ki_filp;
-+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
- struct blk_plug plug;
- ssize_t ret;
-
- BUG_ON(iocb->ki_pos != pos);
-
- blk_start_plug(&plug);
-+
-+ down_read(&bdev->bd_block_size_semaphore);
-+
- ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
- if (ret > 0 || ret == -EIOCBQUEUED) {
- ssize_t err;
-@@ -1592,11 +1632,29 @@
- if (err < 0 && ret > 0)
- ret = err;
- }
-+
-+ up_read(&bdev->bd_block_size_semaphore);
-+
- blk_finish_plug(&plug);
-+
- return ret;
- }
- EXPORT_SYMBOL_GPL(blkdev_aio_write);
-
-+int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ int ret;
-+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
-+
-+ down_read(&bdev->bd_block_size_semaphore);
-+
-+ ret = generic_file_mmap(file, vma);
-+
-+ up_read(&bdev->bd_block_size_semaphore);
-+
-+ return ret;
-+}
-+
- /*
- * Try to release a page associated with block device when the system
- * is under memory pressure.
-@@ -1627,9 +1685,9 @@
- .llseek = block_llseek,
- .read = do_sync_read,
- .write = do_sync_write,
-- .aio_read = generic_file_aio_read,
-+ .aio_read = blkdev_aio_read,
- .aio_write = blkdev_aio_write,
-- .mmap = generic_file_mmap,
-+ .mmap = blkdev_mmap,
- .fsync = blkdev_fsync,
- .unlocked_ioctl = block_ioctl,
- #ifdef CONFIG_COMPAT
-Index: linux-3.6.x86_64/include/linux/fs.h
-===================================================================
---- linux-3.6.x86_64.orig/include/linux/fs.h 2012-11-16 17:12:35.127010280 -0500
-+++ linux-3.6.x86_64/include/linux/fs.h 2012-11-16 17:12:37.424002387 -0500
-@@ -724,6 +724,8 @@
- int bd_fsfreeze_count;
- /* Mutex for freeze */
- struct mutex bd_fsfreeze_mutex;
-+ /* A semaphore that prevents I/O while block size is being changed */
-+ struct rw_semaphore bd_block_size_semaphore;
- };
-
- /*
-@@ -2564,6 +2566,8 @@
- unsigned long *nr_segs, size_t *count, int access_flags);
-
- /* fs/block_dev.c */
-+extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
-+ unsigned long nr_segs, loff_t pos);
- extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
- extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
diff --git a/freed-ora/current/f18/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch b/freed-ora/current/f18/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
deleted file mode 100644
index 82caa6b76..000000000
--- a/freed-ora/current/f18/blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-blockdev: turn a rw semaphore into a percpu rw semaphore
-
-commit 62ac665ff9fc07497ca524bd20d6a96893d11071
-Author: Mikulas Patocka <mpatocka@redhat.com>
-Date: Wed Sep 26 07:46:43 2012 +0200
-
- blockdev: turn a rw semaphore into a percpu rw semaphore
-
- This avoids cache line bouncing when many processes lock the semaphore
- for read.
-
- New percpu lock implementation
-
- The lock consists of an array of percpu unsigned integers, a boolean
- variable and a mutex.
-
- When we take the lock for read, we enter rcu read section, check for a
- "locked" variable. If it is false, we increase a percpu counter on the
- current cpu and exit the rcu section. If "locked" is true, we exit the
- rcu section, take the mutex and drop it (this waits until a writer
- finished) and retry.
-
- Unlocking for read just decreases percpu variable. Note that we can
- unlock on a difference cpu than where we locked, in this case the
- counter underflows. The sum of all percpu counters represents the number
- of processes that hold the lock for read.
-
- When we need to lock for write, we take the mutex, set "locked" variable
- to true and synchronize rcu. Since RCU has been synchronized, no
- processes can create new read locks. We wait until the sum of percpu
- counters is zero - when it is, there are no readers in the critical
- section.
-
- Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
- Signed-off-by: Jens Axboe <axboe@kernel.dk>
-
-Index: linux-3.6.x86_64/Documentation/percpu-rw-semaphore.txt
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-3.6.x86_64/Documentation/percpu-rw-semaphore.txt 2012-11-16 17:12:57.351936583 -0500
-@@ -0,0 +1,27 @@
-+Percpu rw semaphores
-+--------------------
-+
-+Percpu rw semaphores is a new read-write semaphore design that is
-+optimized for locking for reading.
-+
-+The problem with traditional read-write semaphores is that when multiple
-+cores take the lock for reading, the cache line containing the semaphore
-+is bouncing between L1 caches of the cores, causing performance
-+degradation.
-+
-+Locking for reading it very fast, it uses RCU and it avoids any atomic
-+instruction in the lock and unlock path. On the other hand, locking for
-+writing is very expensive, it calls synchronize_rcu() that can take
-+hundreds of microseconds.
-+
-+The lock is declared with "struct percpu_rw_semaphore" type.
-+The lock is initialized percpu_init_rwsem, it returns 0 on success and
-+-ENOMEM on allocation failure.
-+The lock must be freed with percpu_free_rwsem to avoid memory leak.
-+
-+The lock is locked for read with percpu_down_read, percpu_up_read and
-+for write with percpu_down_write, percpu_up_write.
-+
-+The idea of using RCU for optimized rw-lock was introduced by
-+Eric Dumazet <eric.dumazet@gmail.com>.
-+The code was written by Mikulas Patocka <mpatocka@redhat.com>
-Index: linux-3.6.x86_64/fs/block_dev.c
-===================================================================
---- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:37.381002516 -0500
-+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:27:41.217005828 -0500
-@@ -127,7 +127,7 @@
- return -EINVAL;
-
- /* Prevent starting I/O or mapping the device */
-- down_write(&bdev->bd_block_size_semaphore);
-+ percpu_down_write(&bdev->bd_block_size_semaphore);
-
- /* Check that the block device is not memory mapped */
- mapping = bdev->bd_inode->i_mapping;
-@@ -135,7 +135,7 @@
- if (!prio_tree_empty(&mapping->i_mmap) ||
- !list_empty(&mapping->i_mmap_nonlinear)) {
- mutex_unlock(&mapping->i_mmap_mutex);
-- up_write(&bdev->bd_block_size_semaphore);
-+ percpu_up_write(&bdev->bd_block_size_semaphore);
- return -EBUSY;
- }
- mutex_unlock(&mapping->i_mmap_mutex);
-@@ -148,7 +148,7 @@
- kill_bdev(bdev);
- }
-
-- up_write(&bdev->bd_block_size_semaphore);
-+ percpu_up_write(&bdev->bd_block_size_semaphore);
-
- return 0;
- }
-@@ -460,6 +460,12 @@
- struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
- if (!ei)
- return NULL;
-+
-+ if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
-+ kmem_cache_free(bdev_cachep, ei);
-+ return NULL;
-+ }
-+
- return &ei->vfs_inode;
- }
-
-@@ -468,6 +474,8 @@
- struct inode *inode = container_of(head, struct inode, i_rcu);
- struct bdev_inode *bdi = BDEV_I(inode);
-
-+ percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
-+
- kmem_cache_free(bdev_cachep, bdi);
- }
-
-@@ -491,7 +499,6 @@
- inode_init_once(&ei->vfs_inode);
- /* Initialize mutex for freeze. */
- mutex_init(&bdev->bd_fsfreeze_mutex);
-- init_rwsem(&bdev->bd_block_size_semaphore);
- }
-
- static inline void __bd_forget(struct inode *inode)
-@@ -1593,11 +1600,11 @@
- ssize_t ret;
- struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
-
-- down_read(&bdev->bd_block_size_semaphore);
-+ percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
-
-- up_read(&bdev->bd_block_size_semaphore);
-+ percpu_up_read(&bdev->bd_block_size_semaphore);
-
- return ret;
- }
-@@ -1622,7 +1629,7 @@
-
- blk_start_plug(&plug);
-
-- down_read(&bdev->bd_block_size_semaphore);
-+ percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
- if (ret > 0 || ret == -EIOCBQUEUED) {
-@@ -1633,7 +1640,7 @@
- ret = err;
- }
-
-- up_read(&bdev->bd_block_size_semaphore);
-+ percpu_up_read(&bdev->bd_block_size_semaphore);
-
- blk_finish_plug(&plug);
-
-@@ -1646,11 +1653,11 @@
- int ret;
- struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
-- down_read(&bdev->bd_block_size_semaphore);
-+ percpu_down_read(&bdev->bd_block_size_semaphore);
-
- ret = generic_file_mmap(file, vma);
-
-- up_read(&bdev->bd_block_size_semaphore);
-+ percpu_up_read(&bdev->bd_block_size_semaphore);
-
- return ret;
- }
-Index: linux-3.6.x86_64/include/linux/fs.h
-===================================================================
---- linux-3.6.x86_64.orig/include/linux/fs.h 2012-11-16 17:12:37.424002387 -0500
-+++ linux-3.6.x86_64/include/linux/fs.h 2012-11-16 17:28:12.578901349 -0500
-@@ -415,6 +415,7 @@
- #include <linux/migrate_mode.h>
- #include <linux/uidgid.h>
- #include <linux/lockdep.h>
-+#include <linux/percpu-rwsem.h>
-
- #include <asm/byteorder.h>
-
-@@ -725,7 +726,7 @@
- /* Mutex for freeze */
- struct mutex bd_fsfreeze_mutex;
- /* A semaphore that prevents I/O while block size is being changed */
-- struct rw_semaphore bd_block_size_semaphore;
-+ struct percpu_rw_semaphore bd_block_size_semaphore;
- };
-
- /*
-Index: linux-3.6.x86_64/include/linux/percpu-rwsem.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-3.6.x86_64/include/linux/percpu-rwsem.h 2012-11-16 17:12:57.354936574 -0500
-@@ -0,0 +1,89 @@
-+#ifndef _LINUX_PERCPU_RWSEM_H
-+#define _LINUX_PERCPU_RWSEM_H
-+
-+#include <linux/mutex.h>
-+#include <linux/percpu.h>
-+#include <linux/rcupdate.h>
-+#include <linux/delay.h>
-+
-+struct percpu_rw_semaphore {
-+ unsigned __percpu *counters;
-+ bool locked;
-+ struct mutex mtx;
-+};
-+
-+static inline void percpu_down_read(struct percpu_rw_semaphore *p)
-+{
-+ rcu_read_lock();
-+ if (unlikely(p->locked)) {
-+ rcu_read_unlock();
-+ mutex_lock(&p->mtx);
-+ this_cpu_inc(*p->counters);
-+ mutex_unlock(&p->mtx);
-+ return;
-+ }
-+ this_cpu_inc(*p->counters);
-+ rcu_read_unlock();
-+}
-+
-+static inline void percpu_up_read(struct percpu_rw_semaphore *p)
-+{
-+ /*
-+ * On X86, write operation in this_cpu_dec serves as a memory unlock
-+ * barrier (i.e. memory accesses may be moved before the write, but
-+ * no memory accesses are moved past the write).
-+ * On other architectures this may not be the case, so we need smp_mb()
-+ * there.
-+ */
-+#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
-+ barrier();
-+#else
-+ smp_mb();
-+#endif
-+ this_cpu_dec(*p->counters);
-+}
-+
-+static inline unsigned __percpu_count(unsigned __percpu *counters)
-+{
-+ unsigned total = 0;
-+ int cpu;
-+
-+ for_each_possible_cpu(cpu)
-+ total += ACCESS_ONCE(*per_cpu_ptr(counters, cpu));
-+
-+ return total;
-+}
-+
-+static inline void percpu_down_write(struct percpu_rw_semaphore *p)
-+{
-+ mutex_lock(&p->mtx);
-+ p->locked = true;
-+ synchronize_rcu();
-+ while (__percpu_count(p->counters))
-+ msleep(1);
-+ smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
-+}
-+
-+static inline void percpu_up_write(struct percpu_rw_semaphore *p)
-+{
-+ p->locked = false;
-+ mutex_unlock(&p->mtx);
-+}
-+
-+static inline int percpu_init_rwsem(struct percpu_rw_semaphore *p)
-+{
-+ p->counters = alloc_percpu(unsigned);
-+ if (unlikely(!p->counters))
-+ return -ENOMEM;
-+ p->locked = false;
-+ mutex_init(&p->mtx);
-+ return 0;
-+}
-+
-+static inline void percpu_free_rwsem(struct percpu_rw_semaphore *p)
-+{
-+ free_percpu(p->counters);
-+ p->counters = NULL; /* catch use after free bugs */
-+}
-+
-+#endif
diff --git a/freed-ora/current/f18/config-arm-generic b/freed-ora/current/f18/config-arm-generic
index d44eda51d..89fc4356a 100644
--- a/freed-ora/current/f18/config-arm-generic
+++ b/freed-ora/current/f18/config-arm-generic
@@ -12,6 +12,7 @@ CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_VFP=y
CONFIG_ARM_UNWIND=y
+# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=4
@@ -27,6 +28,7 @@ CONFIG_FPE_FASTFPE=y
CONFIG_HIGHPTE=y
CONFIG_HW_PERF_EVENTS=y
CONFIG_UACCESS_WITH_MEMCPY=y
+# CONFIG_GENERIC_CPUFREQ_CPU0 is not set
# Generic ARM Errata
CONFIG_ARM_ERRATA_720789=y
@@ -35,13 +37,14 @@ CONFIG_ARM_ERRATA_742230=y
CONFIG_ARM_ERRATA_742231=y
CONFIG_ARM_ERRATA_754327=y
CONFIG_ARM_ERRATA_764369=y
-
+CONFIG_ARM_ERRATA_775420=y
# Generic ARM config options
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_LOCAL_TIMERS=y
+CONFIG_ATAGS=y
CONFIG_ATAGS_PROC=y
CONFIG_PL330_DMA=y
@@ -63,9 +66,6 @@ CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
-CONFIG_LSM_MMAP_MIN_ADDR=32768
-
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -75,6 +75,16 @@ CONFIG_SUSPEND=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_CPU_TOPOLOGY=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_LSM_MMAP_MIN_ADDR=32768
+
+# CONFIG_XEN is not set
+
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+
+CONFIG_COMMON_CLK=y
+
CONFIG_THERMAL=y
CONFIG_ETHERNET=y
@@ -84,24 +94,20 @@ CONFIG_PERF_COUNTERS=y
CONFIG_CC_STACKPROTECTOR=y
-CONFIG_AUTO_ZRELADDR=y
-
CONFIG_SECCOMP=y
CONFIG_STRICT_DEVMEM=y
CONFIG_SPARSE_IRQ=y
# Generic HW for all ARM platforms
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
CONFIG_LEDS_GPIO=m
CONFIG_LBDAF=y
+CONFIG_GPIOLIB=y
CONFIG_RFKILL_GPIO=m
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIO_GENERIC_PLATFORM=m
-CONFIG_GPIOLIB=y
CONFIG_PINCTRL_SINGLE=m
CONFIG_USB_ULPI=y
@@ -136,10 +142,13 @@ CONFIG_MMC_SPI=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_PLTFM=m
CONFIG_MMC_DW_PCI=m
+# CONFIG_MMC_DW_EXYNOS is not set
# CONFIG_MMC_DW_IDMAC is not set
CONFIG_MMC_SDHCI_PXAV3=m
CONFIG_MMC_SDHCI_PXAV2=m
+# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set
+
# Generic GPIO options
CONFIG_GENERIC_GPIO=y
@@ -234,12 +243,15 @@ CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_UBIFS_FS_DEBUG is not set
# HW crypto and rng
+CONFIG_CRYPTO_SHA1_ARM=m
+CONFIG_CRYPTO_AES_ARM=m
CONFIG_HW_RANDOM_ATMEL=m
CONFIG_HW_RANDOM_EXYNOS=m
# Device tree
CONFIG_OF=y
CONFIG_USE_OF=y
+CONFIG_OF_IRQ=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_PROC_DEVICETREE=y
@@ -252,6 +264,7 @@ CONFIG_OF_PCI_IRQ=y
CONFIG_I2C_MUX_PINCTRL=m
CONFIG_OF_MDIO=m
CONFIG_MDIO_BUS_MUX_GPIO=m
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
CONFIG_BPF_JIT=y
@@ -263,6 +276,7 @@ CONFIG_EDAC_LEGACY_SYSFS=y
CONFIG_RTC_DRV_88PM80X=m
CONFIG_RTC_DRV_PL030=m
CONFIG_RTC_DRV_PL031=m
+CONFIG_RTC_DRV_SNVS=m
CONFIG_RFKILL_REGULATOR=m
CONFIG_INPUT_88PM80X_ONKEY=y
CONFIG_INPUT_GP2A=m
@@ -272,14 +286,22 @@ CONFIG_SERIAL_AMBA_PL010=m
CONFIG_SERIAL_AMBA_PL011=m
CONFIG_GPIO_PL061=y
CONFIG_GPIO_MCP23S08=m
+CONFIG_GPIO_ADNP=m
CONFIG_PL310_ERRATA_753970=y
CONFIG_MFD_88PM800=m
CONFIG_MFD_88PM805=m
+CONFIG_MFD_SYSCON=y
+# CONFIG_MFD_SMSC is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MAX8907 is not set
+
CONFIG_REGULATOR_VIRTUAL_CONSUMER=m
CONFIG_REGULATOR_USERSPACE_CONSUMER=m
CONFIG_REGULATOR_GPIO=m
CONFIG_REGULATOR_AD5398=m
+CONFIG_REGULATOR_ANATOP=m
+CONFIG_REGULATOR_FAN53555=m
CONFIG_REGULATOR_ISL6271A=m
CONFIG_REGULATOR_MAX1586=m
CONFIG_REGULATOR_MAX8649=m
@@ -292,6 +314,12 @@ CONFIG_REGULATOR_TPS6507X=m
CONFIG_CHARGER_MANAGER=y
CONFIG_EXTCON_GPIO=m
+# CONFIG_ARM_VIRT_EXT is not set
+# CONFIG_PINCTRL_EXYNOS4 is not set
+
+# CONFIG_AUTO_ZRELADDR is not set
+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
+
# CONFIG_VFIO is not set
# CONFIG_XIP_KERNEL is not set
@@ -356,3 +384,4 @@ CONFIG_EXTCON_GPIO=m
# CONFIG_NET_VENDOR_CIRRUS is not set
# CONFIG_CS89x0 is not set
+# CONFIG_DVB_USB_PCTV452E is not set
diff --git a/freed-ora/current/f18/config-arm-highbank b/freed-ora/current/f18/config-arm-highbank
index 952a21ac4..ca27f65cb 100644
--- a/freed-ora/current/f18/config-arm-highbank
+++ b/freed-ora/current/f18/config-arm-highbank
@@ -59,4 +59,7 @@ CONFIG_OC_ETM=y
# CONFIG_MEDIA_SUPPORT is not set
# CONFIG_DRM is not set
# CONFIG_SND is not set
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+# CONFIG_ARCH_MULTI_V6 is not set
# end of list of requested disabled options
diff --git a/freed-ora/current/f18/config-arm-imx b/freed-ora/current/f18/config-arm-imx
index bddff88ab..8ffd96559 100644
--- a/freed-ora/current/f18/config-arm-imx
+++ b/freed-ora/current/f18/config-arm-imx
@@ -7,6 +7,7 @@ CONFIG_NEON=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_CPU_FREQ_IMX=y
+CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6Q=y
CONFIG_MACH_ARMADILLO5X0=y
@@ -67,6 +68,7 @@ CONFIG_I2C_IMX=m
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_MCP23S08=m
# CONFIG_GPIO_MC9S08DZ60 is not set
+CONFIG_PINCTRL_IMX35=y
CONFIG_PINCTRL_IMX51=y
CONFIG_PINCTRL_IMX53=y
CONFIG_USB_EHCI_MXC=y
@@ -77,6 +79,12 @@ CONFIG_MMC_MXC=m
CONFIG_RTC_MXC=y
CONFIG_RTC_DRV_MXC=m
+CONFIG_DRM_IMX=m
+CONFIG_DRM_IMX_FB_HELPER=m
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=m
+CONFIG_DRM_IMX_IPUV3_CORE=m
+CONFIG_DRM_IMX_IPUV3=m
+CONFIG_VIDEO_CODA=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_LEDS_PWM=m
@@ -104,6 +112,8 @@ CONFIG_SND_SOC_IMX_SGTL5000=m
CONFIG_PL310_ERRATA_769419=y
CONFIG_LEDS_RENESAS_TPU=y
+CONFIG_MFD_MAX8907=m
+
CONFIG_FB_IMX=m
# CONFIG_NET_VENDOR_BROADCOM is not set
diff --git a/freed-ora/current/f18/config-arm-kirkwood b/freed-ora/current/f18/config-arm-kirkwood
index c8d0ec181..ff1dad7df 100644
--- a/freed-ora/current/f18/config-arm-kirkwood
+++ b/freed-ora/current/f18/config-arm-kirkwood
@@ -6,6 +6,7 @@ CONFIG_ARCH_KIRKWOOD_DT=y
CONFIG_MACH_D2NET_V2=y
CONFIG_MACH_DB88F6281_BP=y
CONFIG_MACH_DOCKSTAR=y
+CONFIG_MACH_DOCKSTAR_DT=y
CONFIG_MACH_DREAMPLUG_DT=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_DLINK_KIRKWOOD_DT=y
@@ -14,6 +15,8 @@ CONFIG_MACH_GURUPLUG=y
CONFIG_MACH_ICONNECT_DT=y
CONFIG_MACH_IB62X0_DT=y
CONFIG_MACH_INETSPACE_V2=y
+CONFIG_MACH_IOMEGA_IX2_200_DT=y
+CONFIG_MACH_KM_KIRKWOOD_DT=y
CONFIG_MACH_LSXL_DT=y
CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_NETSPACE_V2=y
@@ -48,6 +51,8 @@ CONFIG_LEDS_NETXBIG=m
CONFIG_RTC_DRV_MV=y
CONFIG_MV_XOR=y
CONFIG_CRYPTO_DEV_MV_CESA=m
+CONFIG_PINCTRL_MVEBU=y
+CONFIG_PINCTRL_KIRKWOOD=y
# CONFIG_CPU_FEROCEON_OLD_ID is not set
# CONFIG_INPUT_GP2A is not set
diff --git a/freed-ora/current/f18/config-arm-omap b/freed-ora/current/f18/config-arm-omap
index 8e314ce1d..68421b06e 100644
--- a/freed-ora/current/f18/config-arm-omap
+++ b/freed-ora/current/f18/config-arm-omap
@@ -176,6 +176,7 @@ CONFIG_TWL4030_POWER=y
CONFIG_TWL4030_CODEC=y
CONFIG_TWL4030_WATCHDOG=m
CONFIG_GPIO_TWL4030=m
+CONFIG_GPIO_TWL6040=m
CONFIG_CHARGER_TWL4030=m
CONFIG_TWL6030_PWM=m
CONFIG_TWL6040_CORE=y
@@ -185,19 +186,23 @@ CONFIG_TI_DAVINCI_MDIO=m
CONFIG_TI_DAVINCI_CPDMA=m
CONFIG_LEDS_PWM=m
+CONFIG_LEDS_LP8788=m
CONFIG_MTD_ONENAND_OMAP2=y
CONFIG_HDQ_MASTER_OMAP=m
CONFIG_I2C_OMAP=m
CONFIG_SPI_OMAP24XX=y
CONFIG_MFD_OMAP_USB_HOST=y
CONFIG_MFD_WL1273_CORE=m
+CONFIG_MFD_LP8788=y
CONFIG_REGULATOR_TWL4030=y
+CONFIG_REGULATOR_LP8788=y
# Enable V4L2 drivers for OMAP2+
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_VPFE_CAPTURE=m
CONFIG_VIDEO_OMAP2_VOUT=m
+CONFIG_VIDEO_DM6446_CCDC=m
# CONFIG_VIDEO_OMAP3 is not set
# Also enable vivi driver - useful for testing a full kernelspace V4L2 driver
CONFIG_V4L_TEST_DRIVERS=y
@@ -228,6 +233,7 @@ CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET=y
CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
CONFIG_PANEL_TFP410=m
+CONFIG_PANEL_TAAL=m
CONFIG_PANEL_PICODLP=m
CONFIG_BACKLIGHT_PANDORA=m
@@ -240,21 +246,22 @@ CONFIG_PANEL_NEC_NL8048HL11_01B=y
CONFIG_PANEL_TPO_TD043MTEA1=y
CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_MCBSP=y
-CONFIG_SND_OMAP_SOC_MCPDM=y
-CONFIG_SND_OMAP_SOC_OVERO=y
-CONFIG_SND_OMAP_SOC_OMAP3EVM=y
-CONFIG_SND_OMAP_SOC_AM3517EVM=y
-CONFIG_SND_OMAP_SOC_SDP3430=y
-CONFIG_SND_OMAP_SOC_SDP4430=y
-CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
-CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y
-CONFIG_SND_OMAP_SOC_ZOOM2=y
+CONFIG_SND_OMAP_SOC_MCBSP=m
+CONFIG_SND_OMAP_SOC_MCPDM=m
+CONFIG_SND_OMAP_SOC_OVERO=m
+CONFIG_SND_OMAP_SOC_OMAP3EVM=m
+CONFIG_SND_OMAP_SOC_AM3517EVM=m
+CONFIG_SND_OMAP_SOC_SDP3430=m
+CONFIG_SND_OMAP_SOC_SDP4430=m
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
+CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=m
+CONFIG_SND_OMAP_SOC_ZOOM2=m
CONFIG_SND_OMAP_SOC_IGEP0020=y
CONFIG_SND_OMAP_SOC_OMAP_HDMI=y
# Because alsa is modular http://www.spinics.net/lists/linux-omap/msg67307.html
# CONFIG_SND_OMAP_SOC_OMAP4_HDMI is not set
CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
+CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_OMAP_SOC_RX51 is not set
# CONFIG_SND_SOC_ALL_CODECS is not set
@@ -292,19 +299,21 @@ CONFIG_TWL4030_USB=y
CONFIG_TWL6030_USB=y
CONFIG_RTC_DRV_TWL4030=y
-CONFIG_TIDSPBRIDGE=m
-CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000
+CONFIG_IR_RX51=m
+
+# CONFIG_TIDSPBRIDGE is not set
+# CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE=0x600000
# CONFIG_TIDSPBRIDGE_DEBUG is not set
-CONFIG_TIDSPBRIDGE_RECOVERY=y
+# CONFIG_TIDSPBRIDGE_RECOVERY=y
# CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK is not set
-CONFIG_TIDSPBRIDGE_WDT3=y
-CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5
+# CONFIG_TIDSPBRIDGE_WDT3=y
+# CONFIG_TIDSPBRIDGE_WDT_TIMEOUT=5
# CONFIG_TIDSPBRIDGE_NTFY_PWRERR is not set
# CONFIG_TIDSPBRIDGE_BACKTRACE is not set
-CONFIG_OMAP_REMOTEPROC=m
-CONFIG_OMAP_BANDGAP=m
-CONFIG_OMAP_IOVMM=m
+# CONFIG_OMAP_REMOTEPROC is not set
+# CONFIG_OMAP_BANDGAP is not set
+# CONFIG_OMAP_IOVMM is not set
CONFIG_CRYPTO_DEV_OMAP_SHAM=m
CONFIG_CRYPTO_DEV_OMAP_AES=m
diff --git a/freed-ora/current/f18/config-arm-tegra b/freed-ora/current/f18/config-arm-tegra
index 78ddf0722..894b5dbef 100644
--- a/freed-ora/current/f18/config-arm-tegra
+++ b/freed-ora/current/f18/config-arm-tegra
@@ -18,7 +18,6 @@ CONFIG_MACH_WARIO=y
CONFIG_MACH_VENTANA=y
CONFIG_TEGRA_DEBUG_UARTD=y
-CONFIG_NR_CPUS=4
CONFIG_ARM_CPU_TOPOLOGY=y
CONFIG_TEGRA_IOMMU_GART=y
diff --git a/freed-ora/current/f18/config-arm-versatile b/freed-ora/current/f18/config-arm-versatile
index 89d4f7b09..758a78c76 100644
--- a/freed-ora/current/f18/config-arm-versatile
+++ b/freed-ora/current/f18/config-arm-versatile
@@ -95,3 +95,8 @@ CONFIG_PATA_OF_PLATFORM=m
# unset on versatille for jon masters
# CONFIG_GPIOLIB is not set
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_DRM_EXYNOS is not set
+
diff --git a/freed-ora/current/f18/config-generic b/freed-ora/current/f18/config-generic
index 23d6425b4..a60e6094d 100644
--- a/freed-ora/current/f18/config-generic
+++ b/freed-ora/current/f18/config-generic
@@ -190,30 +190,76 @@ CONFIG_EXTRA_FIRMWARE=""
# Memory Technology Devices (MTD)
#
CONFIG_MTD=m
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_TS5500 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+# Self-contained MTD device drivers
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
# CONFIG_MTD_DOCG3 is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_LPDDR is not set
CONFIG_MTD_UBI=m
-
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
#
# Parallel port support
@@ -433,6 +479,7 @@ CONFIG_ATA_BMDMA=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_SFF=y
CONFIG_ATA_PIIX=y
+# CONFIG_SATA_HIGHBANK is not set
CONFIG_ATA_ACPI=y
CONFIG_BLK_DEV_SX8=m
CONFIG_PDC_ADMA=m
@@ -603,6 +650,7 @@ CONFIG_TCP_MD5SIG=y
# Networking options
#
CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=m
CONFIG_NET_KEY=m
@@ -682,6 +730,7 @@ CONFIG_IPV6_MIP6=y
CONFIG_IPV6_SIT=m
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_GRE is not set
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_MROUTE=y
@@ -825,7 +874,6 @@ CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_ECN=m
@@ -833,6 +881,8 @@ CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
@@ -864,6 +914,9 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_NF_NAT_IPV6=m
+# CONFIG_IP6_NF_TARGET_MASQUERADE is not set
+# CONFIG_IP6_NF_TARGET_NPT is not set
#
# Bridge: Netfilter Configuration
@@ -1053,6 +1106,7 @@ CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_VETH=m
@@ -1305,6 +1359,7 @@ CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PHYLIB=y
+CONFIG_AT803X_PHY=m
CONFIG_AMD_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_BCM87XX_PHY=m
@@ -1360,6 +1415,7 @@ CONFIG_MLX4_EN_DCB=y
CONFIG_SFC=m
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
+CONFIG_SFC_PTP=y
# CONFIG_SFC_MTD is not set
@@ -1474,6 +1530,7 @@ CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_SDIO_OOB=y
CONFIG_BRCMFMAC_USB=y
+# CONFIG_BRCMISCAN is not set
# CONFIG_BRCMDBG is not set
# CONFIG_HERMES is not set
# CONFIG_HOSTAP is not set
@@ -2020,6 +2077,7 @@ CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
CONFIG_TCG_TPM=m
CONFIG_TCG_TIS=m
+# CONFIG_TCG_TIS_I2C_INFINEON is not set
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
# CONFIG_TCG_INFINEON is not set
@@ -2046,6 +2104,7 @@ CONFIG_CYCLADES=m
# CONFIG_ISI is not set
# CONFIG_RIO is not set
CONFIG_SERIAL_JSM=m
+# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_MFD_HSU is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
@@ -2054,6 +2113,7 @@ CONFIG_SERIAL_JSM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_KGDB_NMI is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_XILINX_PS_UART is not set
@@ -2142,6 +2202,7 @@ CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM1031=m
CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ADT7410=m
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_ADT7462=m
CONFIG_SENSORS_ADT7470=m
@@ -2261,6 +2322,7 @@ CONFIG_SENSORS_LTC2978=m
CONFIG_SENSORS_MAX34440=m
CONFIG_SENSORS_MAX8688=m
CONFIG_SENSORS_MAX1668=m
+CONFIG_SENSORS_MAX197=m
# CONFIG_HMC6352 is not set
# CONFIG_BMP085 is not set
@@ -2275,6 +2337,7 @@ CONFIG_W1_CON=y
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
CONFIG_W1_MASTER_DS1WM=m
+# CONFIG_HDQ_MASTER_OMAP is not set
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2408=m
@@ -2346,6 +2409,7 @@ CONFIG_W83697UG_WDT=m
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_HW_RANDOM_TPM=m
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_RTC_DEBUG is not set
@@ -2379,6 +2443,7 @@ CONFIG_RTC_DRV_RS5C372=m
# CONFIG_RTC_DRV_TEST is not set
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_V3020=m
+CONFIG_RTC_DRV_DS2404=m
CONFIG_RTC_DRV_STK17TA8=m
# CONFIG_RTC_DRV_S35390A is not set
CONFIG_RTC_DRV_RX8581=m
@@ -2436,6 +2501,8 @@ CONFIG_DRM_I915=m
CONFIG_DRM_I915_KMS=y
CONFIG_DRM_VIA=m
CONFIG_DRM_NOUVEAU=m
+CONFIG_NOUVEAU_DEBUG=5
+CONFIG_NOUVEAU_DEBUG_DEFAULT=3
CONFIG_DRM_NOUVEAU_BACKLIGHT=y
CONFIG_DRM_NOUVEAU_DEBUG=y
# CONFIG_DRM_PSB is not set
@@ -2443,6 +2510,7 @@ CONFIG_DRM_I2C_CH7006=m
CONFIG_DRM_I2C_SIL164=m
CONFIG_DRM_UDL=m
CONFIG_DRM_VMWGFX=m
+# CONFIG_DRM_VMWGFX_FBCON is not set
CONFIG_DRM_VGEM=m
#
@@ -2458,6 +2526,8 @@ CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=8192
CONFIG_HANGCHECK_TIMER=m
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_MEDIA_PCI_SUPPORT=y
#
# Multimedia devices
#
@@ -2515,6 +2585,7 @@ CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_IVTV=m
+# CONFIG_VIDEO_IVTV_ALSA is not set
CONFIG_VIDEO_MEYE=m
CONFIG_VIDEO_MXB=m
CONFIG_VIDEO_PVRUSB2_DVB=y
@@ -2526,6 +2597,8 @@ CONFIG_VIDEO_SAA7134_ALSA=m
CONFIG_VIDEO_SAA7134_DVB=m
CONFIG_VIDEO_SAA7134_RC=y
CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_STK1160=m
+CONFIG_VIDEO_STK1160_AC97=y
CONFIG_VIDEO_W9966=m
CONFIG_VIDEO_ZORAN=m
CONFIG_VIDEO_ZORAN_AVS6EYES=m
@@ -2589,6 +2662,7 @@ CONFIG_DVB_BT8XX=m
CONFIG_DVB_BUDGET_CORE=m
CONFIG_DVB_PLUTO2=m
CONFIG_SMS_SIANO_MDTV=m
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
CONFIG_SMS_USB_DRV=m
CONFIG_SMS_SDIO_DRV=m
CONFIG_DVB_TTUSB_DEC=m
@@ -2606,6 +2680,7 @@ CONFIG_DVB_FIREDTV=m
CONFIG_DVB_NGENE=m
CONFIG_DVB_DDBRIDGE=m
CONFIG_DVB_USB_TECHNISAT_USB2=m
+# CONFIG_DVB_USB_V2 is not set
CONFIG_DVB_AV7110=m
CONFIG_DVB_AV7110_OSD=y
@@ -2618,7 +2693,10 @@ CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_B2C2_FLEXCOP=m
+# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
+
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
CONFIG_DVB_B2C2_FLEXCOP_USB=m
# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
CONFIG_DVB_USB=m
@@ -2690,9 +2768,13 @@ CONFIG_IR_ENE=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_WINBOND_CIR=m
CONFIG_IR_IGUANA=m
+CONFIG_IR_TTUSBIR=m
CONFIG_IR_GPIO_CIR=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
+# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
#
@@ -3067,6 +3149,7 @@ CONFIG_HID_MULTITOUCH=m
CONFIG_HID_NTRIG=y
CONFIG_HID_QUANTA=y
CONFIG_HID_PRIMAX=m
+CONFIG_HID_PS3REMOTE=m
CONFIG_HID_PRODIKEYS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_HID_GYRATION=m
@@ -3086,6 +3169,7 @@ CONFIG_HID_TOPSEED=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_HID_ZEROPLUS=m
CONFIG_HID_ZYDACRON=m
+# CONFIG_HID_SENSOR_HUB is not set
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELECOM=m
CONFIG_HID_UCLOGIC=m
@@ -3277,6 +3361,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_ZTE is not set
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MOTOROLA=m
CONFIG_USB_SERIAL_NAVMAN=m
@@ -3317,6 +3402,7 @@ CONFIG_USB_ADUTUX=m
CONFIG_USB_SEVSEG=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_APPLEDISPLAY=m
+# CONFIG_OMAP_USB2 is not set
CONFIG_USB_ATM=m
CONFIG_USB_CXACRU=m
# CONFIG_USB_C67X00_HCD is not set
@@ -3335,6 +3421,7 @@ CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_IOWARRIOR=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
+CONFIG_USB_EZUSB_FX2=m
CONFIG_USB_LCD=m
CONFIG_USB_LD=m
CONFIG_USB_LEGOTOWER=m
@@ -3585,6 +3672,7 @@ CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_SMB2=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
@@ -3756,6 +3844,7 @@ CONFIG_DEBUG_NX_TEST=m
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_DEBUG_INFO_REDUCED is not set
@@ -3769,7 +3858,6 @@ CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_BACKTRACE_SELF_TEST is not set
CONFIG_LATENCYTOP=y
CONFIG_RESOURCE_COUNTERS=y
-# CONFIG_MEMCG is not set
# CONFIG_COMPAT_BRK is not set
# CONFIG_DEBUG_VIRTUAL is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
@@ -3920,6 +4008,8 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_PROGEAR=m
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
CONFIG_FB_NVIDIA_BACKLIGHT=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_RADEON_BACKLIGHT=y
@@ -3971,10 +4061,15 @@ CONFIG_KEXEC=y
CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
CONFIG_THERMAL_HWMON=y
+# CONFIG_CPU_THERMAL is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
+#
+# Bus devices
+#
+# CONFIG_OMAP_OCP2SCP is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
@@ -4009,6 +4104,8 @@ CONFIG_NET_VENDOR_SMC=y
# CONFIG_MOUSE_ATIXL is not set
+# CONFIG_MEDIA_PARPORT_SUPPORT is not set
+
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_TEA5764=m
CONFIG_RADIO_SAA7706H=m
@@ -4055,6 +4152,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA9633 is not set
CONFIG_LEDS_DELL_NETBOOKS=m
# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_OT200 is not set
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
@@ -4062,12 +4160,14 @@ CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+# CONFIG_LEDS_TRIGGER_CPU is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_ALIX2=m
CONFIG_LEDS_CLEVO_MAIL=m
CONFIG_LEDS_INTEL_SS4200=m
CONFIG_LEDS_LM3530=m
+# CONFIG_LEDS_LM3642 is not set
CONFIG_LEDS_LM3556=m
CONFIG_LEDS_BLINKM=m
CONFIG_LEDS_LP3944=m
@@ -4101,6 +4201,8 @@ CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
CONFIG_FUNCTION_PROFILER=y
CONFIG_RING_BUFFER_BENCHMARK=m
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
CONFIG_FUNCTION_TRACER=y
CONFIG_STACK_TRACER=y
# CONFIG_FUNCTION_GRAPH_TRACER is not set
@@ -4316,9 +4418,19 @@ CONFIG_ALTERA_STAPL=m
# CONFIG_WIMAX_GDM72XX is not set
# CONFIG_IPACK_BUS is not set
# CONFIG_CSR_WIFI is not set
-#
+# CONFIG_ZCACHE2 is not set
+# CONFIG_NET_VENDOR_SILICOM is not set
+# CONFIG_SBYPASS is not set
+# CONFIG_BPCTL is not set
+# CONFIG_CED1401 is not set
+# CONFIG_DGRP is not set
# END OF STAGING
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
CONFIG_FCOE=m
diff --git a/freed-ora/current/f18/config-powerpc-generic b/freed-ora/current/f18/config-powerpc-generic
index a263acc80..a6ef1c4df 100644
--- a/freed-ora/current/f18/config-powerpc-generic
+++ b/freed-ora/current/f18/config-powerpc-generic
@@ -372,3 +372,11 @@ CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_FAIL_IOMMU is not set
+
+# CONFIG_PPC_DENORMALISATION is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_GPIO_ADNP is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
+
diff --git a/freed-ora/current/f18/config-powerpc64 b/freed-ora/current/f18/config-powerpc64
index 82f4c603b..7c0477cf1 100644
--- a/freed-ora/current/f18/config-powerpc64
+++ b/freed-ora/current/f18/config-powerpc64
@@ -167,7 +167,10 @@ CONFIG_HW_RANDOM_AMD=m
CONFIG_UIO_PDRV=m
CONFIG_HW_RANDOM_PSERIES=m
-CONFIG_CRYPTO_DEV_NX=m
+CONFIG_CRYPTO_DEV_NX=y
+CONFIG_CRYPTO_842=m
+CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
+CONFIG_CRYPTO_DEV_NX_COMPRESS=m
CONFIG_BPF_JIT=y
diff --git a/freed-ora/current/f18/config-powerpc64p7 b/freed-ora/current/f18/config-powerpc64p7
index e8e826a88..9a8289588 100644
--- a/freed-ora/current/f18/config-powerpc64p7
+++ b/freed-ora/current/f18/config-powerpc64p7
@@ -158,7 +158,10 @@ CONFIG_HW_RANDOM_AMD=m
CONFIG_UIO_PDRV=m
CONFIG_HW_RANDOM_PSERIES=m
-CONFIG_CRYPTO_DEV_NX=m
+CONFIG_CRYPTO_DEV_NX=y
+CONFIG_CRYPTO_842=m
+CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
+CONFIG_CRYPTO_DEV_NX_COMPRESS=m
CONFIG_BPF_JIT=y
diff --git a/freed-ora/current/f18/config-s390x b/freed-ora/current/f18/config-s390x
index 451512e9a..41e41c53c 100644
--- a/freed-ora/current/f18/config-s390x
+++ b/freed-ora/current/f18/config-s390x
@@ -241,3 +241,12 @@ CONFIG_STRICT_DEVMEM=y
CONFIG_CRYPTO_GHASH_S390=m
CONFIG_NET_CORE=y
CONFIG_ETHERNET=y
+
+CONFIG_BPF_JIT=y
+# CONFIG_TRANSPARENT_HUGEPAGE is not set
+# CONFIG_SCM_BUS is not set
+# CONFIG_EADM_SCH is not set
+# CONFIG_SCM_BLOCK is not set
+# CONFIG_SCM_BLOCK_CLUSTER_WRITE is not set
+# CONFIG_S390_PTDUMP is not set
+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
diff --git a/freed-ora/current/f18/config-sparc64-generic b/freed-ora/current/f18/config-sparc64-generic
index ebc891d8a..e15e2ef18 100644
--- a/freed-ora/current/f18/config-sparc64-generic
+++ b/freed-ora/current/f18/config-sparc64-generic
@@ -201,3 +201,17 @@ CONFIG_CRYPTO_DEV_NIAGARA2=y
CONFIG_BPF_JIT=y
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_IRQ_DOMAIN_DEBUG is not set
+
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_RTC_DRV_SNVS is not set
+# CONFIG_CRYPTO_CRC32C_SPARC64 is not set
+# CONFIG_CRYPTO_MD5_SPARC64 is not set
+# CONFIG_CRYPTO_SHA1_SPARC64 is not set
+# CONFIG_CRYPTO_SHA256_SPARC64 is not set
+# CONFIG_CRYPTO_SHA512_SPARC64 is not set
+# CONFIG_CRYPTO_AES_SPARC64 is not set
+# CONFIG_CRYPTO_CAMELLIA_SPARC64 is not set
+# CONFIG_CRYPTO_DES_SPARC64 is not set
+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
+
diff --git a/freed-ora/current/f18/config-x86-32-generic b/freed-ora/current/f18/config-x86-32-generic
index b1a04993a..1216d47e6 100644
--- a/freed-ora/current/f18/config-x86-32-generic
+++ b/freed-ora/current/f18/config-x86-32-generic
@@ -190,6 +190,7 @@ CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m
# CONFIG_X86_INTEL_MID is not set
CONFIG_MFD_CS5535=m
+# CONFIG_MFD_SYSCON is not set
# I2O enabled only for 32-bit x86, disabled for PAE kernel
CONFIG_I2O=m
@@ -211,5 +212,8 @@ CONFIG_I2O_BUS=m
# CONFIG_GEOS is not set
# CONFIG_NET5501 is not set
# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
# CONFIG_GPIO_SODAVILLE is not set
+# CONFIG_GPIO_ADNP is not set
# CONFIG_BACKLIGHT_OT200 is not set
+# CONFIG_RTC_DRV_SNVS is not set
diff --git a/freed-ora/current/f18/config-x86-generic b/freed-ora/current/f18/config-x86-generic
index b26f42d9f..2bcd498eb 100644
--- a/freed-ora/current/f18/config-x86-generic
+++ b/freed-ora/current/f18/config-x86-generic
@@ -91,10 +91,11 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y
# CONFIG_ACPI_APEI_EINJ is not set
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_CUSTOM_METHOD=m
-CONFIG_ACPI_BGRT=m
+CONFIG_ACPI_BGRT=y
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_PCC_CPUFREQ=y
+CONFIG_X86_ACPI_CPUFREQ_CPB=y
CONFIG_X86_POWERNOW_K8=y
CONFIG_X86_P4_CLOCKMOD=y
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
diff --git a/freed-ora/current/f18/config-x86_64-generic b/freed-ora/current/f18/config-x86_64-generic
index 342b8620a..6003f11c0 100644
--- a/freed-ora/current/f18/config-x86_64-generic
+++ b/freed-ora/current/f18/config-x86_64-generic
@@ -46,6 +46,8 @@ CONFIG_CRYPTO_SHA1_SSSE3=m
CONFIG_CRYPTO_BLOWFISH_X86_64=m
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m
CONFIG_CRYPTO_CAMELLIA_X86_64=m
+CONFIG_CRYPTO_CAST5_AVX_X86_64=m
+CONFIG_CRYPTO_CAST6_AVX_X86_64=m
CONFIG_CRYPTO_SERPENT_AVX_X86_64=m
CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m
@@ -107,6 +109,7 @@ CONFIG_X86_X2APIC=y
CONFIG_SPARSE_IRQ=y
CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_USER_QS is not set
CONFIG_INTEL_TXT=y
diff --git a/freed-ora/current/f18/deblob-3.6 b/freed-ora/current/f18/deblob-3.7
index 1c6f38230..cfe46d94b 100755
--- a/freed-ora/current/f18/deblob-3.6
+++ b/freed-ora/current/f18/deblob-3.7
@@ -48,7 +48,7 @@
# For each kver release, start extra with an empty string, then count
# from 1 if changes are needed that require rebuilding the tarball.
-kver=3.6 extra=
+kver=3.7 extra=
case $1 in
--force)
@@ -80,6 +80,7 @@ if [ ! -f $check ] ; then
have_check=false
else
have_check=:
+ [ -x $check ] || check="/bin/sh $check"
fi
filetest () {
@@ -116,7 +117,13 @@ clean_blob () {
name=$1
set fnord "$@" -d
shift 2
- $check "$@" -i linux-$kver $name > $name.deblob
+ if $check "$@" -i linux-$kver $name > $name.deblob; then
+ if [ ! -s $name.deblob ]; then
+ die got an empty file after removing blobs from $name
+ fi
+ else
+ die failed removing blobs from $name
+ fi
check_changed $name && echo $name: removed blobs
else
clean_file $1
@@ -208,7 +215,7 @@ maybe_reject_firmware () {
#$1 = file $2 = pre sed pattern
filetest $1 || return
clean_sed "$2"'
-s,request_firmware\(_nowait\)\?,maybe_reject_firmware\1,g
+s,request_\(ihex_\)\?firmware\(_nowait\)\?,maybe_reject_\1firmware\2,g
' "$1" 'retain Free firmware-loading machinery, disabling non-Free one'
}
@@ -238,34 +245,40 @@ undefault_firmware () {
# corresponding sources are present.
for f in \
- drivers/char/ser_a2232fw.h \
- drivers/char/ser_a2232fw.ax \
- drivers/gpu/drm/nouveau/nva3_copy.fuc.h \
- drivers/gpu/drm/nouveau/nva3_copy.fuc \
- drivers/gpu/drm/nouveau/nvc0_copy.fuc.h \
- drivers/gpu/drm/nouveau/nva3_copy.fuc \
- drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h \
- drivers/gpu/drm/nouveau/nvc0_grgpc.fuc \
- drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h \
- drivers/gpu/drm/nouveau/nvc0_grhub.fuc \
- drivers/net/ixp2000/ixp2400_rx.ucode \
- drivers/net/ixp2000/ixp2400_rx.uc \
- drivers/net/ixp2000/ixp2400_tx.ucode \
- drivers/net/ixp2000/ixp2400_rx.uc \
+ drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc \
+ drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc \
+ drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h \
+ drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc \
drivers/net/wan/wanxlfw.inc_shipped \
drivers/net/wan/wanxlfw.S \
drivers/net/wireless/atmel.c \
drivers/net/wireless/atmel.c \
- drivers/scsi/53c700_d.h_shipped \
- drivers/scsi/53c700.scr \
drivers/scsi/aic7xxx/aic79xx_seq.h_shipped \
drivers/scsi/aic7xxx/aic79xx.seq \
drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped \
drivers/scsi/aic7xxx/aic7xxx.seq \
drivers/scsi/aic7xxx_old/aic7xxx_seq.c \
drivers/scsi/aic7xxx_old/aic7xxx.seq \
- drivers/scsi/53c7xx_d.h_shipped \
- drivers/scsi/53c7xx.scr \
+ drivers/scsi/53c700_d.h_shipped \
+ drivers/scsi/53c700.scr \
drivers/scsi/sym53c8xx_2/sym_fw1.h \
drivers/scsi/sym53c8xx_2/sym_fw1.h \
drivers/scsi/sym53c8xx_2/sym_fw2.h \
@@ -278,12 +291,8 @@ for f in \
firmware/keyspan_pda/xircom_pgs.S \
sound/pci/cs46xx/imgs/cwcdma.h \
sound/pci/cs46xx/imgs/cwcdma.asp \
- firmware/isci/isci_firmware.bin.ihex \
- drivers/scsi/isci/firmware/create_fw.c \
; do
- if test ! $f; then
- die $f is not present, something is amiss && return
- fi
+ filetest $f
done
# Identify the tarball.
@@ -407,6 +416,24 @@ maybe_reject_firmware_nowait(struct module *module, int uevent,\
#endif /* _LINUX_LIBRE_FIRMWARE_H */\
' include/linux/firmware.h 'added non-Free firmware notification support'
+grep -q _LINUX_LIBRE_IHEX_FIRMWARE_H include/linux/ihex.h ||
+clean_sed '$i\
+#ifndef _LINUX_LIBRE_IHEX_H\
+#define _LINUX_LIBRE_IHEX_H\
+\
+static inline int\
+maybe_reject_ihex_firmware(const struct firmware **fw,\
+ const char *name, struct device *device)\
+{\
+ if (strstr (name, NONFREE_FIRMWARE))\
+ return reject_firmware(fw, name, device);\
+ else\
+ return request_ihex_firmware(fw, name, device);\
+}\
+\
+#endif /* _LINUX_LIBRE_IHEX_H */\
+' include/linux/ihex.h 'added non-Free ihex firmware notification support'
+
########
# Arch #
########
@@ -429,7 +456,10 @@ clean_mk CONFIG_MICROCODE_INTEL arch/x86/kernel/Makefile
announce IXP4XX_NPE - "IXP4xx Network Processor Engine support"
reject_firmware arch/arm/mach-ixp4xx/ixp4xx_npe.c
+clean_blob arch/arm/mach-ixp4xx/ixp4xx_npe.c
clean_blob Documentation/arm/IXP4xx
+clean_kconfig arch/arm/mach-ixp4xx/Kconfig 'ARCH_IXP4XX'
+clean_mk CONFIG_IXP4XX_NPE arch/arm/mach-ixp4xx/Makefile
announce ARCH_NETX - "Hilscher NetX based"
clean_sed '
@@ -470,9 +500,6 @@ clean_mk CONFIG_ATM_SOLOS drivers/atm/Makefile
# tty #
########
-announce COMPUTONE - "Computone IntelliPort Plus serial"
-drop_fw_file firmware/intelliport2.bin.ihex firmware/intelliport2.bin
-
announce CYCLADES - "Cyclades async mux support"
reject_firmware drivers/tty/cyclades.c
clean_blob drivers/tty/cyclades.c
@@ -494,10 +521,8 @@ clean_mk CONFIG_MOXA_INTELLIO drivers/tty/Makefile
# gpu drm
announce DRM_NOUVEAU - "Nouveau (nVidia) cards"
-reject_firmware drivers/gpu/drm/nouveau/nvc0_graph.c
-clean_blob drivers/gpu/drm/nouveau/nvc0_graph.c
-reject_firmware drivers/gpu/drm/nouveau/nve0_graph.c
-clean_blob drivers/gpu/drm/nouveau/nve0_graph.c
+reject_firmware drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+clean_blob drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
clean_kconfig drivers/gpu/drm/nouveau/Kconfig 'DRM_NOUVEAU'
clean_mk CONFIG_DRM_NOUVEAU drivers/gpu/drm/nouveau/Makefile
@@ -568,11 +593,9 @@ reject_firmware drivers/dma/imx-sdma.c
clean_blob arch/arm/mach-imx/mm-imx25.c
clean_blob arch/arm/mach-imx/mm-imx3.c
clean_blob arch/arm/mach-imx/mm-imx5.c
-clean_blob arch/arm/boot/dts/imx51-babbage.dts
-clean_blob arch/arm/boot/dts/imx53-ard.dts
-clean_blob arch/arm/boot/dts/imx53-evk.dts
-clean_blob arch/arm/boot/dts/imx53-qsb.dts
-clean_blob arch/arm/boot/dts/imx53-smd.dts
+clean_blob arch/arm/boot/dts/imx51.dtsi
+clean_blob arch/arm/boot/dts/imx53.dtsi
+clean_blob arch/arm/boot/dts/imx6q.dtsi
clean_blob Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
clean_kconfig drivers/dma/Kconfig 'IMX_SDMA'
clean_mk CONFIG_IMX_SDMA drivers/dma/Makefile
@@ -585,292 +608,299 @@ clean_mk CONFIG_IMX_SDMA drivers/dma/Makefile
announce MEDIA_TUNER_XC2028 - "XCeive xc2028/xc3028 tuners"
undefault_firmware 'XC\(2028\|3028L\)' \
- drivers/media/common/tuners/tuner-xc2028.h \
- drivers/media/video/saa7134/saa7134-cards.c \
- drivers/media/video/ivtv/ivtv-driver.c \
- drivers/media/video/cx18/cx18-driver.c \
- drivers/media/video/cx18/cx18-dvb.c \
- drivers/media/video/cx23885/cx23885-dvb.c \
- drivers/media/video/cx23885/cx23885-video.c \
- drivers/media/video/cx88/cx88-dvb.c \
- drivers/media/video/cx88/cx88-cards.c \
- drivers/media/video/em28xx/em28xx-cards.c \
- drivers/media/dvb/dvb-usb/dib0700_devices.c \
- drivers/media/dvb/dvb-usb/cxusb.c
-reject_firmware drivers/media/common/tuners/tuner-xc2028.c
-clean_blob drivers/media/common/tuners/tuner-xc2028.c
-clean_kconfig drivers/media/common/tuners/Kconfig 'MEDIA_TUNER_XC2028'
-clean_mk CONFIG_MEDIA_TUNER_XC2028 drivers/media/common/tuners/Makefile
+ drivers/media/tuners/tuner-xc2028.h \
+ drivers/media/pci/saa7134/saa7134-cards.c \
+ drivers/media/pci/ivtv/ivtv-driver.c \
+ drivers/media/pci/cx18/cx18-driver.c \
+ drivers/media/pci/cx18/cx18-dvb.c \
+ drivers/media/pci/cx23885/cx23885-dvb.c \
+ drivers/media/pci/cx23885/cx23885-video.c \
+ drivers/media/pci/cx88/cx88-dvb.c \
+ drivers/media/pci/cx88/cx88-cards.c \
+ drivers/media/usb/em28xx/em28xx-cards.c \
+ drivers/media/usb/dvb-usb/dib0700_devices.c \
+ drivers/media/usb/dvb-usb/cxusb.c
+reject_firmware drivers/media/tuners/tuner-xc2028.c
+clean_blob drivers/media/tuners/tuner-xc2028.c
+clean_kconfig drivers/media/tuners/Kconfig 'MEDIA_TUNER_XC2028'
+clean_mk CONFIG_MEDIA_TUNER_XC2028 drivers/media/tuners/Makefile
announce VIDEO_TM6000_DVB - "DVB Support for tm6000 based TV cards"
-clean_blob drivers/media/video/tm6000/tm6000-cards.c
-clean_kconfig drivers/media/video/tm6000/Kconfig 'VIDEO_TM6000_DVB'
-clean_mk CONFIG_VIDEO_TM6000_DVB drivers/media/video/tm6000/Makefile
+clean_blob drivers/media/usb/tm6000/tm6000-cards.c
+clean_kconfig drivers/media/usb/tm6000/Kconfig 'VIDEO_TM6000_DVB'
+clean_mk CONFIG_VIDEO_TM6000_DVB drivers/media/usb/tm6000/Makefile
announce MEDIA_TUNER_XC4000 - "Xceive XC4000 silicon tuner"
-undefault_firmware 'XC4000' drivers/media/common/tuners/xc4000.c
-maybe_reject_firmware drivers/media/common/tuners/xc4000.c
-clean_kconfig drivers/media/common/tuners/Kconfig 'MEDIA_TUNER_XC4000'
-clean_mk CONFIG_MEDIA_TUNER_XC4000 drivers/media/common/tuners/Makefile
+undefault_firmware 'XC4000' drivers/media/tuners/xc4000.c
+maybe_reject_firmware drivers/media/tuners/xc4000.c
+clean_kconfig drivers/media/tuners/Kconfig 'MEDIA_TUNER_XC4000'
+clean_mk CONFIG_MEDIA_TUNER_XC4000 drivers/media/tuners/Makefile
announce MEDIA_TUNER_XC5000 - "Xceive XC5000 silicon tuner"
undefault_firmware 'XC5000' \
- drivers/media/video/cx231xx/cx231xx-cards.c
-reject_firmware drivers/media/common/tuners/xc5000.c
-clean_blob drivers/media/common/tuners/xc5000.c
-clean_kconfig drivers/media/common/tuners/Kconfig 'MEDIA_TUNER_XC5000'
-clean_mk CONFIG_MEDIA_TUNER_XC5000 drivers/media/common/tuners/Makefile
+ drivers/media/usb/cx231xx/cx231xx-cards.c
+reject_firmware drivers/media/tuners/xc5000.c
+clean_blob drivers/media/tuners/xc5000.c
+clean_kconfig drivers/media/tuners/Kconfig 'MEDIA_TUNER_XC5000'
+clean_mk CONFIG_MEDIA_TUNER_XC5000 drivers/media/tuners/Makefile
announce DVB_USB - "Support for various USB DVB devices"
-reject_firmware drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB'
-clean_mk CONFIG_DVB_USB drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB'
+clean_mk CONFIG_DVB_USB drivers/media/usb/dvb-usb/Makefile
+
+announce DVB_USB_V2 - "Support for various USB DVB devices v2"
+reject_firmware drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_V2'
+clean_mk CONFIG_DVB_USB_V2 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_B2C2_FLEXCOP - "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
-reject_firmware drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+reject_firmware drivers/media/common/b2c2/flexcop-fe-tuner.c
announce DVB_BT8XX - "BT8xx based PCI cards"
-reject_firmware drivers/media/dvb/bt8xx/dvb-bt8xx.c
+reject_firmware drivers/media/pci/bt8xx/dvb-bt8xx.c
announce DVB_USB_A800 - "AVerMedia AverTV DVB-T USB 2.0 (A800)"
-clean_blob drivers/media/dvb/dvb-usb/a800.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_A800'
-clean_mk CONFIG_DVB_USB_A800 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/a800.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_A800'
+clean_mk CONFIG_DVB_USB_A800 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_AF9005 - "Afatech AF9005 DVB-T USB1.1 support"
-clean_file drivers/media/dvb/dvb-usb/af9005-script.h
+clean_file drivers/media/usb/dvb-usb/af9005-script.h
clean_sed '
s,^ deb_info("load init script\\n");$, {\n err("Missing Free init script\\n");\n return scriptlen = ret = -EINVAL;\n ,;
-' drivers/media/dvb/dvb-usb/af9005-fe.c 'report missing Free init script'
-clean_blob drivers/media/dvb/dvb-usb/af9005-fe.c
-clean_blob drivers/media/dvb/dvb-usb/af9005.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_AF9005'
-clean_mk CONFIG_DVB_USB_AF9005 drivers/media/dvb/dvb-usb/Makefile
+' drivers/media/usb/dvb-usb/af9005-fe.c 'report missing Free init script'
+clean_blob drivers/media/usb/dvb-usb/af9005-fe.c
+clean_blob drivers/media/usb/dvb-usb/af9005.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_AF9005'
+clean_mk CONFIG_DVB_USB_AF9005 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_AF9015 - "Afatech AF9015 DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/af9015.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_AF9015'
-clean_mk CONFIG_DVB_USB_AF9015 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb-v2/af9015.h
+clean_blob drivers/media/usb/dvb-usb-v2/af9015.c
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_AF9015'
+clean_mk CONFIG_DVB_USB_AF9015 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_AF9035 - "Afatech AF9035 DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/af9035.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_AF9035'
-clean_mk CONFIG_DVB_USB_AF9035 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb-v2/af9035.h
+clean_blob drivers/media/usb/dvb-usb-v2/af9035.c
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_AF9035'
+clean_mk CONFIG_DVB_USB_AF9035 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_AZ6007 - "Azurewave 6007 and clones DVB-T/C USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/az6007.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_AZ6007'
-clean_mk CONFIG_DVB_USB_AZ6007 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb-v2/az6007.c
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_AZ6007'
+clean_mk CONFIG_DVB_USB_AZ6007 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_AZ6027 - "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
-clean_blob drivers/media/dvb/dvb-usb/az6027.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_AZ6027'
-clean_mk CONFIG_DVB_USB_AZ6027 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/az6027.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_AZ6027'
+clean_mk CONFIG_DVB_USB_AZ6027 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_CXUSB - "Conexant USB2.0 hybrid reference design support"
-clean_blob drivers/media/dvb/dvb-usb/cxusb.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_CXUSB'
-clean_mk CONFIG_DVB_USB_CXUSB drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/cxusb.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_CXUSB'
+clean_mk CONFIG_DVB_USB_CXUSB drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DIB0700 - "DiBcom DiB0700 USB DVB devices"
-reject_firmware drivers/media/dvb/dvb-usb/dib0700_devices.c
-clean_blob drivers/media/dvb/dvb-usb/dib0700_devices.c
-clean_blob drivers/media/dvb/dvb-usb/dib0700_core.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DIB0700'
-clean_mk CONFIG_DVB_USB_DIB0700 drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/dib0700_devices.c
+clean_blob drivers/media/usb/dvb-usb/dib0700_devices.c
+clean_blob drivers/media/usb/dvb-usb/dib0700_core.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DIB0700'
+clean_mk CONFIG_DVB_USB_DIB0700 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DIBUSB_MB - "DiBcom USB DVB-T devices (based on the DiB3000M-B)"
-clean_blob drivers/media/dvb/dvb-usb/dibusb-mb.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DIBUSB_MB'
-clean_mk CONFIG_DVB_USB_DIBUSB_MB drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/dibusb-mb.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DIBUSB_MB'
+clean_mk CONFIG_DVB_USB_DIBUSB_MB drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DIBUSB_MC - "DiBcom USB DVB-T devices (based on the DiB3000M-C/P)"
-clean_blob drivers/media/dvb/dvb-usb/dibusb-mc.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DIBUSB_MC'
-clean_mk CONFIG_DVB_USB_DIBUSB_MC drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/dibusb-mc.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DIBUSB_MC'
+clean_mk CONFIG_DVB_USB_DIBUSB_MC drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DIGITV - "Nebula Electronics uDigiTV DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/digitv.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DIGITV'
-clean_mk CONFIG_DVB_USB_DIGITV drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/digitv.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DIGITV'
+clean_mk CONFIG_DVB_USB_DIGITV drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DTT200U - "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
-clean_blob drivers/media/dvb/dvb-usb/dtt200u.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DTT200U'
-clean_mk CONFIG_DVB_USB_DTT200U drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/dtt200u.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DTT200U'
+clean_mk CONFIG_DVB_USB_DTT200U drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_DW2102 - "DvbWorld DVB-S/S2 USB2.0 support"
-reject_firmware drivers/media/dvb/dvb-usb/dw2102.c
-clean_blob drivers/media/dvb/dvb-usb/dw2102.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_DW2102'
-clean_mk CONFIG_DVB_USB_DW2102 drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/dw2102.c
+clean_blob drivers/media/usb/dvb-usb/dw2102.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_DW2102'
+clean_mk CONFIG_DVB_USB_DW2102 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_EC168 - "E3C EC168 DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/ec168.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_EC168'
-clean_mk CONFIG_DVB_USB_EC168 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb-v2/ec168.h
+clean_blob drivers/media/usb/dvb-usb-v2/ec168.c
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_EC168'
+clean_mk CONFIG_DVB_USB_EC168 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_GP8PSK - "GENPIX 8PSK->USB module support"
-reject_firmware drivers/media/dvb/dvb-usb/gp8psk.c
-clean_blob drivers/media/dvb/dvb-usb/gp8psk.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_GP8PSK'
-clean_mk CONFIG_DVB_USB_GP8PSK drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/gp8psk.c
+clean_blob drivers/media/usb/dvb-usb/gp8psk.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_GP8PSK'
+clean_mk CONFIG_DVB_USB_GP8PSK drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_IT913X - "it913x driver"
-clean_blob drivers/media/dvb/dvb-usb/it913x.c
+clean_blob drivers/media/usb/dvb-usb-v2/it913x.c
clean_file Documentation/dvb/it9137.txt
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_IT913X'
-clean_mk CONFIG_DVB_USB_IT913X drivers/media/dvb/dvb-usb/Makefile
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_IT913X'
+clean_mk CONFIG_DVB_USB_IT913X drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_LME2510 - "LME DM04/QQBOX DVB-S USB2.0 support"
-reject_firmware drivers/media/dvb/dvb-usb/lmedm04.c
-clean_blob drivers/media/dvb/dvb-usb/lmedm04.c
+reject_firmware drivers/media/usb/dvb-usb-v2/lmedm04.c
+clean_blob drivers/media/usb/dvb-usb-v2/lmedm04.c
clean_file Documentation/dvb/lmedm04.txt
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_LME2510'
-clean_mk CONFIG_DVB_USB_LME2510 drivers/media/dvb/dvb-usb/Makefile
+clean_kconfig drivers/media/usb/dvb-usb-v2/Kconfig 'DVB_USB_LME2510'
+clean_mk CONFIG_DVB_USB_LME2510 drivers/media/usb/dvb-usb-v2/Makefile
announce DVB_USB_M920X - "Uli m920x DVB-T USB2.0 support"
-reject_firmware drivers/media/dvb/dvb-usb/m920x.c
-clean_blob drivers/media/dvb/dvb-usb/m920x.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_M920X'
-clean_mk CONFIG_DVB_USB_M920X drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/m920x.c
+clean_blob drivers/media/usb/dvb-usb/m920x.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_M920X'
+clean_mk CONFIG_DVB_USB_M920X drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_NOVA_T_USB2 - "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/nova-t-usb2.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_NOVA_T_USB2'
-clean_mk CONFIG_DVB_USB_NOVA_T_USB2 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/nova-t-usb2.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_NOVA_T_USB2'
+clean_mk CONFIG_DVB_USB_NOVA_T_USB2 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_OPERA1 - "Opera1 DVB-S USB2.0 receiver"
-reject_firmware drivers/media/dvb/dvb-usb/opera1.c
-clean_blob drivers/media/dvb/dvb-usb/opera1.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_OPERA1'
-clean_mk CONFIG_DVB_USB_OPERA1 drivers/media/dvb/dvb-usb/Makefile
+reject_firmware drivers/media/usb/dvb-usb/opera1.c
+clean_blob drivers/media/usb/dvb-usb/opera1.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_OPERA1'
+clean_mk CONFIG_DVB_USB_OPERA1 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_TECHNISAT_USB2 - "Technisat DVB-S/S2 USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/technisat-usb2.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_TECHNISAT_USB2'
-clean_mk CONFIG_DVB_USB_TECHNISAT_USB2 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/technisat-usb2.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_TECHNISAT_USB2'
+clean_mk CONFIG_DVB_USB_TECHNISAT_USB2 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_TTUSB2 - "Pinnacle 400e DVB-S USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/ttusb2.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_TTUSB2'
-clean_mk CONFIG_DVB_USB_TTUSB2 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/ttusb2.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_TTUSB2'
+clean_mk CONFIG_DVB_USB_TTUSB2 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_UMT_010 - "HanfTek UMT-010 DVB-T USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/umt-010.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_UMT_010'
-clean_mk CONFIG_DVB_USB_UMT_010 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/umt-010.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_UMT_010'
+clean_mk CONFIG_DVB_USB_UMT_010 drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_VP702X - "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/vp702x.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_VP702X'
-clean_mk CONFIG_DVB_USB_VP702X drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/vp702x.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_VP702X'
+clean_mk CONFIG_DVB_USB_VP702X drivers/media/usb/dvb-usb/Makefile
announce DVB_USB_VP7045 - "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
-clean_blob drivers/media/dvb/dvb-usb/vp7045.c
-clean_kconfig drivers/media/dvb/dvb-usb/Kconfig 'DVB_USB_VP7045'
-clean_mk CONFIG_DVB_USB_VP7045 drivers/media/dvb/dvb-usb/Makefile
+clean_blob drivers/media/usb/dvb-usb/vp7045.c
+clean_kconfig drivers/media/usb/dvb-usb/Kconfig 'DVB_USB_VP7045'
+clean_mk CONFIG_DVB_USB_VP7045 drivers/media/usb/dvb-usb/Makefile
# dvb/frontends
announce DVB_AF9013 - "Afatech AF9013 demodulator"
-undefault_firmware 'AF9013' \
- drivers/media/dvb/frontends/af9013.c \
- drivers/media/dvb/frontends/af9013_priv.h
-reject_firmware drivers/media/dvb/frontends/af9013.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_AF9013'
-clean_mk CONFIG_DVB_AF9013 drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/af9013.c
+clean_blob drivers/media/dvb-frontends/af9013.c
+clean_blob drivers/media/dvb-frontends/af9013_priv.h
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_AF9013'
+clean_mk CONFIG_DVB_AF9013 drivers/media/dvb-frontends/Makefile
announce DVB_BCM3510 - "Broadcom BCM3510"
-undefault_firmware 'BCM3510' drivers/media/dvb/frontends/bcm3510.c
-reject_firmware drivers/media/dvb/frontends/bcm3510.c
-reject_firmware drivers/media/dvb/frontends/bcm3510.h
+undefault_firmware 'BCM3510' drivers/media/dvb-frontends/bcm3510.c
+reject_firmware drivers/media/dvb-frontends/bcm3510.c
+reject_firmware drivers/media/dvb-frontends/bcm3510.h
clean_sed '
/You.ll need a firmware/,/dvb-fe-bcm/d;
-' drivers/media/dvb/frontends/bcm3510.c \
+' drivers/media/dvb-frontends/bcm3510.c \
"removed non-Free firmware notes"
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_BCM3510'
-clean_mk CONFIG_DVB_BCM3510 drivers/media/dvb/frontends/Makefile
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_BCM3510'
+clean_mk CONFIG_DVB_BCM3510 drivers/media/dvb-frontends/Makefile
announce DVB_DS3000 - "Montage Tehnology DS3000 based"
undefault_firmware 'DS3000' \
- drivers/media/dvb/frontends/ds3000.c
-reject_firmware drivers/media/dvb/frontends/ds3000.c
-clean_blob drivers/media/dvb/frontends/ds3000.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_DS3000'
-clean_mk CONFIG_DVB_DS3000 drivers/media/dvb/frontends/Makefile
+ drivers/media/dvb-frontends/ds3000.c
+reject_firmware drivers/media/dvb-frontends/ds3000.c
+clean_blob drivers/media/dvb-frontends/ds3000.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_DS3000'
+clean_mk CONFIG_DVB_DS3000 drivers/media/dvb-frontends/Makefile
announce DVB_LGS8GXX - "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
-reject_firmware drivers/media/dvb/frontends/lgs8gxx.c
-clean_blob drivers/media/dvb/frontends/lgs8gxx.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_LGS8GXX'
-clean_mk CONFIG_DVB_LGS8GXX drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/lgs8gxx.c
+clean_blob drivers/media/dvb-frontends/lgs8gxx.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_LGS8GXX'
+clean_mk CONFIG_DVB_LGS8GXX drivers/media/dvb-frontends/Makefile
announce DVB_NXT200X - "NxtWave Communications NXT2002/NXT2004 based"
-undefault_firmware 'NXT200[24]' drivers/media/dvb/frontends/nxt200x.c
-reject_firmware drivers/media/dvb/frontends/nxt200x.c
-clean_blob drivers/media/dvb/frontends/nxt200x.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_NXT200X'
-clean_mk CONFIG_DVB_NXT200X drivers/media/dvb/frontends/Makefile
+undefault_firmware 'NXT200[24]' drivers/media/dvb-frontends/nxt200x.c
+reject_firmware drivers/media/dvb-frontends/nxt200x.c
+clean_blob drivers/media/dvb-frontends/nxt200x.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_NXT200X'
+clean_mk CONFIG_DVB_NXT200X drivers/media/dvb-frontends/Makefile
announce DVB_OR51132 - "Oren OR51132 based"
-reject_firmware drivers/media/dvb/frontends/or51132.c
-clean_blob drivers/media/dvb/frontends/or51132.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_OR51132'
-clean_mk CONFIG_DVB_OR51132 drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/or51132.c
+clean_blob drivers/media/dvb-frontends/or51132.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_OR51132'
+clean_mk CONFIG_DVB_OR51132 drivers/media/dvb-frontends/Makefile
announce DVB_OR51211 - "Oren OR51211 based"
-undefault_firmware 'OR51211' drivers/media/dvb/frontends/or51211.c
-reject_firmware drivers/media/dvb/frontends/or51211.c
-reject_firmware drivers/media/dvb/frontends/or51211.h
-clean_blob drivers/media/dvb/frontends/or51211.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_OR51211'
-clean_mk CONFIG_DVB_OR51211 drivers/media/dvb/frontends/Makefile
+undefault_firmware 'OR51211' drivers/media/dvb-frontends/or51211.c
+reject_firmware drivers/media/dvb-frontends/or51211.c
+reject_firmware drivers/media/dvb-frontends/or51211.h
+clean_blob drivers/media/dvb-frontends/or51211.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_OR51211'
+clean_mk CONFIG_DVB_OR51211 drivers/media/dvb-frontends/Makefile
announce DVB_SP8870 - "Spase sp8870"
-undefault_firmware 'SP8870' drivers/media/dvb/frontends/sp8870.c
-reject_firmware drivers/media/dvb/frontends/sp8870.c
-reject_firmware drivers/media/dvb/frontends/sp8870.h
-clean_blob drivers/media/dvb/frontends/sp8870.c
-clean_kconfig drivers/media/dvb/frontends 'DVB_SP8870'
-clean_mk CONFIG_DVB_SP8870 drivers/media/dvb/frontends/Makefile
+undefault_firmware 'SP8870' drivers/media/dvb-frontends/sp8870.c
+reject_firmware drivers/media/dvb-frontends/sp8870.c
+reject_firmware drivers/media/dvb-frontends/sp8870.h
+clean_blob drivers/media/dvb-frontends/sp8870.c
+clean_kconfig drivers/media/dvb-frontends 'DVB_SP8870'
+clean_mk CONFIG_DVB_SP8870 drivers/media/dvb-frontends/Makefile
announce DVB_CX24116 - "Conexant CX24116 based"
-undefault_firmware CX24116 drivers/media/dvb/frontends/cx24116.c
-reject_firmware drivers/media/dvb/frontends/cx24116.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_CX24116'
-clean_mk CONFIG_DVB_CX24116 drivers/media/dvb/frontends/Makefile
+undefault_firmware CX24116 drivers/media/dvb-frontends/cx24116.c
+reject_firmware drivers/media/dvb-frontends/cx24116.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_CX24116'
+clean_mk CONFIG_DVB_CX24116 drivers/media/dvb-frontends/Makefile
announce DVB_SP887X - "Spase sp887x based"
-undefault_firmware 'SP887X' drivers/media/dvb/frontends/sp887x.c
-reject_firmware drivers/media/dvb/frontends/sp887x.c
-reject_firmware drivers/media/dvb/frontends/sp887x.h
-clean_blob drivers/media/dvb/frontends/sp887x.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_SP887X'
-clean_mk CONFIG_DVB_SP887X drivers/media/dvb/frontends/Makefile
+undefault_firmware 'SP887X' drivers/media/dvb-frontends/sp887x.c
+reject_firmware drivers/media/dvb-frontends/sp887x.c
+reject_firmware drivers/media/dvb-frontends/sp887x.h
+clean_blob drivers/media/dvb-frontends/sp887x.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_SP887X'
+clean_mk CONFIG_DVB_SP887X drivers/media/dvb-frontends/Makefile
announce DVB_TDA10048 - "Philips TDA10048HN based"
undefine_macro 'TDA10048_DEFAULT_FIRMWARE_SIZE' 0 \
- 'removed non-Free firmware size' drivers/media/dvb/frontends/tda10048.c
-undefault_firmware 'TDA10048' drivers/media/dvb/frontends/tda10048.c
-reject_firmware drivers/media/dvb/frontends/tda10048.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_TDA10048'
-clean_mk CONFIG_DVB_TDA10048 drivers/media/dvb/frontends/Makefile
+ 'removed non-Free firmware size' drivers/media/dvb-frontends/tda10048.c
+undefault_firmware 'TDA10048' drivers/media/dvb-frontends/tda10048.c
+reject_firmware drivers/media/dvb-frontends/tda10048.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_TDA10048'
+clean_mk CONFIG_DVB_TDA10048 drivers/media/dvb-frontends/Makefile
announce DVB_TDA1004X - "Philips TDA10045H/TDA10046H"
-undefault_firmware 'TDA1004[56]' drivers/media/dvb/frontends/tda1004x.c
-reject_firmware drivers/media/dvb/frontends/tda1004x.c
-reject_firmware drivers/media/dvb/frontends/tda1004x.h
-clean_blob drivers/media/dvb/frontends/tda1004x.c
-clean_kconfig drivers/media/dvb/frontends 'DVB_TDA1004X'
-clean_mk CONFIG_DVB_TDA1004X drivers/media/dvb/frontends/Makefile
+undefault_firmware 'TDA1004[56]' drivers/media/dvb-frontends/tda1004x.c
+reject_firmware drivers/media/dvb-frontends/tda1004x.c
+reject_firmware drivers/media/dvb-frontends/tda1004x.h
+clean_blob drivers/media/dvb-frontends/tda1004x.c
+clean_kconfig drivers/media/dvb-frontends 'DVB_TDA1004X'
+clean_mk CONFIG_DVB_TDA1004X drivers/media/dvb-frontends/Makefile
announce DVB_TDA10071 - "NXP TDA10071"
-undefault_firmware 'TDA10071' drivers/media/dvb/frontends/tda10071_priv.h
-undefault_firmware 'TDA10071' drivers/media/dvb/frontends/tda10071.c
-reject_firmware drivers/media/dvb/frontends/tda10071.c
-clean_kconfig drivers/media/dvb/frontends 'DVB_TDA10071'
-clean_mk CONFIG_DVB_TDA10071 drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/tda10071.c
+clean_blob drivers/media/dvb-frontends/tda10071.c
+clean_blob drivers/media/dvb-frontends/tda10071_priv.h
+clean_kconfig drivers/media/dvb-frontends 'DVB_TDA10071'
+clean_mk CONFIG_DVB_TDA10071 drivers/media/dvb-frontends/Makefile
# dvb
@@ -881,135 +911,142 @@ clean_kconfig drivers/staging/media/as102/Kconfig 'DVB_AS102'
clean_mk CONFIG_DVB_AS102 drivers/staging/media/as102/Makefile
announce DVB_AV7110 - "AV7110 cards"
-reject_firmware drivers/media/dvb/ttpci/av7110.c
-clean_blob drivers/media/dvb/ttpci/av7110.c
-clean_kconfig drivers/media/dvb/ttpci/Kconfig 'DVB_AV7110'
-clean_mk CONFIG_DVB_AV7110 drivers/media/dvb/ttpci/Makefile
+reject_firmware drivers/media/pci/ttpci/av7110.c
+clean_blob drivers/media/pci/ttpci/av7110.c
+clean_kconfig drivers/media/pci/ttpci/Kconfig 'DVB_AV7110'
+clean_mk CONFIG_DVB_AV7110 drivers/media/pci/ttpci/Makefile
announce DVB_BUDGET - "Budget cards"
-reject_firmware drivers/media/dvb/ttpci/budget.c
-reject_firmware drivers/media/dvb/frontends/tdhd1.h
+reject_firmware drivers/media/pci/ttpci/budget.c
+reject_firmware drivers/media/dvb-frontends/tdhd1.h
announce DVB_BUDGET_AV - "Budget cards with analog video inputs"
-reject_firmware drivers/media/dvb/ttpci/budget-av.c
+reject_firmware drivers/media/pci/ttpci/budget-av.c
announce DVB_BUDGET_CI - "Budget cards with onboard CI connector"
-reject_firmware drivers/media/dvb/ttpci/budget-ci.c
+reject_firmware drivers/media/pci/ttpci/budget-ci.c
announce DVB_DRXD - "Micronas DRXD driver"
-reject_firmware drivers/media/dvb/frontends/drxd_hard.c
-clean_blob drivers/media/dvb/frontends/drxd_hard.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_DRXD'
-clean_mk CONFIG_DVB_DRXD drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/drxd_hard.c
+clean_blob drivers/media/dvb-frontends/drxd_hard.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_DRXD'
+clean_mk CONFIG_DVB_DRXD drivers/media/dvb-frontends/Makefile
announce DVB_DRXK - "Micronas DRXK based"
-reject_firmware drivers/media/dvb/frontends/drxk_hard.c
-clean_kconfig drivers/media/dvb/frontends/Kconfig 'DVB_DRXK'
-clean_mk CONFIG_DVB_DRXK drivers/media/dvb/frontends/Makefile
+reject_firmware drivers/media/dvb-frontends/drxk_hard.c
+clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_DRXK'
+clean_mk CONFIG_DVB_DRXK drivers/media/dvb-frontends/Makefile
announce DVB_NGENE - "Micronas nGene support"
-reject_firmware drivers/media/dvb/ngene/ngene-core.c
-clean_blob drivers/media/dvb/ngene/ngene-core.c
-clean_kconfig drivers/media/dvb/ngene/Kconfig 'DVB_NGENE'
-clean_mk CONFIG_DVB_NGENE drivers/media/dvb/ngene/Makefile
+reject_firmware drivers/media/pci/ngene/ngene-core.c
+clean_blob drivers/media/pci/ngene/ngene-core.c
+clean_kconfig drivers/media/pci/ngene/Kconfig 'DVB_NGENE'
+clean_mk CONFIG_DVB_NGENE drivers/media/pci/ngene/Makefile
announce DVB_PLUTO2 - "Pluto2 cards"
-reject_firmware drivers/media/dvb/pluto2/pluto2.c
+reject_firmware drivers/media/pci/pluto2/pluto2.c
announce SMS_SIANO_MDTV - "Siano SMS1xxx based MDTV receiver"
-reject_firmware drivers/media/dvb/siano/smscoreapi.c
-clean_blob drivers/media/dvb/siano/smscoreapi.c
-clean_blob drivers/media/dvb/siano/sms-cards.c
-clean_kconfig drivers/media/dvb/siano/Kconfig 'SMS_SIANO_MDTV'
-clean_mk CONFIG_SMS_SIANO_MDTV drivers/media/dvb/siano/Makefile
+reject_firmware drivers/media/common/siano/smscoreapi.c
+clean_blob drivers/media/common/siano/smscoreapi.c
+clean_blob drivers/media/common/siano/sms-cards.c
+clean_kconfig drivers/media/common/siano/Kconfig 'SMS_SIANO_MDTV'
+clean_mk CONFIG_SMS_SIANO_MDTV drivers/media/common/siano/Makefile
announce SMS_USB_DRV - "Siano's USB interface support"
-reject_firmware drivers/media/dvb/siano/smsusb.c
-clean_blob drivers/media/dvb/siano/smsusb.c
-clean_kconfig drivers/media/dvb/siano/Kconfig 'SMS_USB_DRV'
-clean_mk CONFIG_SMS_USB_DRV drivers/media/dvb/siano/Makefile
+reject_firmware drivers/media/usb/siano/smsusb.c
+clean_blob drivers/media/usb/siano/smsusb.c
+clean_kconfig drivers/media/usb/siano/Kconfig 'SMS_USB_DRV'
+clean_mk CONFIG_SMS_USB_DRV drivers/media/usb/siano/Makefile
announce DVB_TTUSB_BUDGET - "Technotrend/Hauppauge Nova-USB devices"
drop_fw_file firmware/ttusb-budget/dspbootcode.bin.ihex firmware/ttusb-budget/dspbootcode.bin
-reject_firmware drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-clean_blob drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-clean_kconfig drivers/media/dvb/ttusb-budget/Kconfig 'DVB_TTUSB_BUDGET'
-clean_mk CONFIG_DVB_TTUSB_BUDGET drivers/media/dvb/ttusb-budget/Makefile
+reject_firmware drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+clean_blob drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+clean_kconfig drivers/media/usb/ttusb-budget/Kconfig 'DVB_TTUSB_BUDGET'
+clean_mk CONFIG_DVB_TTUSB_BUDGET drivers/media/usb/ttusb-budget/Makefile
announce DVB_TTUSB_DEC - "Technotrend/Hauppauge USB DEC devices"
-reject_firmware drivers/media/dvb/ttusb-dec/ttusb_dec.c
-clean_blob drivers/media/dvb/ttusb-dec/ttusb_dec.c
+reject_firmware drivers/media/usb/ttusb-dec/ttusb_dec.c
+clean_blob drivers/media/usb/ttusb-dec/ttusb_dec.c
clean_blob Documentation/dvb/ttusb-dec.txt
-clean_kconfig drivers/media/dvb/ttusb-dec/Kconfig 'DVB_TTUSB_DEC'
-clean_mk CONFIG_DVB_TTUSB_DEC drivers/media/dvb/ttusb-dec/Makefile
+clean_kconfig drivers/media/usb/ttusb-dec/Kconfig 'DVB_TTUSB_DEC'
+clean_mk CONFIG_DVB_TTUSB_DEC drivers/media/usb/ttusb-dec/Makefile
# video
announce VIDEO_BT848 - "BT848 Video For Linux"
-reject_firmware drivers/media/video/bt8xx/bttv-cards.c
-clean_blob drivers/media/video/bt8xx/bttv-cards.c
+reject_firmware drivers/media/pci/bt8xx/bttv-cards.c
+clean_blob drivers/media/pci/bt8xx/bttv-cards.c
clean_blob Documentation/video4linux/bttv/README
-clean_kconfig drivers/media/video/bt8xx/Kconfig 'VIDEO_BT848'
-clean_mk CONFIG_VIDEO_BT848 drivers/media/video/bt8xx/Makefile
+clean_kconfig drivers/media/pci/bt8xx/Kconfig 'VIDEO_BT848'
+clean_mk CONFIG_VIDEO_BT848 drivers/media/pci/bt8xx/Makefile
+
+announce VIDEO_CODA - "Chips&Media Coda multi-standard codec IP"
+reject_firmware drivers/media/platform/coda.c
+clean_blob drivers/media/platform/coda.c
+clean_kconfig drivers/media/platform/Kconfig 'VIDEO_CODA'
+clean_mk CONFIG_VIDEO_CODA drivers/media/platform/Makefile
announce VIDEO_CPIA2 - "CPiA2 Video For Linux"
clean_fw firmware/cpia2/stv0672_vp4.bin.ihex firmware/cpia2/stv0672_vp4.bin
-reject_firmware drivers/media/video/cpia2/cpia2_core.c
-clean_blob drivers/media/video/cpia2/cpia2_core.c
-clean_kconfig drivers/media/video/cpia2/Kconfig 'VIDEO_CPIA2'
-clean_mk CONFIG_VIDEO_CPIA2 drivers/media/video/cpia2/Makefile
+reject_firmware drivers/media/usb/cpia2/cpia2_core.c
+clean_blob drivers/media/usb/cpia2/cpia2_core.c
+clean_kconfig drivers/media/usb/cpia2/Kconfig 'VIDEO_CPIA2'
+clean_mk CONFIG_VIDEO_CPIA2 drivers/media/usb/cpia2/Makefile
announce VIDEO_CX18 - "Conexant cx23418 MPEG encoder support"
-reject_firmware drivers/media/video/cx18/cx18-av-firmware.c
-reject_firmware drivers/media/video/cx18/cx18-dvb.c
-reject_firmware drivers/media/video/cx18/cx18-firmware.c
-clean_blob drivers/media/video/cx18/cx18-av-firmware.c
-clean_blob drivers/media/video/cx18/cx18-dvb.c
-clean_blob drivers/media/video/cx18/cx18-firmware.c
-clean_kconfig drivers/media/video/cx18/Kconfig 'VIDEO_CX18'
-clean_mk CONFIG_VIDEO_CX18 drivers/media/video/cx18/Makefile
+reject_firmware drivers/media/pci/cx18/cx18-av-firmware.c
+reject_firmware drivers/media/pci/cx18/cx18-dvb.c
+reject_firmware drivers/media/pci/cx18/cx18-firmware.c
+clean_blob drivers/media/pci/cx18/cx18-av-firmware.c
+clean_blob drivers/media/pci/cx18/cx18-dvb.c
+clean_blob drivers/media/pci/cx18/cx18-firmware.c
+clean_blob drivers/media/pci/cx18/cx18-driver.c
+clean_kconfig drivers/media/pci/cx18/Kconfig 'VIDEO_CX18'
+clean_mk CONFIG_VIDEO_CX18 drivers/media/pci/cx18/Makefile
announce VIDEO_CX231XX - "Conexant cx231xx USB video capture support"
-reject_firmware drivers/media/video/cx231xx/cx231xx-417.c
-clean_blob drivers/media/video/cx231xx/cx231xx-417.c
-clean_kconfig drivers/media/video/cx231xx/Kconfig 'VIDEO_CX231XX'
-clean_mk CONFIG_VIDEO_CX231XX drivers/media/video/cx231xx/Makefile
+reject_firmware drivers/media/usb/cx231xx/cx231xx-417.c
+clean_blob drivers/media/usb/cx231xx/cx231xx-417.c
+clean_kconfig drivers/media/usb/cx231xx/Kconfig 'VIDEO_CX231XX'
+clean_mk CONFIG_VIDEO_CX231XX drivers/media/usb/cx231xx/Makefile
announce VIDEO_CX23885 - "Conexant cx23885 (2388x successor) support"
-reject_firmware drivers/media/video/cx23885/cx23885-417.c
-clean_blob drivers/media/video/cx23885/cx23885-417.c
-reject_firmware drivers/media/video/cx23885/cx23885-cards.c
-clean_blob drivers/media/video/cx23885/cx23885-cards.c
-clean_kconfig drivers/media/video/cx23885/Kconfig 'VIDEO_CX23885'
-clean_mk CONFIG_VIDEO_CX23885 drivers/media/video/cx23885/Makefile
+reject_firmware drivers/media/pci/cx23885/cx23885-417.c
+clean_blob drivers/media/pci/cx23885/cx23885-417.c
+reject_firmware drivers/media/pci/cx23885/cx23885-cards.c
+clean_blob drivers/media/pci/cx23885/cx23885-cards.c
+clean_kconfig drivers/media/pci/cx23885/Kconfig 'VIDEO_CX23885'
+clean_mk CONFIG_VIDEO_CX23885 drivers/media/pci/cx23885/Makefile
announce VIDEO_CX25840 - "Conexant CX2584x audio/video decoders"
-reject_firmware drivers/media/video/cx25840/cx25840-firmware.c
-clean_blob drivers/media/video/cx25840/cx25840-firmware.c
-clean_kconfig drivers/media/video/cx25840/Kconfig 'VIDEO_CX25840'
-clean_mk CONFIG_VIDEO_CX25840 drivers/media/video/cx25840/Makefile
+reject_firmware drivers/media/i2c/cx25840/cx25840-firmware.c
+clean_blob drivers/media/i2c/cx25840/cx25840-firmware.c
+clean_kconfig drivers/media/i2c/cx25840/Kconfig 'VIDEO_CX25840'
+clean_mk CONFIG_VIDEO_CX25840 drivers/media/i2c/cx25840/Makefile
announce VIDEO_CX88_BLACKBIRD - "Blackbird MPEG encoder support (cx2388x + cx23416)"
-reject_firmware drivers/media/video/cx88/cx88-blackbird.c
-clean_kconfig drivers/media/video/cx88/Kconfig 'VIDEO_CX88_BLACKBIRD'
-clean_mk CONFIG_VIDEO_CX88_BLACKBIRD drivers/media/video/cx88/Makefile
+reject_firmware drivers/media/pci/cx88/cx88-blackbird.c
+clean_kconfig drivers/media/pci/cx88/Kconfig 'VIDEO_CX88_BLACKBIRD'
+clean_mk CONFIG_VIDEO_CX88_BLACKBIRD drivers/media/pci/cx88/Makefile
announce VIDEO_EM28XX_DVB - "DVB/ATSC Support for em28xx based TV cards"
-clean_blob drivers/media/video/em28xx/em28xx-dvb.c
-clean_kconfig drivers/media/video/em28xx/Kconfig 'VIDEO_EM28XX_DVB'
-clean_mk CONFIG_VIDEO_EM28XX_DVB drivers/media/video/em28xx/Makefile
+clean_blob drivers/media/usb/em28xx/em28xx-dvb.c
+clean_kconfig drivers/media/usb/em28xx/Kconfig 'VIDEO_EM28XX_DVB'
+clean_mk CONFIG_VIDEO_EM28XX_DVB drivers/media/usb/em28xx/Makefile
announce VIDEO_IVTV - "Conexant cx23416/cx23415 MPEG encoder/decoder support"
-reject_firmware drivers/media/video/ivtv/ivtv-firmware.c
-clean_blob drivers/media/video/ivtv/ivtv-firmware.c
-clean_kconfig drivers/media/video/ivtv/Kconfig 'VIDEO_IVTV'
-clean_mk CONFIG_VIDEO_IVTV drivers/media/video/ivtv/Makefile
+reject_firmware drivers/media/pci/ivtv/ivtv-firmware.c
+clean_blob drivers/media/pci/ivtv/ivtv-firmware.c
+clean_kconfig drivers/media/pci/ivtv/Kconfig 'VIDEO_IVTV'
+clean_mk CONFIG_VIDEO_IVTV drivers/media/pci/ivtv/Makefile
announce VIDEO_PVRUSB2 - "Hauppauge WinTV-PVR USB2 support"
-reject_firmware drivers/media/video/pvrusb2/pvrusb2-hdw.c
-clean_blob drivers/media/video/pvrusb2/pvrusb2-devattr.c
-clean_kconfig drivers/media/video/pvrusb2/Kconfig 'VIDEO_PVRUSB2'
-clean_mk CONFIG_VIDEO_PVRUSB2 drivers/media/video/pvrusb2/Makefile
+reject_firmware drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+clean_blob drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+clean_kconfig drivers/media/usb/pvrusb2/Kconfig 'VIDEO_PVRUSB2'
+clean_mk CONFIG_VIDEO_PVRUSB2 drivers/media/usb/pvrusb2/Makefile
announce "VIDEO_CX23885, VIDEO_CX88_BLACKBIRD, VIDEO_IVTV, VIDEO_PVRUSB2" - "See above"
clean_blob include/media/cx2341x.h
@@ -1030,44 +1067,50 @@ clean_kconfig drivers/staging/media/go7007/Kconfig 'VIDEO_GO7007_USB_S2250_BOARD
clean_mk CONFIG_VIDEO_GO7007_USB_S2250_BOARD drivers/staging/media/go7007/Makefile
announce VIDEO_SAA7134_DVB - "DVB/ATSC Support for saa7134 based TV cards"
-reject_firmware drivers/media/video/saa7134/saa7134-dvb.c
-clean_kconfig drivers/media/video/saa7134/Kconfig 'VIDEO_SAA7134_DVB'
-clean_mk CONFIG_VIDEO_SAA7134_DVB drivers/media/video/saa7134/Makefile
+reject_firmware drivers/media/pci/saa7134/saa7134-dvb.c
+clean_kconfig drivers/media/pci/saa7134/Kconfig 'VIDEO_SAA7134_DVB'
+clean_mk CONFIG_VIDEO_SAA7134_DVB drivers/media/pci/saa7134/Makefile
announce VIDEO_SAA7164 - "NXP SAA7164 support"
-reject_firmware drivers/media/video/saa7164/saa7164-fw.c
-clean_blob drivers/media/video/saa7164/saa7164-fw.c
-clean_kconfig drivers/media/video/saa7164/Kconfig 'VIDEO_SAA7164'
-clean_mk CONFIG_VIDEO_SAA7164 drivers/media/video/saa7164/Makefile
+reject_firmware drivers/media/pci/saa7164/saa7164-fw.c
+clean_blob drivers/media/pci/saa7164/saa7164-fw.c
+clean_kconfig drivers/media/pci/saa7164/Kconfig 'VIDEO_SAA7164'
+clean_mk CONFIG_VIDEO_SAA7164 drivers/media/pci/saa7164/Makefile
announce VIDEO_TLG2300 - "Telegent TLG2300 USB video capture support"
-reject_firmware drivers/media/video/tlg2300/pd-main.c
-clean_blob drivers/media/video/tlg2300/pd-main.c
-clean_kconfig drivers/media/video/tlg2300/Kconfig 'VIDEO_TLG2300'
-clean_mk CONFIG_VIDEO_TLG2300 drivers/media/video/tlg2300/Makefile
+reject_firmware drivers/media/usb/tlg2300/pd-main.c
+clean_blob drivers/media/usb/tlg2300/pd-main.c
+clean_kconfig drivers/media/usb/tlg2300/Kconfig 'VIDEO_TLG2300'
+clean_mk CONFIG_VIDEO_TLG2300 drivers/media/usb/tlg2300/Makefile
+
+announce VIDEO_S5K4ECGX - "Samsung S5K4ECGX sensor support"
+reject_firmware drivers/media/i2c/s5k4ecgx.c
+clean_blob drivers/media/i2c/s5k4ecgx.c
+clean_kconfig drivers/media/i2c/s5k4ecgx.c 'VIDEO_S5K4ECGX'
+clean_mk CONFIG_VIDEO_S5K4ECGX drivers/media/i2c/Makefile
announce VIDEO_SAMSUNG_S5P_MFC - "Samsung S5P MFC 5.1 Video Codec"
-reject_firmware drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
-clean_blob drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
-clean_kconfig drivers/media/video/Kconfig 'VIDEO_SAMSUNG_S5P_MFC'
-clean_mk CONFIG_VIDEO_SAMSUNG_S5P_MFC drivers/media/video/s5p-mfc/Makefile
+reject_firmware drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+clean_blob drivers/media/platform/s5p-mfc/s5p_mfc.c
+clean_kconfig drivers/media/platform/Kconfig 'VIDEO_SAMSUNG_S5P_MFC'
+clean_mk CONFIG_VIDEO_SAMSUNG_S5P_MFC drivers/media/platform/s5p-mfc/Makefile
announce USB_DABUSB - "left-over DABUSB firmware"
clean_fw firmware/dabusb/bitstream.bin.ihex firmware/dabusb/bitstream.bin
clean_fw firmware/dabusb/firmware.HEX firmware/dabusb/firmware.fw
announce USB_S2255 - "USB Sensoray 2255 video capture device"
-reject_firmware drivers/media/video/s2255drv.c
-clean_blob drivers/media/video/s2255drv.c
-clean_kconfig drivers/media/video/Kconfig 'USB_S2255'
-clean_mk CONFIG_USB_S2255 drivers/media/video/Makefile
+reject_firmware drivers/media/usb/s2255/s2255drv.c
+clean_blob drivers/media/usb/s2255/s2255drv.c
+clean_kconfig drivers/media/usb/Kconfig 'USB_S2255'
+clean_mk CONFIG_USB_S2255 drivers/media/usb/s2255/Makefile
announce USB_GSPCA_VICAM - "USB 3com HomeConnect, AKA vicam"
drop_fw_file firmware/vicam/firmware.H16 firmware/vicam/firmware.fw
-reject_firmware drivers/media/video/gspca/vicam.c
-clean_blob drivers/media/video/gspca/vicam.c
-clean_kconfig drivers/media/video/gspca/Kconfig 'USB_GSPCA_VICAM'
-clean_mk CONFIG_USB_GSPCA_VICAM drivers/media/video/gspca/Makefile
+reject_firmware drivers/media/usb/gspca/vicam.c
+clean_blob drivers/media/usb/gspca/vicam.c
+clean_kconfig drivers/media/usb/gspca/Kconfig 'USB_GSPCA_VICAM'
+clean_mk CONFIG_USB_GSPCA_VICAM drivers/media/usb/gspca/Makefile
# radio
@@ -1167,7 +1210,6 @@ clean_mk CONFIG_CASSINI drivers/net/ethernet/sun/Makefile
announce CHELSIO_T3 - "Chelsio AEL 2005 support"
drop_fw_file firmware/cxgb3/t3b_psram-1.1.0.bin.ihex firmware/cxgb3/t3b_psram-1.1.0.bin
drop_fw_file firmware/cxgb3/t3c_psram-1.1.0.bin.ihex firmware/cxgb3/t3c_psram-1.1.0.bin
-drop_fw_file firmware/cxgb3/t3fw-7.10.0.bin.ihex firmware/cxgb3/t3fw-7.10.0.bin
drop_fw_file firmware/cxgb3/ael2005_opt_edc.bin.ihex firmware/cxgb3/ael2005_opt_edc.bin
drop_fw_file firmware/cxgb3/ael2005_twx_edc.bin.ihex firmware/cxgb3/ael2005_twx_edc.bin
drop_fw_file firmware/cxgb3/ael2020_twx_edc.bin.ihex firmware/cxgb3/ael2020_twx_edc.bin
@@ -1705,8 +1747,10 @@ clean_mk CONFIG_RTL8192SE drivers/net/wireless/rtlwifi/rtl8192se/Makefile
announce RTL8192E - "RealTek RTL8192E Wireless LAN NIC driver"
reject_firmware drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
+clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h
clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
+clean_blob drivers/staging/rtl8192e/rtl8192e/rtl_core.c
clean_kconfig drivers/staging/rtl8192e/Kconfig RTL8192E
clean_mk CONFIG_RTL8192E drivers/staging/rtl8192e/Makefile
@@ -1748,6 +1792,7 @@ clean_mk CONFIG_WL18XX drivers/net/wireless/ti/wl18xx/Makefile
announce WLCORE - "TI wlcore support"
reject_firmware drivers/net/wireless/ti/wlcore/main.c
+clean_blob drivers/net/wireless/ti/wlcore/main.c
clean_blob drivers/net/wireless/ti/wlcore/wlcore_i.h
clean_kconfig drivers/net/wireless/ti/wlcore/Kconfig 'WLCORE'
clean_mk CONFIG_WLCORE drivers/net/wireless/ti/wlcore/Makefile
@@ -1835,12 +1880,7 @@ clean_kconfig drivers/staging/gdm72xx/Kconfig 'WIMAX_GDM72XX_SDIO'
clean_mk CONFIG_WIMAX_GDM72XX_SDIO drivers/staging/gdm72xx/Makefile
announce WIMAX_GDM72XX_USB - "GCT GDM72xx WiMAX support: USB interface"
-clean_sed '
-/^int usb_boot/,/^}/ {
- /filp = filp_open/ s,filp = .*;,/*(DEBLOBBED)*/,
- s,if (IS_ERR(filp)),if (1 /*(DEBLOBBED)*/),
-}' drivers/staging/gdm72xx/usb_boot.c \
- 'disabled non-Free firmware loading machinery'
+reject_firmware drivers/staging/gdm72xx/usb_boot.c
clean_blob drivers/staging/gdm72xx/usb_boot.c
clean_kconfig drivers/staging/gdm72xx/Kconfig 'WIMAX_GDM72XX_USB'
clean_mk CONFIG_WIMAX_GDM72XX_USB drivers/staging/gdm72xx/Makefile
@@ -1942,12 +1982,30 @@ clean_mk CONFIG_LIRC_ZILOG drivers/staging/media/lirc/Makefile
# Data acquisition #
####################
+announce COMEDI_DAQBOARD2000 - "IOtech DAQboard/2000 support"
+reject_firmware drivers/staging/comedi/drivers/daqboard2000.c
+clean_blob drivers/staging/comedi/drivers/daqboard2000.c
+clean_kconfig drivers/staging/comedi/Kconfig 'COMEDI_DAQBOARD2000'
+clean_mk CONFIG_COMEDI_DAQBOARD2000 drivers/staging/comedi/drivers/Makefile
+
announce COMEDI_JR3_PCI - "JR3/PCI force sensor board support"
reject_firmware drivers/staging/comedi/drivers/jr3_pci.c
clean_blob drivers/staging/comedi/drivers/jr3_pci.c
clean_kconfig drivers/staging/comedi/Kconfig 'COMEDI_JR3_PCI'
clean_mk CONFIG_COMEDI_JR3_PCI drivers/staging/comedi/drivers/Makefile
+announce COMEDI_ME_DAQ - "Meilhaus ME-2000i, ME-2600i, ME-3000vm1 support"
+reject_firmware drivers/staging/comedi/drivers/me_daq.c
+clean_blob drivers/staging/comedi/drivers/me_daq.c
+clean_kconfig drivers/staging/comedi/Kconfig 'COMEDI_ME_DAQ'
+clean_mk CONFIG_COMEDI_ME_DAQ drivers/staging/comedi/drivers/Makefile
+
+announce COMEDI_NI_PCIDIO - "NI PCI-DIO32HS, PCI-6533, PCI-6534 support"
+reject_firmware drivers/staging/comedi/drivers/ni_pcidio.c
+clean_blob drivers/staging/comedi/drivers/ni_pcidio.c
+clean_kconfig drivers/staging/comedi/Kconfig 'COMEDI_NI_PCIDIO'
+clean_mk CONFIG_COMEDI_NI_PCIDIO drivers/staging/comedi/drivers/Makefile
+
announce COMEDI_USBDUX - "ITL USBDUX support"
reject_firmware drivers/staging/comedi/drivers/usbdux.c
clean_blob drivers/staging/comedi/drivers/usbdux.c
@@ -2100,6 +2158,9 @@ clean_blob drivers/usb/misc/emi62.c
clean_kconfig drivers/usb/misc/Kconfig 'USB_EMI62'
clean_mk CONFIG_USB_EMI62 drivers/usb/misc/Makefile
+announce USB_EZUSB_FX2 - "Functions for loading firmware on EZUSB chips"
+maybe_reject_firmware drivers/usb/misc/ezusb.c
+
announce USB_ISIGHTFW - "iSight firmware loading support"
reject_firmware drivers/usb/misc/isight_firmware.c
clean_blob drivers/usb/misc/isight_firmware.c
@@ -2152,16 +2213,10 @@ drop_fw_file firmware/keyspan/usa49w.HEX firmware/keyspan/usa49w.fw
clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_KEYSPAN_USA49W'
drop_fw_file firmware/keyspan/usa49wlc.HEX firmware/keyspan/usa49wlc.fw
clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_KEYSPAN_USA49WLC'
-reject_firmware drivers/usb/serial/keyspan.c
clean_blob drivers/usb/serial/keyspan.c
clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_KEYSPAN'
clean_mk CONFIG_USB_SERIAL_KEYSPAN drivers/usb/serial/Makefile
-announce USB_SERIAL_KEYSPAN_PDA - "USB Keyspan PDA Single Port Serial Driver"
-clean_sed '
-s,request_ihex_firmware,/*KEYSPAN_PDA*/&,
-' drivers/usb/serial/keyspan_pda.c 'accept Free firmware'
-
announce USB_SERIAL_EDGEPORT - "USB Inside Out Edgeport Serial Driver"
clean_fw firmware/edgeport/boot.H16 firmware/edgeport/boot.fw
clean_fw firmware/edgeport/boot2.H16 firmware/edgeport/boot2.fw
@@ -2194,7 +2249,6 @@ announce USB_SERIAL_WHITEHEAT - "USB ConnectTech WhiteHEAT Serial Driver"
clean_fw firmware/whiteheat.HEX firmware/whiteheat.fw
clean_fw firmware/whiteheat_loader.HEX firmware/whiteheat_loader.fw
clean_fw firmware/whiteheat_loader_debug.HEX firmware/whiteheat_loader_debug.fw
-reject_firmware drivers/usb/serial/whiteheat.c
clean_blob drivers/usb/serial/whiteheat.c
clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_WHITEHEAT'
clean_mk CONFIG_USB_SERIAL_WHITEHEAT drivers/usb/serial/Makefile
@@ -2211,6 +2265,18 @@ clean_mk CONFIG_UWB_I1480U drivers/uwb/i1480/dfu/Makefile
+##############
+# RemoteProc #
+##############
+
+announce STE_MODEM_RPROC - "STE-Modem remoteproc support"
+maybe_reject_firmware drivers/remoteproc/remoteproc_core.c
+undefine_macro SPROC_MODEM_FIRMWARE "\"/*(DEBLOBBED)*/\"" \
+ "disabled non-Free firmware" drivers/remoteproc/ste_modem_rproc.c
+clean_kconfig drivers/remoteproc/Kconfig 'STE_MODEM_RPROC'
+clean_mk CONFIG_STE_MODEM_RPROC drivers/remoteproc/Makefile
+
+
#########
# Sound #
#########
@@ -2467,6 +2533,12 @@ clean_mk CONFIG_SND_SOC_ADAU1701 sound/soc/codecs/Makefile
announce SND_SOC_SIGMADSP - "SigmaStudio firmware loader"
maybe_reject_firmware sound/soc/codecs/sigmadsp.c
+announce SND_SOC_WM0010 - "WM0010 DSP driver"
+reject_firmware sound/soc/codecs/wm0010.c
+clean_blob sound/soc/codecs/wm0010.c
+clean_kconfig sound/soc/codecs/Kconfig 'SND_SOC_WM0010'
+clean_mk CONFIG_SND_SOC_WM0010 sound/soc/codecs/Makefile
+
# It's not clear that wm2000_anc.bin is pure data.
# Check with developer, clean up for now.
announce SND_SOC_WM2000 - "WM2000 ALSA Soc Audio codecs"
diff --git a/freed-ora/current/f18/deblob-check b/freed-ora/current/f18/deblob-check
index ff1ba48aa..794eab404 100755
--- a/freed-ora/current/f18/deblob-check
+++ b/freed-ora/current/f18/deblob-check
@@ -1,6 +1,6 @@
#! /bin/sh
-# deblob-check version 2012-10-31
+# deblob-check version 2012-11-27
# Inspired in gNewSense's find-firmware script.
# Written by Alexandre Oliva <lxoliva@fsfla.org>
@@ -1026,8 +1026,8 @@ set_except () {
initnc '[ ]int[ ]bcomm_irq\[3[*]16\][ ]='
initnc '[ ]static[ ]const[ ]int8[ ]countLeadingZerosHigh\[\][ ]='
initnc 'static[ ]struct[ ]nic_qp_map[ ]nic_qp_mapping_[01]\[\][ ]='
- initnc 'static[ ]struct[ ]regval[ ]ov_initvals\[\][ ]='
- initnc 'static[ ]struct[ ]regval[ ]stk1125_initvals\[\][ ]='
+ initnc 'static[ ]struct[ ]regval[ ]ov_initvals\[\][ ]=' drivers/media/usb/stkwebcam/stk-sensor.c
+ initnc 'static[ ]struct[ ]regval[ ]stk1125_initvals\[\][ ]=' drivers/media/usb/stkwebcam/stk-webcam.c
initnc 'static[ ]u8[ ]bnx2x_stats_len_arr\[BNX2X_NUM_STATS\][ ]='
defsnc 'static[ ]const[ ]struct[ ]arb_line[ ]read_arb_data\[NUM_RD_Q\]\[MAX_RD_ORD[ ][+][ ]1\][ ]=' drivers/net/bnx2x/bnx2x_init_opts.h
defsnc 'static[ ]const[ ]struct[ ]arb_line[ ]write_arb_data\[NUM_WR_Q\]\[MAX_WR_ORD[ ][+][ ]1\][ ]=' drivers/net/bnx2x/bnx2x_init_opts.h
@@ -1061,7 +1061,7 @@ set_except () {
accept ':03000000020200F9[\n]:040023000205\(9B0037\|5F0073\)[\n]\(:050030000000000000CB[\n]\|:0400430002010000B6[\n]\)*'"$sepx$blobpat*"'[\n]:\(0E06E0006400670065007400060334003700F4\|0606A000060334003700E0\)[\n]:00000001FF' 'firmware/keyspan_pda/\(keyspan_pda\|xircom_pgs\).HEX'
accept ':100000000C004000000000000000000000000000A4[\n]'"$sepx$blobpat*"'[\n][/][*][ ]DSP56001[ ]bootstrap[ ]code[ ][*][/]' firmware/dsp56k/bootstrap.bin.ihex
initnc 'static[ ]const[ ]u16[ ]uda1380_reg\[UDA1380_CACHEREGNUM\][ ]=' sound/soc/codecs/uda1380.c
- initnc 'static[ ]const[ ]u16[ ]wm8510_reg\[WM8510_CACHEREGNUM\][ ]=' sound/soc/codecs/wm8510.c
+ defsnc 'static[ ]const[ ]u16[ ]wm8510_reg\[WM8510_CACHEREGNUM\][ ]=' sound/soc/codecs/wm8510.c
initnc 'static[ ]const[ ]unsigned[ ]short[ ]atkbd_unxlate_table\[128\][ ]=' drivers/input/keyboard/atkbd.c
initnc 'static[ ]const[ ]unsigned[ ]char[ ]usb_kbd_keycode\[256\][ ]=' drivers/hid/usbhid/usbkbd.c
initnc '[ ][ ]u8[ ]buf,[ ]bufs\[\][ ]=' drivers/media/dvb/dvb-usb/cxusb.c
@@ -1842,7 +1842,7 @@ set_except () {
initc 'static[ ]uint32_t[ ]cuda_images\[\]\[PCXW_IMAGE_SIZE[/]sizeof[(]uint32_t[)]\][ ]__read_mostly[ ]='
# These are regarded as ok
- initnc 'static[ ]const[ ]u8[ ]SN9C102_\(Y\|UV\)_QTABLE[01]\[64\][ ]=[ ][{]'
+ initnc 'static[ ]const[ ]u8[ ]SN9C102_\(Y\|UV\)_QTABLE[01]\[64\][ ]=[ ][{]' drivers/media/usb/sn9c102/sn9c102_config.h
initnc '[ ]static[ ]\(const[ ]\)\?u8[ ]jpeg_header\[589\][ ]=[ ][{]' media/video/sn9c102/sn9c102_core.c
accept '[ ][ ]\?err[ ]=[ ]sn9c102_write_const_regs[(]cam\(,[ \n]\+[{]0x[0-9a-fA-F][0-9a-fA-F],[ ]0x[0-9a-fA-F][0-9a-fA-F][}]\)*[)][;]'
@@ -1897,24 +1897,24 @@ set_except () {
initnc '[ ]static[ ]const[ ]unsigned[ ]int[ ]avg_pkts\[NCCTRL_WIN\][ ]='
initnc '[ ]static[ ]const[ ]unsigned[ ]short[ ]ac97_defaults\[\][ ]='
initnc '[ ]static[ ]int[ ]exp_lut\[256\][ ]='
- initnc '[ ]static[ ]u16[ ]jpeg_tables\[\]\[70\][ ]='
- initnc '[ ]static[ ]u16[ ]tables\[\][ ]='
+ defsnc '[ ]static[ ]u16[ ]jpeg_tables\[\]\[70\][ ]=' drivers/media/pci/meye/meye.c
+ defsnc '[ ]static[ ]u16[ ]tables\[\][ ]=' drivers/media/pci/meye/meye.c
initnc '[ ]static[ ]u32[ ]logMagTable\[128\][ ]='
- initnc '[ ]static[ ]u8[ ]init_bufs\[13\]\[5\][ ]='
+ defsnc '[ ]static[ ]u8[ ]init_bufs\[13\]\[5\][ ]=' drivers/media/pci/cx88/cx88-cards.c
initnc '[ ]static[ ]u_short[ ]geometry_table\[\]\[[45]\][ ]='
initnc '[ ]static[ ]unsigned[ ]char[ ]CRCTable1\[\][ ]='
initnc '[ ]static[ ]unsigned[ ]char[ ]CRCTable2\[\][ ]='
initnc '[ ]static[ ]unsigned[ ]char[ ]default_colors\[\][ ]='
- initnc '[ ]static[ ]unsigned[ ]char[ ]iso_regs\[8\]\[4\][ ]='
+ defsnc '[ ]static[ ]unsigned[ ]char[ ]iso_regs\[8\]\[4\][ ]=' drivers/media/usb/cpia2/cpia2_usb.c
initnc '[ ]static[ ]unsigned[ ]char[ ]log_scale\[101\][ ]=' sound/oss/pss.c
initnc '[ ]static[ ]unsigned[ ]char[ ]msg\[\][ ]='
- initnc '[ ]static[ ]unsigned[ ]char[ ]static_pad\[\][ ]='
+ defsnc '[ ]static[ ]unsigned[ ]char[ ]static_pad\[\][ ]=' drivers/s390/crypto/zcrypt_msgtype6.c
defsnc '[ ]static[ ]unsigned[ ]char[ ]table_alaw2ulaw\[\][ ]=' drivers/staging/telephony/ixj.c
defsnc '[ ]static[ ]unsigned[ ]char[ ]table_ulaw2alaw\[\][ ]=' drivers/staging/telephony/ixj.c
defsnc '[ ]\(static[ ]const[ ]\)\?u32[ ]reg_boundaries\[\][ ]=' drivers/net/bnx2.c
- initnc '[ ]u8[ ]b\[\][ ]='
+ defsnc '[ ]u8[ ]b\[\][ ]=' drivers/media/usb/ttusb-dec/ttusbdecfe.c
initnc '[ ]uint8_t[ ]tx\[\][ ]='
- initnc '[ ]unsigned[ ]char[ ]saa7111_regs\[\][ ]='
+ defsnc '[ ]unsigned[ ]char[ ]saa7111_regs\[\][ ]=' drivers/media/parport/w9966.c
initnc '[ ]unsigned[ ]char[ ]sas_pcd_m_pg\[\][ ]='
initnc '[ ][}][ ]modedb\[5\][ ]='
defsnc '[ ][}][ ]reg_tbl\[\][ ]=' drivers/net/bnx2.c
@@ -1994,7 +1994,7 @@ set_except () {
initnc 'static[ ]const[ ]u32[ ]SS[0-3]\[256\][ ]='
initnc 'static[ ]const[ ]u32[ ]S[1-8]\[64\][ ]='
initnc 'static[ ]const[ ]u32[ ]T[0-5]\[256\][ ]='
- initnc 'static[ ]const[ ]u32[ ]Tm\[24\]\[8\][ ]='
+ defsnc 'static[ ]const[ ]u32[ ]Tm\[24\]\[8\][ ]=' crypto/cast6_generic.c
initnc 'static[ ]const[ ]u32[ ]bass_table\[41\]\[5\][ ]='
initnc 'static[ ]const[ ]u32[ ]bf_sbox\[256[ ][*][ ]4\][ ]='
defsnc 'static[ ]const[ ]u32[ ]camellia_sp0222\[256\][ ]=' crypto/camellia.c
@@ -2006,14 +2006,14 @@ set_except () {
initnc 'static[ ]const[ ]u32[ ]m8xx_size_to_gray\[M8XX_SIZES_NO\][ ]='
initnc 'static[ ]const[ ]u32[ ]mds\[4\]\[256\][ ]='
initnc 'static[ ]const[ ]u32[ ]pc2\[1024\][ ]='
- initnc 'static[ ]const[ ]u32[ ]s[1-7]\[256\][ ]='
- initnc 'static[ ]const[ ]u32[ ]sb8\[256\][ ]='
+ defsnc 'static[ ]const[ ]u32[ ]s[1-7]\[256\][ ]=' crypto/cast5_generic.c
+ defsnc 'static[ ]const[ ]u32[ ]sb8\[256\][ ]=' crypto/cast5_generic.c
initnc 'static[ ]const[ ]u32[ ]tfrc_calc_x_lookup\[TFRC_CALC_X_ARRSIZE\]\[2\][ ]='
initnc 'static[ ]const[ ]u32[ ]treble_table\[41\]\[5\][ ]='
initnc 'static[ ]const[ ]u64[ ][CT][0-7]\[256\][ ]='
initnc 'static[ ]const[ ]u64[ ]sbox[1-4]\[256\][ ]='
initnc 'static[ ]const[ ]u64[ ]sha512_K\[80\][ ]=' 'crypto/sha512\(_generic\)\?.c'
- initnc 'static[ ]const[ ]u8[ ]Tr\[4\]\[8\][ ]='
+ defsnc 'static[ ]const[ ]u8[ ]Tr\[4\]\[8\][ ]=' crpto/cast6_generic.c
initnc 'static[ ]const[ ]u8[ ]aes_sbox\[256\][ ]='
initnc 'static[ ]const[ ]u8[ ]calc_sb_tbl\[512\][ ]='
initnc 'static[ ]const[ ]u8[ ]exp_to_poly\[492\][ ]='
@@ -2038,16 +2038,16 @@ set_except () {
initnc 'static[ ]const[ ]unsigned[ ]char[ ]comet_miireg2offset\[32\][ ]='
initnc 'static[ ]\(const[ ]\)\?unsigned[ ]char[ ]euc2sjisibm_g3upper_map\[\]\[2\][ ]='
initnc 'static[ ]const[ ]unsigned[ ]char[ ]green\[256\][ ]='
- initnc 'static[ ]const[ ]unsigned[ ]char[ ]hash_table_ops\[64[*]4\][ ]='
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]hash_table_ops\[64[*]4\][ ]=' drivers/media/usb/pwc/pwc-dec23.c
defsnc 'static[ ]const[ ]unsigned[ ]char[ ]hid_keyboard\[256\][ ]=' drivers/hid/hid-input.c
initnc 'static[ ]const[ ]unsigned[ ]char[ ]mts_direction\[256[/]8\][ ]='
initnc 'static[ ]const[ ]unsigned[ ]char[ ]red\[256\][ ]='
initnc 'static[ ]\(const[ ]\)\?unsigned[ ]char[ ]sjisibm2euc_map\[\]\[2\][ ]='
initnc 'static[ ]const[ ]unsigned[ ]char[ ]vol_cvt_datt\[128\][ ]='
- initnc 'static[ ]const[ ]unsigned[ ]int[ ]MulIdx\[16\]\[16\][ ]='
+ defsnc 'static[ ]const[ ]unsigned[ ]int[ ]MulIdx\[16\]\[16\][ ]=' drivers/media/usb/pwc/pwc-dec23.c
initnc 'static[ ]const[ ]unsigned[ ]int[ ]crctab32\[\][ ]='
initnc 'static[ ]const[ ]unsigned[ ]short[ ]crc_flex_table\[\][ ]='
- initnc 'static[ ]const[ ]unsigned[ ]short[ ]logtable\[256\][ ]='
+ defsnc 'static[ ]const[ ]unsigned[ ]short[ ]logtable\[256\][ ]=' drivers/media/dvb-core/dvb_math.c
initnc 'static[ ]const[ ]unsigned[ ]short[ ]wd7000_iobase\[\][ ]='
defsnc 'static[ ]const[ ]unsigned[ ]short[ ]x86_keycodes\[256\][ ]=' drivers/tty/vt/keyboard.c
initnc 'static[ ]const[ ]unsigned[ ]table\[\][ ]='
@@ -2066,7 +2066,7 @@ set_except () {
initnc 'static[ ]short[ ]isdn_audio_[ua]law_to_s16\[\][ ]='
defsnc 'static[ ]struct[ ]iw\?l\(3945\)\?_tx_power[ ]power_gain_table\[2\]\[IW\?L_MAX_GAIN_ENTRIES\][ ]=' drivers/net/wireless/iwlegacy/iwl-3945.c
initnc 'static[ ]struct[ ]ovcamchip_regvals[ ]regvals_init_\(76be\|7[16]20\|7x10\)\[\][ ]='
- initnc 'static[ ]struct[ ]regval_list[ ]ov7670_default_regs\[\][ ]='
+ initnc 'static[ ]struct[ ]regval_list[ ]ov7670_default_regs\[\][ ]=' drivers/media/i2c/ov7670.c
initnc 'static[ ]struct[ ]s_c2[ ]SetRate48000\[\][ ]='
initnc 'static[ ]struct[ ]tea6420_multiplex[ ]TEA6420_line\[MXB_AUDIOS[+]1\]\[2\][ ]='
initnc 'static[ ]struct[ ]wm_info[ ]i810_wm_16_100\[\][ ]='
@@ -2079,15 +2079,15 @@ set_except () {
initnc 'static[ ]u16[ ]asEqCoefsPipes\[64\][ ]='
initnc 'static[ ]u16[ ]asEqCoefsZeros\[50\][ ]='
initnc 'static[ ]u16[ ]asEqOutStateZeros\[48\][ ]='
- initnc 'static[ ]u16[ ]default_key_map[ ]\[256\][ ]='
+ defsnc 'static[ ]u16[ ]default_key_map[ ]\[256\][ ]=' drivers/media/pci/ttpci/av7110_ir.c
initnc 'static[ ]u16[ ]eq_levels\[64\][ ]='
initnc 'static[ ]u32[ ][ ]crc32tab\[\][ ]__attribute__[ ][(][(]aligned[(]8[)][)][)][ ]='
- initnc 'static[ ]u32[ ]ac3_frames\[3\]\[32\][ ]='
+ defsnc 'static[ ]u32[ ]ac3_frames\[3\]\[32\][ ]=' drivers/media/dvb-core/dvb_filter.c
initnc 'static[ ]u32[ ]adwDecim8\[33\][ ]='
initnc 'static[ ]u32[ ]h_prescale\[64\][ ]='
initnc 'static[ ]u32[ ]v_gain\[64\][ ]='
- initnc 'static[ ]u8[ ]SRAM_Table\[\]\[60\][ ]='
- initnc 'static[ ]u8[ ]alps_tdee4_stv0297_inittab\[\][ ]='
+ defsnc 'static[ ]u8[ ]SRAM_Table\[\]\[60\][ ]=' drivers/media/pci/bt8xx/bttv-driver.c
+ defsnc 'static[ ]u8[ ]alps_tdee4_stv0297_inittab\[\][ ]=' drivers/media/common/b2c2/flexcop-fe-tuner.c
defsnc 'static[ ]u8[ ]bnx2_570[68]_stats_len_arr\[BNX2_NUM_STATS\][ ]=' drivers/net/bnx2.c
initnc 'static[ ]u8[ ]flit_desc_map\[\][ ]='
defsnc 'static[ ]\(const[ ]\)\?u8[ ]init_tab[ ]\?\[\][ ]=' 'drivers/media/dvb/frontends/cx2270\(0\|2\)\.c'
@@ -2096,9 +2096,9 @@ set_except () {
initnc 'static[ ]u8[ ]mt2131_config1\[\][ ]=' drivers/media/common/tuners/mt2131.c # >= 2.6.26
initnc 'static[ ]u8[ ]mt2266_init2\[\][ ]=' drivers/media/dvb/frontends/mt2266.c # <= 2.6.25
initnc 'static[ ]u8[ ]mt2266_init2\[\][ ]=' drivers/media/common/tuners/mt2266.c # >= 2.6.26
- initnc 'static[ ]u8[ ]opera1_inittab\[\][ ]='
- initnc 'static[ ]u8[ ]saa7113_init_regs\[\][ ]='
- initnc 'static[ ]u8[ ]samsung_tbmu24112_inittab\[\][ ]='
+ defsnc 'static[ ]u8[ ]opera1_inittab\[\][ ]=' drivers/media/usb/dvb-usb/opera1.c
+ defsnc 'static[ ]u8[ ]saa7113_init_regs\[\][ ]=' drivers/media/pci/ttpci/av7110_v4l.c
+ defsnc 'static[ ]u8[ ]samsung_tbmu24112_inittab\[\][ ]=' drivers/media/common/b2c2/flexcop-fe-tuner.c
defsnc 'static[ ]u8[ ]w1_crc8_table\[\][ ]=' drivers/w1/w1_io.c
initnc 'static[ ]u_char[ ]const[ ]data_sizes_32\[32\][ ]='
initnc 'static[ ]u_long[ ]ident_map\[32\][ ]='
@@ -2131,7 +2131,7 @@ set_except () {
initnc 'static[ ]unsigned[ ]char[ ]crystal_key\[\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]dsp_ulaw\[\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]expressiontab\[128\][ ]='
- initnc 'static[ ]unsigned[ ]char[ ]header2\[\][ ]='
+ defsnc 'static[ ]unsigned[ ]char[ ]header2\[\][ ]=' drivers/media/usb/zr364xx/zr364xx.c
initnc 'static[ ]unsigned[ ]char[ ]hidp_keycode\[256\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]nkbd_keycode\[128\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]pan_volumes\[256\][ ]='
@@ -2151,9 +2151,9 @@ set_except () {
initnc 'static[ ]unsigned[ ]char[ ]voltab[12]\[128\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]vpd89_data\[\][ ]='
initnc 'static[ ]unsigned[ ]char[ ]xtkbd_keycode\[256\][ ]='
- initnc 'static[ ]unsigned[ ]int[ ]ac3_bitrates\[32\][ ]='
+ defsnc 'static[ ]unsigned[ ]int[ ]ac3_bitrates\[32\][ ]=' drivers/media/dvb-core/dvb_filter.c
initnc 'static[ ]unsigned[ ]int[ ]bass_volume_table\[\][ ]='
- initnc 'static[ ]unsigned[ ]int[ ]bitrates\[3\]\[16\][ ]='
+ defsnc 'static[ ]unsigned[ ]int[ ]bitrates\[3\]\[16\][ ]=' drivers/media/dvb-core/dvb_filter.c
initnc 'static[ ]unsigned[ ]int[ ]isa_dma_port\[8\]\[7\][ ]='
initnc 'static[ ]unsigned[ ]int[ ]master_volume_table\[\][ ]='
initnc 'static[ ]unsigned[ ]int[ ]mixer_volume_table\[\][ ]='
@@ -2187,17 +2187,17 @@ set_except () {
initnc '\(uint16_t\|u16\)[ ]e1000_igp_2_cable_length_table\[IGP02E1000_AGC_LENGTH_TABLE_SIZE\][ ]=' drivers/net/e1000/e1000_hw.c # u16 on 2.6.26
initnc '[}][ ]euc2sjisibm_jisx0212_map\[\][ ]='
initnc '[}][ ]freq\[\][ ]='
- initnc '[}][ ]hps_h_coeff_tab[ ]\[\][ ]='
- initnc '[}][ ]hps_v_coeff_tab[ ]\[\][ ]='
- initnc '[}][ ]init_tab\[\][ ]='
+ defsnc '[}][ ]hps_h_coeff_tab[ ]\[\][ ]=' drivers/media/common/saa7146/saa7146_hlp.c
+ defsnc '[}][ ]hps_v_coeff_tab[ ]\[\][ ]=' drivers/media/common/saa7146/saa7146_hlp.c
+ defsnc '[}][ ]init_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
initnc '[}][ ]maven_gamma\[\][ ]='
defsnc '[}][ ]mem_table\[\][ ]=' drivers/net/ethernet/8390/smc-mca.c
- initnc '[}][ ]mxb_saa7740_init\[\][ ]='
+ defsnc '[}][ ]mxb_saa7740_init\[\][ ]=' drivers/media/pci/saa7146/mxb.c
initnc '[}][ ]pll_table\[\][ ]=' drivers/video/geode/lxfb_ops.c
- initnc '[}][ ]qam256_snr_tab\[\][ ]='
- initnc '[}][ ]qam64_snr_tab\[\][ ]='
+ defsnc '[}][ ]qam256_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
+ defsnc '[}][ ]qam64_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
initnc '[}][ ]sil_port\[\][ ]='
- initnc '[}][ ]vsb_snr_tab\[\][ ]='
+ defsnc '[}][ ]vsb_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
# new in 2.6.30
defsnc 'static[ ]const[ ]unsigned[ ]char[ ]sync\[\][ ]=' Documentation/networking/timestamping/timestamping.c
@@ -3147,6 +3147,89 @@ set_except () {
blobname 'rtl_nic[/]rtl8168g-1\.fw' drivers/net/ethernet/realtek/r8169.c
defsnc '[ ]static[ ]const[ ]u16[ ]mac_ocp_patch\[\][ ]=' in drivers/net/ethernet/realtek/r8169.c
blobname 'rt3290\.bin\(\.[\n][ ][ ][*][/]\)\?' drivers/net/wireless/rt2x00/rt2800pci.h
+
+ # New in 3.7:
+ blobname 'imx[/]sdma[/]sdma-imx6q-to1\.bin' arch/arm/boot/dts/imx6q.dtsi
+ accept 'AES_T[ed]:\([\n]\.word[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*[\n][@][ ]T[ed]4\[256\]\([\n]\.byte[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*\([\n][@][ ]rcon\[\]\([\n]\.word[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*\([,][ ]0\)*\)\?' arch/arm/crypto/aes-armv4.S
+ defsnc 'const[ ]u32[ ]cast5_s[1234]\[256\][ ]=' crypto/cast5_generic.c
+ defsnc 'const[ ]u32[ ]cast6_s[1234]\[256\][ ]=' crypto/cast6_generic.c
+ accept '[ ][*][ ]Once[ ]it[ ]returns[ ]successfully[,][ ]driver[ ]can[ ]use[ ]request_firmware' drivers/base/firmware_class.c
+ accept 'int[\n ]cache_firmware[(]const[ ]char[ ][*]fw_name[)][\n][{]\([\n]\+[^\n}][^\n]*\)*ret[ ]=[ ]request_firmware[(][^\n]*\([\n]\+[^\n}][^\n]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept '[ ][*][ ]If[ ]one[ ]device[ ]called[ ]request_firmware' drivers/base/firmware_class.c
+ defsnc 'static[ ]const[ ]struct[ ]mV_pos[ ]__cpuinitconst[ ]\(vrm85\|mobilevrm\)_mV\[32\][ ]=' drivers/cpufreq/longhaul.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]__cpuinitconst[ ]mV_\(vrm85\|mobilevrm\)\[32\][ ]=' drivers/cpufreq/longhaul.h
+ # Sources for these are in the corresponding .fuc files.
+ defsnc 'static[ ]u32[ ]nva3_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
+ defsnc 'static[ ]u32[ ]nvc0_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
+ defsnc 'static[ ]uint32_t[ ]nv98_pcrypt_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
+ defsnc 'uint32_t[ ]nve0_grgpc_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
+ defsnc 'uint32_t[ ]nve0_grhub_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
+ defsnc 'nv04_graph_ctx_regs\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nv04.c
+ accept '[ ]*ret[ ]=[ ]request_firmware[(]&fw[,][ ]source[,][ ]&nv_device[(]bios[)]->pdev->dev[)][;]' drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+ defsnc 'static[ ]u8[ ][*]edid_load[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*err[ ]=[ ]request_firmware[(][&]fw[,][ ]name[,][ ][&]pdev' drivers/gpu/drm/drm_edid_load.c
+ defsnc 'static[ ]const[ ]RegInitializer[ ]initData\[\][ ]__initconst[ ]=' drivers/ide/ali14xx.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_val[ ]tuner_init_fc2580\[\][ ]=' drivers/media/dvb-frontends/af9033_priv.h
+ defsnc '[ ]static[ ]const[ ]u8[ ]bw_params1\[3\]\[34\][ ]=' drivers/media/dvb-frontends/rtl2830.c
+ blobname 's5k4ecgx\.bin' drivers/media/i2c/s5k4ecgx.c
+ blobname 'v4l-coda\(dx6-imx27\|7541-imx53\)\.bin' drivers/media/platform/coda.c
+ blobname 's5p-mfc\(-v6\)\?\.fw' drivers/media/platform/s5p-mfc/s5p_mfc.c
+ defsnc 'static[ ]const[ ]struct[ ]e4000_lna_filter[ ]e400_lna_filter_lut\[\][ ]=' drivers/media/tuners/e4000_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]e4000_if_filter[ ]e4000_if_filter_lut\[\][ ]=' drivers/media/tuners/e4000_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]fc2580_reg_val[ ]fc2580_init_reg_vals\[\][ ]=' drivers/media/tuners/fc2580_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]fc2580_freq_regs[ ]fc2580_freq_regs_lut\[\][ ]=' drivers/media/tuners/fc2580_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5110_revb_patch\[\][ ]=' drivers/mfd/wm5110-tables.c
+ defsnc 'static[ ]struct[ ]nand_ecclayout[ ]lpc32xx_nand_oob[ ]=' drivers/mtd/nand/lpc32xx_mlc.c
+ defsnc 'static[ ]struct[ ]nand_ecclayout[ ]flctl_4secc_oob_64[ ]=' drivers/mtd/nand/sh_flctl.c
+ defsnc 'static[ ]const[ ]struct[ ]atl1c_platform_patch[ ]plats\[\][ ]__devinitconst[ ]=' drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+ defsnc 'static[ ]const[ ]u32[ ]ar9565_1p0_\(\(mac\|baseband\|radio\)_core\|[Cc]ommon_\(wo_xlna_\)\?rx_gain_table\)\[\]\[2\][ ]=' drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+ defsnc 'static[ ]const[ ]u32[ ]ar9565_1p0_\(\(mac\|baseband\)_postamble\|[Mm]odes_\(low\(est\)\?\|high\)_\(ob_db\|power\)_tx_gain_table\)\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+ defsnc 'static[ ]u16[ ]r2057_rev[4578]a\?_init\[[45][245]\]\[2\][ ]=' drivers/net/wireless/b43/radio_2057.c
+ defsnc '[ ]*tbl_rf_control_override_rev7_over[01]\[\][ ]=' drivers/net/wireless/b43/tables_nphy.c
+ defsnc 'static[ ]const[ ]unsigned[ ]pci_pins\[\][ ]=' drivers/pinctrl/spear/pinctrl-spear1310.c
+ defsnc 'static[ ]int[ ]array_soc\[\]\[2\][ ]=' drivers/power/88pm860x_battery.c
+ defsnc 'static[ ]const[ ]int[ ]mc13783_sw[12]x_val\[\][ ]=' drivers/regulator/mc13783-regulator.c
+ # remoteproc uses request_firmware, but it is generic and names
+ # no blobs of its own, so we change it to maybe_request_firmware.
+ accept '[ ]ret[ ]=[ ]request_firmware_nowait[(]THIS_MODULE[,][ ]FW_ACTION_HOTPLUG[,][\n][ ]*rproc->firmware[,][ ][&]rproc->dev[,][ ]GFP_KERNEL[,][\n][ ]*rproc[,][ ]rproc_fw_config_virtio[)][;][\n][ ]if[ ][(]ret[ ]<[ ]0[)][ ][{][\n][ ][ ]dev_err[(][&]rproc->dev[,][ ]["]request_firmware_nowait[ ]err' drivers/remoteproc/remoteproc_core.c
+ # This remoteproc client does name blobs, but we discard it
+ # with undefine_macro.
+ blob 'SPROC_MODEM_NAME[ ]["]-fw\.bin["]' drivers/remoteproc/ste_modem_rproc.c
+ accept '[ ]if[ ][(]request_firmware[(]&fw_entry,[ ]fname,[ ]&ioa_cfg->pdev->dev[)][)]' drivers/scsi/ipr.c
+ blobname 'daqboard2000_firmware\.bin' drivers/staging/comedi/drivers/daqboard2000.c
+ blobname 'me2600_firmware\.bin' drivers/staging/comedi/drivers/me_daq.c
+ blobname 'ni6534a\.bin' drivers/staging/comedi/drivers/ni_pcidio.c
+ blobname 'niscrb0[12]\.bin' drivers/staging/comedi/drivers/ni_pcidio.c
+ defsnc 'static[ ]const[ ]struct[ ]SiS_TVData[ ]XGI_\(St\|Ext\)\(PAL\|NTSC\|YPbPr\(525\|750\)[ip]\)Data\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]XGI330_\(NTSC\|PAL\|HiTV\(Ext\|St[12]\|Text\)\|YPbPr\(525\|750\)[ip]\)Timing\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]XGI330_\(HiTV\|Ren\(525\|750\)p\)Group3\(Data\|Simu\|Text\)\?\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ accept 'static[ ]inline[ ]int[\n]\(maybe_\)\?reject_ihex_firmware\(_nowait\)\?[(][^{;]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*[\n]\+[}]' include/linux/firmware.h
+ defsnc '[/][*][ ]callback[ ]from[ ]request_firmware_nowait' sound/pci/hda/hda_intel.c
+ defsnc 'static[ ]int[ ]__devinit[ ]azx_probe[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*request_firmware[^\n]*' sound/pci/hda/hda_intel.c
+ defsnc 'static[ ]struct[ ]reg_default[ ]da9055_reg_defaults\[\][ ]=' sound/soc/codecs/da9055.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]sta32x_regs\[\][ ]=' sound/soc/codecs/sta32x.c
+ blobname 'wm0010\(_stage2\.bin\|\.dfw\)' sound/soc/codecs/wm0010.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5102_sysclk_reva_patch\[\][ ]=' sound/soc/codecs/wm5102.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8510_reg_defaults\[\][ ]=' sound/soc/codecs/wm8510.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8580_reg_defaults\[\][ ]=' sound/soc/codecs/wm8580.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8776_reg_defaults\[\][ ]=' sound/soc/codecs/wm8776.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8900_reg_defaults\[\][ ]=' sound/soc/codecs/wm8900.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8960_reg_defaults\[\][ ]=' sound/soc/codecs/wm8960.c
+ accept '[ ][ ]priv->firmware[ ]=[ ]true[;]' drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+ accept '[ ][ ]*\(if[ ][(]\|[ ][ ][ ][ ]\)nvc0_graph_ctor_fw[(]priv[,][ ]["]fuc4\(09\|1a\)[cd]["][,][ ][&]priv->fuc4\(09\|1a\)[cd][)]' 'drivers/gpu/drm/nouveau/core/engine/graph/nv[ce]0\.c'
+ accept '[ ][ ]*nvc0_graph_dtor_fw[(]&priv->fuc4\(09\|1a\)[cd][)][;]' 'drivers/gpu/drm/nouveau/nv[ce]0\.c'
+ accept '[ ][ ]*nvc0_graph_init_fw[(]priv[,][ ]0x4\(09\|1a\)000[,][ ][&]priv->fuc4\(09\|1a\)c[,][ \n ]*[&]priv->fuc4\(09\|1a\)d[)][;]' 'drivers/gpu/drm/nouveau/core/engine/graph/nv[ce]0\.c'
+ blobname 'dvb-fe-xc5000c-4\.1\.30\.7\.fw' drivers/media/tuners/xc5000.c
+ accept '[ ]\.firmware[ ]=[ ]AF9015_FIRMWARE' drivers/media/usb/dvb-usb-v2/af9015.c
+ accept '[ ]\.firmware[ ]=[ ]AF9035_FIRMWARE' drivers/media/usb/dvb-usb-v2/af9035.c
+ accept '[ ]\.firmware[ ]*=[ ]AZ6007_FIRMWARE' drivers/media/usb/dvb-usb-v2/az6007.c
+ accept '[ ]\.firmware[ ]=[ ]EC168_FIRMWARE' drivers/media/usb/dvb-usb-v2/ec168.c
+ blobname 'brcm[/]brcmfmac43\(143\|242a\)\.bin' drivers/net/wireless/brcm80211/brcmfmac/usb.c
+ accept '[ ]priv->firmware[ ]=[ ]fw[;]' drivers/net/wireless/p54/p54pci.c
+ blobname 'c[bt]2\?fw-3\.1\.0\.0\.bin' drivers/scsi/bfa/bfad.c
+ blobname 'gdmuimg\.bin' drivers/staging/gdm72xx/usb_boot.c
+ blobname 'CMV4[pi]\.bin\(\.v2\)\?' drivers/usb/atm/ueagle-atm.c
+ blobname 'dvb-fe-tda10071\.fw' drivers/media/dvb/frontends/tda10071_priv.h
+ accept '[ ]st->it913x_config\.firmware[ ]=' drivers/media/usb/dvb-usb-v2/it913x.c
;;
*/*freedo*.patch | */*logo*.patch)
@@ -3158,6 +3241,350 @@ set_except () {
accept 'MODULE_FIRMWARE[(]["]keyspan_pda[/]\(keyspan_pda\|xircom_pgs\)\.fw["][)][;]' drivers/usb/serial/keyspan_pda.c
# Present in patch for 3.6.5.
defsnc 'static[ ]const[ ]u32[ ]ar9300Modes_high_power_tx_gain_table_2p2\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+ # Specific to the 3.7 patch
+ accept '[ ]\.firmware[ ]*=[ ]["][/][*][(]DEBLOBBED[)][*][/]["]'
+ accept '[ ]\(p1100\|s660\|p7500\)->firmware[ ]=[ ]["][/][*][(]DEBLOBBED[)][*][/]["]'
+ accept '[ ]-[ ]calls[ ]request_firmware[(]' Documentation/firmware_class/README
+ accept '[ ]7[)],[ ]kernel:[ ]request_firmware[(]' Documentation/firmware_class/README
+ accept '[ ][ ]request_firmware[(][)][ ]returns[ ]non-zero' Documentation/firmware_class/README
+ accept '\(static[ ]\(int\|void\)[\n ]\)\?_request_firmware\(_prepare\|_cleanup\)\?[(]const[ ]struct[ ]firmware[ ][*][*]\?' drivers/base/firmware_class.c
+ accept '[ ][ ]_request_firmware_cleanup[(]firmware_p[)][;]' drivers/base/firmware_class.c
+ accept '[ ][*][ ]Asynchronous[ ]variant[ ]of[ ]request_firmware[(][)]' drivers/base/firmware_class.c
+ accept 'request_firmware\(_nowait\)\?[(]' drivers/base/firmware_class.c
+ accept 'static[ ]inline[ ]int[ ]request_firmware\(_nowait\)\?[(]' include/linux/firmware.h
+ accept '[ ][ ]err[ ]=[ ]request_firmware_nowait[(]THIS_MODULE,[ ]true,[ ]patch\[dev\],' sound/pci/hda/hda_intel.c
+ accept '[ ][{]0x00009e1c,[ ]0x0001cf9c,[ ]0x[0-9a-fx{},\n ]*' drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+ accept '[;][/][*]@@[ ]-391,17[ ][+]407,17[ ]@@[*][/][;][\n]\([ ]*[123],\)*[\n]\(\([ ]*[ 1234][0-9],\)*[\n]\)*[\n]\(\([ ]*[ 1234][0-9],\)*[\n]\)*\([ ]*1,\)*' scripts/dtc/dtc-lexer.lex.c_shipped
+ accept '[;][/][*]@@[ ]-395,16[ ][+]423,16[ ]@@[*][/][;][\n][ ]*0,\([ ]*2,\)*[\n]\(\([ ]*[ 1234][0-9],\)*[\n]\)*\([ ]*2,\)*' scripts/dtc/dtc-parser.tab.c_shipped
+ accept '[;][/][*]@@[ ]-418,45[ ][+]446,68[ ]@@[*][/][;][\n]\([ ]*[2],\)*[\n]\(\([ ]*[ 12][0-9],\)*[\n]\)*\([ ]*[12][0-9],\)*[ ]*24' scripts/dtc/dtc-parser.tab.c_shipped
+
+ # Already in 3.6, but changed or moved thus present in patch to 3.7:
+ initnc '[/][*][\n][ ][*][ ]\(cfa_coef\|gamma\|luma_enhance\|noise_filter\)_table\.h[\n][ ][*]\([^\n]*[\n][ ][*]\)*[/]' 'drivers/media/video/omap3isp/\(cfa_coef\|gamma\|luma_enhance\|noise_filter\)_table\.h'
+ accept '[ ][ ][ ][/][*][ ]\(SQCIF\|QSIF\|QCIF\|SIF\|CIF\|VGA\)[ ][*][/][\n][ ][ ][ ][{][\n][ ][ ][ ][ ][ ][ ][{]'"$blobpat*" drivers/media/video/pwc/pwc-nala.h
+ accept 'FIRMWARE[ ]LOADER[ ][(]request_firmware[)]' MAINTAINERS
+ accept '[ ]INIT_WORK[(][&]fw_work->work[,][ ]request_firmware_work_func[)][;]' drivers/base/firmware_class.c
+ accept '[ ]\+request_firmware[(][)][ ]will[ ]hit[ ]an[ ]OOPS' drivers/media/dvb/frontends/dib7000p.c
+ defsnc 'static[ ]struct[ ]clk_pll_\(freq_\)\?table[ ]tegra_pll_[adpxm]_\(freq_\)\?table\[\][ ]=' arch/arm/mach-tegra/tegra2_clocks.c
+ defsnc 'static[ ]struct[ ]clk_pll_freq_table[ ]tegra_pll_[cu]_freq_table\[\][ ]=' arch/arm/mach-tegra/tegra30_clocks.c
+ defsnc 'const[ ]u64[ ]camellia_sp\(10011110\|22000222\|03303033\|00444404\|02220222\|30333033\|44044404\|11101110\)\[256\][ ]=' arch/x86/crypto/camellia_glue.c
+ defsnc 'static[ ]const[ ]u32[ ]s[1-7]\[256\][ ]=' crypto/cast5_generic.c
+ defsnc 'static[ ]const[ ]u32[ ]sb8\[256\][ ]=' crypto/cast5_generic.c
+ defsnc 'static[ ]const[ ]u32[ ]Tm\[24\]\[8\][ ]=' crypto/cast6_generic.c
+ defsnc 'static[ ]const[ ]u8[ ]Tr\[4\]\[8\][ ]=' crpto/cast6_generic.c
+ defsnc 'static[ ]struct[ ]cipher_testvec[ ]\(aes\|anubis\|bf\|camellia\|cts_mode\|des3_ede\|cast6\|salsa20_stream\|serpent\|tf\|tnepres\|xeta\|x\?tea\)\(_\(cbc\|ctr\(_rfc3686\)\?\|xts\)\)\?_\(enc\|dec\)_tv_template\[\][ ]=' 'crypto/\(tcrypt\|testmgr\).h'
+ accept '\([ ]request_firmware[(][)][ ]hotplug[ ]interface:[\n][ ]--*[\n].*[ ]\)\?-[ ]request_firmware_nowait[(][)][ ]is[ ]also[ ]provided[ ]for[ ]convenience' Documentation/firmware_class/README
+ accept '\(static[ ]\(int\|void\)[\n ]\)\?_request_firmware\(_prepare\|_cleanup\)\?[(]const[ ]struct[ ]firmware[ ][*][*]\?firmware\(_p\)\?[,)][^{]*[\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept 'static[ ]int[ ]_request_firmware_load[(]struct[ ]firmware_priv[ ][*]fw_priv[,]' drivers/base/firmware_class.c
+ accept 'static[ ]void[ ]request_firmware_work_func[(]struct[ ]work_struct[ ][*]work[)]' drivers/base/firmware_class.c
+ accept 'EXPORT_SYMBOL[(]request_firmware\(_nowait\)\?[)][;]' drivers/base/firmware_class.c
+ accept '[ ]fw_priv[ ]=[ ]_request_firmware_prepare[(][&]fw[,]' drivers/base/firmware_class.c
+ accept '[ ][ ]ret[ ]=[ ]_request_firmware_load[(]fw_priv[,]' drivers/base/firmware_class.c
+ accept '[ ][ ]_request_firmware_cleanup[(][&]fw[)][;]' drivers/base/firmware_class.c
+ defsnc 'uint32_t[ ]nvc0_grgpc_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h
+ defsnc 'uint32_t[ ]nvc0_grhub_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h
+ defsnc 'static[ ]int[ ]nv10_graph_ctx_regs[ ]\?\[\][ ]=' drivers/char/drm/nv10_graph.c
+ defsnc 'static[ ]int[ ]types\[0x80\][ ]=' drivers/gpu/drm/nouveau/nv50_vram.c
+ defsnc 'static[ ]const[ ]u8[ ]types\[256\][ ]=' drivers/gpu/drm/nouveau/nvc0_vram.c
+ defsnc 'static[ ]u8[ ]samsung_tbmu24112_inittab\[\][ ]=' drivers/media/common/b2c2/flexcop-fe-tuner.c
+ defsnc 'static[ ]u8[ ]alps_tdee4_stv0297_inittab\[\][ ]=' drivers/media/common/b2c2/flexcop-fe-tuner.c
+ defsnc '[}][ ]hps_h_coeff_tab[ ]\[\][ ]=' drivers/media/common/saa7146/saa7146_hlp.c
+ defsnc '[}][ ]hps_v_coeff_tab[ ]\[\][ ]=' drivers/media/common/saa7146/saa7146_hlp.c
+ defsnc 'static[ ]unsigned[ ]int[ ]bitrates\[3\]\[16\][ ]=' drivers/media/dvb-core/dvb_filter.c
+ defsnc 'static[ ]unsigned[ ]int[ ]ac3_bitrates\[32\][ ]=' drivers/media/dvb-core/dvb_filter.c
+ defsnc 'static[ ]u32[ ]ac3_frames\[3\]\[32\][ ]=' drivers/media/dvb-core/dvb_filter.c
+ defsnc 'static[ ]const[ ]unsigned[ ]short[ ]logtable\[256\][ ]=' drivers/media/dvb-core/dvb_math.c
+ defsnc 'static[ ]const[ ]struct[ ]af9013_coeff[ ]coeff_lut\[\][ ]=' drivers/media/dvb/frontends/af9013_priv.h
+ defsnc 'static[ ]\(const[ ]\)\?struct[ ]\(snr_table\|af9013_snr\)[ ]\(qpsk\|qam\(16\|64\)\)_snr_\(table\|lut\)\[\][ ]=' drivers/media/dvb/frontends/af9013_priv.h
+ defsnc 'static[ ]\(const[ ]\)\?struct[ ]\(regdesc\|af9013_reg_bit\)[ ]\(ofsm_init\|tuner_init_\(env77h11d5\|mt2060\(_2\)\?\|mxl500\(3d\|5\)\|qt1010\|mc44s803\|unknown\|tda18271\)\)\[\][ ]=' drivers/media/dvb/frontends/af9013_priv.h
+ defsnc '[ ]struct[ ]reg_val_mask[ ]tab\[\][ ]=' 'drivers/media/dvb/frontends/\(cxd2820r_\(c\|t2\)\|af9033\)\.c'
+ defsnc 'static[ ]const[ ]struct[ ]coeff[ ]coeff_lut\[\][ ]=' drivers/media/dvb/frontends/af9033_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]val_snr[ ]\(qpsk\|qam\(16\|64\)\)_snr_lut\[\][ ]=' drivers/media/dvb/frontends/af9033_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]reg_val[ ]\(ofsm_init\|tuner_init_\(tua9001\|fc0011\|mxl5007t\|tda18218\)\)\[\][ ]=' drivers/media/dvb/frontends/af9033_priv.h
+ defsnc '\(static[ ]\)\?\(const[ ]\)\?struct[ ]au8522_register_config[ ]lpfilter_coef\[\][ ]=' drivers/media/dvb/frontends/au8522_decoder.c
+ defsnc 'static[ ]struct[ ]mse2snr_tab[ ]\(vsb\|qam\(64\|256\)\)_mse2snr_tab\[\][ ]=' drivers/media/dvb/frontends/au8522.c
+ defsnc '[}][ ]\(VSB\|QAM\(64\|256\)\?\)_mod_tab\[\][ ]=' 'drivers/media/dvb/frontends/au8522\(_dig\)\?\.c'
+ defsnc 'static[ ]u8[ ]stv0288_bsbe1_d01a_inittab\[\][ ]=' drivers/media/dvb/frontends/bsbe1-d01a.h
+ defsnc 'static[ ]\(const[ ]\)\?u8[ ]init_tab[ ]\?\[\][ ]=' 'drivers/media/dvb/frontends/cx2270\(0\|2\)\.c'
+ defsnc 'static[ ]const[ ]u16[ ]dib0090_defaults\[\][ ]=' drivers/media/dvb/frontends/dib0090.c
+ defsnc 'static[ ]const[ ]struct[ ]dib0090_pll[ ]dib0090_\(p1g_\)\?pll_table\[\][ ]=' drivers/media/dvb/frontends/dib0090.c
+ defsnc '[ ]static[ ]u8[ ]sine\[\][ ]=' drivers/media/dvb/frontends/dib7000p.c
+ accept '[ ]\+request_firmware[(][)][ ]will[ ]hit[ ]an[ ]OOPS' drivers/media/dvb/frontends/dib7000p.c
+ defsnc '\(static[ ]const[ ]\)\?u32[ ]fe_info\[44\][ ]=' drivers/media/dvb/frontends/dib9000.c
+ defsnc 'static[ ]u8[ ]ds3000_dvbs2\?_init_tab\[\][ ]=' drivers/media/dvb/frontends/ds3000.c
+ defsnc '[ ]static[ ]const[ ]u16[ ]dvbs2_snr_tab\[\][ ]=' drivers/media/dvb/frontends/ds3000.c
+ defsnc 'static[ ]struct[ ]dvb_pll_desc[ ][^\n]*[ ]=[ ][{]' drivers/media/dvb/frontends/dvb-pll.c
+ defsnc 'static[ ]u8[ ]stv0288_earda_inittab\[\][ ]=' drivers/media/dvb/frontends/eds1547.h
+ defsnc 'static[ ]const[ ]struct[ ]reg_mod_vals[ ]reg_mod_vals_tab\[\][ ]=' drivers/media/dvb/frontends/hd29l2_priv.h
+ defsnc 'static[ ]struct[ ]adctable[ ]tab[1-8]\[\][ ]=' drivers/media/dvb/frontends/it913x-fe-priv.h
+ initnc '[}][ ]itd1000_\(lpf_pga\|fre_values\)\[\][ ]=' drivers/media/dvb/frontends/itd1000.c
+ defsnc 'static[ ]const[ ]struct[ ]cnr[ ]cnr_tab\[\][ ]=' drivers/media/dvb/frontends/mb86a16.c
+ defsnc 'static[ ]struct[ ]regdata[ ]mb86a20s_init\[\][ ]=' drivers/media/dvb/frontends/mb86a20s.c
+ defsnc '[ ]struct[ ]rtl2830_reg_val_mask[ ]tab\[\][ ]=' drivers/media/dvb/frontends/rtl2830.c
+ defsnc '[ ]static[ ]u8[ ]bw_params1\[3\]\[34\][ ]=' drivers/media/dvb/frontends/rtl2830.c
+ defsnc '[ ]static[ ]u8[ ]bw_params\[3\]\[32\][ ]=' drivers/media/dvb/frontends/rtl2832.c
+ defsnc '[}][ ]init_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
+ defsnc '[}][ ]vsb_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
+ defsnc '[}][ ]qam256_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
+ defsnc '[}][ ]qam64_snr_tab\[\][ ]=' drivers/media/dvb-frontends/s5h1409.c
+ defsnc 'static[ ]struct[ ]regdata[ ]s921_init\[\][ ]=' drivers/media/dvb/frontends/s921.c
+ defsnc 'static[ ]u8[ ]serit_sp1511lhb_inittab\[\][ ]=' drivers/media/dvb/frontends/si21xx.c
+ defsnc 'static[ ]\(const[ ]\)\?struct[ ]stb0899_tab[ ]stb0899_\(cn\|dvbs2\?rf\|quant\|est\)_tab\[\][ ]=' drivers/media/dvb/frontends/stb0899_drv.c
+ defsnc 'static[ ]const[ ]struct[ ]stb6100_lkup[ ]lkup\[\][ ]=' drivers/media/dvb/frontends/stb6100.c
+ defsnc 'static[ ]u8[ ]stv0288_inittab\[\][ ]=' drivers/media/dvb/frontends/stv0288.c
+ defsnc 'static[ ]u8[ ]tda10021_inittab\[0x40\]=' drivers/media/dvb/frontends/tda10021.c
+ initnc '[}][ ]snr_tab\[\][ ]=' drivers/media/dvb/frontends/tda10048.c
+ defsnc '[ ]struct[ ]tda10071_reg_val_mask[ ]tab2\[\][ ]=' drivers/media/dvb/frontends/tda10071.c
+ defsnc '[ ]static[ ]u8[ ]InitRegs\[\][ ]=' drivers/media/dvb/frontends/tda18271c2dd.c
+ defsnc 'static[ ]struct[ ]SMapI[ ]m_RF_Cal_Map\[\][ ]=' drivers/media/dvb/frontends/tda18271c2dd_maps.h
+ defsnc 'static[ ]struct[ ]SMap2[ ]m_\(Main\|Cal\)_PLL_Map\[\][ ]=' drivers/media/dvb/frontends/tda18271c2dd_maps.h
+ defsnc 'static[ ]struct[ ]SMap2\?[ ]*m_\(GainTaper\|RF_Cal_DC_Over_DT\|CID_Target\)_Map\[\][ ]=' drivers/media/dvb/frontends/tda18271c2dd_maps.h
+ defsnc 'static[ ]u8[ ]tda8083_init_tab[ ]\[\][ ]=' drivers/media/dvb/frontends/tda8083.c
+ defsnc 'static[ ]u8[ ]ves1820_inittab\[\][ ]=' drivers/media/dvb/frontends/ves1820.c
+ defsnc 'static[ ]u8[ ]init_1[89]93_w\?tab[ ]\?\[\][ ]=' drivers/media/dvb/frontends/ves1x93.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]biphase_tbl\[\][ ]='
+ initnc 'static[ ]struct[ ]regval_list[ ]ov7670_default_regs\[\][ ]=' drivers/media/i2c/ov7670.c
+ defsnc 'static[ ]struct[ ]s5k6aa_regval[ ]s5k6aa_analog_config\[\][ ]=' drivers/media/video/s5k6aa.c
+ initnc 'static[ ]u32[ ]reg_init_initialize\[\][ ]=' drivers/media/video/saa717x.c
+ initnc '[ ][}][ ]vals\[\][ ]=' drivers/media/video/saa717x.c
+ defsnc 'static[ ]const[ ]struct[ ]regval_list[ ]ov2640_init_regs\[\][ ]=' drivers/media/video/ov2640.c
+ defsnc 'static[ ]struct[ ]regval_list[ ]ov5642_default_regs_\(init\|finalise\)\[\][ ]=' drivers/media/video/ov5642.c
+ defsnc 'static[ ]const[ ]struct[ ]ov9640_reg[ ]ov9640_regs_dflt\[\][ ]=' drivers/media/video/ov9640.c
+ defsnc 'static[ ]const[ ]struct[ ]ov9740_reg[ ]ov9740_defaults\[\][ ]=' drivers/media/video/ov9740.c
+ defsnc '\(const[ ]static\|static[ ]const\)[ ]struct[ ]rj54n1_reg_val[ ]bank_[4578]\[\][ ]=' drivers/media/video/rj54n1cb0c.c
+ defsnc 'static[ ]const[ ]u16[ ]vs6624_p1\[\][ ]=' drivers/media/video/vs6624.c
+ defsnc '[ ]unsigned[ ]char[ ]saa7111_regs\[\][ ]=' drivers/media/parport/w9966.c
+ initnc 'static[ ]int[ ]miro_fmtuner\[\][ ][ ]=' drivers/media/video/bt8xx/bt-cards.c
+ initnc 'static[ ]int[ ]miro_tunermap\[\][ ]=' drivers/media/video/bt8xx/bt-cards.c
+ defsnc 'static[ ]u8[ ]SRAM_Table\[\]\[60\][ ]=' drivers/media/pci/bt8xx/bttv-driver.c
+ defsnc '[ ]static[ ]u8[ ]init_bufs\[13\]\[5\][ ]=' drivers/media/pci/cx88/cx88-cards.c
+ defsnc 'static[ ]\(const[ ]\)\?u8[ ]samsung_smt_7020_inittab\[\][ ]=' drivers/media/video/cx88/cx88-dvb.c
+ initnc '[ ]static[ ]const[ ]u8[ ]mpeg_hdr_data\[\][ ]=' drivers/media/video/cx18/cx18-vbi.c
+ defsnc 'u8[ ]lgtdqcs001f_inittab\[\][ ]=' drivers/media/dvb/mantis/mantis_vp1033.c
+ defsnc '[ ]static[ ]u16[ ]jpeg_tables\[\]\[70\][ ]=' drivers/media/pci/meye/meye.c
+ defsnc '[ ]static[ ]u16[ ]tables\[\][ ]=' drivers/media/pci/meye/meye.c
+ defsnc 'static[ ]u8[ ]ITUDecoderSetup\[4\]\[16\][ ]=' drivers/media/dvb/ngene/ngene-core.c
+ defsnc 'static[ ]const[ ]u8[ ]va1j5jf8007[ts]_\(2[05]mhz_\)\?prepare_bufs\[\]\[2\][ ]=' 'drivers/media/dvb/pt1/va1j5jf8007[st]\.c'
+ defsnc '[}][ ]mxb_saa7740_init\[\][ ]=' drivers/media/pci/saa7146/mxb.c
+ defsnc 'static[ ]u8[ ]nexusca_stv0297_inittab\[\][ ]=' drivers/media/dvb/ttpci/av7110.c
+ accept '[ ]const[ ]char[ ]\*fw_name[ ]=[ ]["]av7110[/]bootcode\.bin["][;]' drivers/media/dvb/ttpci/av7110_hw.c
+ accept '[ ]ret[ ]=[ ]request_firmware[(][^;]*[)][;][\n][ ]if[ ][(]ret[)][ ][{][^}]*[}][\n][\n][ ]mwdebi[(]av7110,[ ]DEBISWAB,[ ]DPRAM_BASE' drivers/media/dvb/ttpci/av7110_fw.c
+ accept 'MODULE_FIRMWARE[(]["]av7110[/]bootcode\.bin["][)][;]' drivers/media/dvb/ttpci/av7110_fw.c
+ defsnc 'static[ ]u16[ ]default_key_map[ ]\[256\][ ]=' drivers/media/pci/ttpci/av7110_ir.c
+ defsnc 'static[ ]u8[ ]saa7113_init_regs\[\][ ]=' drivers/media/pci/ttpci/av7110_v4l.c
+ defsnc 'static[ ]const[ ]u8[ ]saa7113_tab\[\][ ]=' drivers/media/dvb/ttpci/budget-av.c
+ defsnc 'static[ ]u8[ ]philips_sd1878_inittab\[\][ ]=' drivers/media/dvb/ttpci/budget-av.c
+ defsnc 'static[ ]u8[ ]philips_su1278_tt_inittab\[\][ ]=' drivers/media/dvb/ttpci/budget-ci.c
+ defsnc 'static[ ]u8[ ]dvbc_philips_tdm1316l_inittab\[\][ ]=' drivers/media/dvb/ttpci/budget-ci.c
+ defsnc 'static[ ]const[ ]char[ ]zr360[56]0_dqt\[0x86\][ ]=' 'drivers/media/video/zr36060\.c\|drivers/media/video/zoran/zr36060\.c'
+ defsnc 'static[ ]const[ ]char[ ]zr360[56]0_dht\[0x1a4\][ ]=' 'drivers/media/video/zr36060\.c\|drivers/media/video/zoran/zr36060\.c'
+ defsnc 'static[ ]const[ ]char[ ]zr360[56]0_dqt\[0x86\][ ]=' 'drivers/media/video/zr36060\.c\|drivers/media/video/zoran/zr36060\.c'
+ defsnc 'static[ ]const[ ]struct[ ]isprsz_coef[ ]filter_coefs[ ]=' drivers/media/video/omap3isp/ispresizer.c
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]qtbl_\(lu\|chro\)minance\[4\]\[64\][ ]=' drivers/media/video/s5p-jpeg/jpeg-core.c
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]hactblg0\[162\][ ]=' drivers/media/video/s5p-jpeg/jpeg-core.c
+ defsnc 'static[ ]const[ ]struct[ ]hdmiphy_conf[ ]hdmiphy_conf_\(s5pv210\|exynos4[24]1[02]\)\[\][ ]=' drivers/media/video/s5p-tv/hdmiphy_drv.c
+ defsnc 'static[ ]const[ ]u8[ ]filter_y_vert_tap4\[\][ ]=' drivers/media/video/s5p-tv/mixer_reg.c
+ initnc 'static[ ]u8[ ]mt2131_config1\[\][ ]=' drivers/media/common/tuners/mt2131.c # >= 2.6.26
+ initnc 'static[ ]u8[ ]mt2266_init2\[\][ ]=' drivers/media/common/tuners/mt2266.c # >= 2.6.26
+ defsnc '[ ]static[ ]u8[ ]def_regs\[\][ ]=' drivers/media/common/tuners/tda18218.c
+ defsnc '[ ]static[ ]unsigned[ ]char[ ]iso_regs\[8\]\[4\][ ]=' drivers/media/usb/cpia2/cpia2_usb.c
+ initnc '[ ][ ]u8[ ]buf,[ ]bufs\[\][ ]=' drivers/media/dvb/dvb-usb/cxusb.c
+ defsnc 'static[ ]struct[ ]dib0090_wbd_slope[ ]dib7090e_wbd_table\[\][ ]=' drivers/media/dvb/dvb-usb/dib0700_devices.c
+ defsnc '[ ][}][ ]regs\[\][ ]=' drivers/media/video/em28xx/em28xx-dvb.c
+ defsnc 'static[ ]u8[ ]init_code\[\]\[2\][ ]=' drivers/media/dvb/dvb-usb/friio-fe.c
+ defsnc 'static[ ]u8[ ]opera1_inittab\[\][ ]=' drivers/media/usb/dvb-usb/opera1.c
+ defsnc 'static[ ]u8[ ]s7395_inittab\[\][ ]=' drivers/media/dvb/dvb-usb/lmedm04.h
+ defsnc '[ ][}][ ]regs\[\][ ]=' drivers/media/video/em28xx/em28xx-dvb.c
+ defsnc 'static[ ]const[ ]__u8[ ]cx11646_fw1\[\]\[3\][ ]=' drivers/media/video/gspca/conex.c
+ defsnc 'static[ ]const[ ]__u8[ ]cx_inits_\(176\|320\|352\|640\)\[\][ ]=' drivers/media/video/gspca/conex.c
+ defsnc 'static[ ]const[ ]__u8[ ]cx_jpeg_init\[\]\[8\][ ]=' drivers/media/video/gspca/conex.c
+ defsnc 'static[ ]const[ ]__u8[ ]cxjpeg_\(640\|352\|320\|176\|qtable\)\[\]\[8\][ ]=' drivers/media/video/gspca/conex.c
+ defsnc 'static[ ]struct[ ]validx[ ]tbl_\(commm\?on\|init_\(at_startup\|post_alt\)\|sensor_settings_common\(_[ab]\|1\)\|big\(_[abc]\|[123]\)\|640\|800\)\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi2020\|mi1320\|ov9655\|ov2640\).c'
+ defsc 'static[ ]struct[ ]idxdata[ ]tbl_common\(_[a-e]\|5\|_\?3B\?\)\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi2020\|mi1320\|ov9655\|ov2640\)\.c'
+ defsnc 'static[ ]u8[ ][*]tbl_\(640\|800\|1280\)\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi1320\|ov9655\).c'
+ defsnc '[ ]struct[ ]jlj_command[ ]start_commands\[\][ ]=' drivers/media/video/gspca/jeilinj.c
+ defsnc 'static[ ]const[ ]u8[ ]jpeg_head\[\][ ]=' drivers/media/video/gspca/jpeg.h
+ defsnc '[ ][ ]\(static[ ]\)\?const[ ]struct[ ]sensor_w_data[ ]\(cif\|vga\)_sensor[01]_init_data\[\][ ]=' drivers/media/video/gspca/mr97310a.c
+ defsnc 'static[ ]const[ ]u8[ ]\(nw80[012]\|spacecam2\?\|cvideopro\|dlink\|ds3303\|kr651\|kritter\|mustek\|proscope\|twinkle\|dvcv6\)_start\(_\([12]\|q\?vga\)\)\?\[\][ ]=' drivers/media/video/gspca/nw80x.c
+ defsnc 'static[ ]const[ ]struct[ ]ov_i2c_regvals[ ]norm_7660\[\][ ]=' drivers/media/video/ov519.c
+ initc '[ ]\?static[ ]const[ ]struct[ ]ov_i2c_regvals[ ]norm_76[1247]0\[\][ ]=' drivers/media/video/gspca/ov519.c
+ defsnc '[ ]const[ ]unsigned[ ]char[ ]\(y\|uv\)QuanTable51[18]\[\][ ]=' 'drivers/media/video/\(ov511\|gspca/ov519\)\.c'
+ defsnc '[ ]static[ ]const[ ]struct[ ]ov_regvals[ ]bridge_ov7660\[2\]\[10\][ ]=' drivers/media/video/gspca/ov519.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]fr_tb\[2\]\[6\]\[3\][ ]=' drivers/media/video/gspca/ov519.c
+ defsnc '[ ]static[ ]const[ ]struct[ ]ov_i2c_regvals[ ]\(brit\|contrast\|colors\)_7660\[\]\[\(6\|7\|31\)\][ ]=' drivers/media/video/gspca/ov519.c
+ defsnc 'static[ ]const[ ]u8[ ]\(bridge\|sensor\)_init\(_2\)\?\[\]\[2\][ ]=' drivers/media/video/gspca/ov534_9.c
+ defsnc 'static[ ]const[ ]u8[ ]\(ov965x\|ov971x\|ov562x\)_init\(_2\)\?\[\]\[2\][ ]=' drivers/media/video/gspca/ov534_9.c
+ defsnc 'static[ ]const[ ]u8[ ]bridge_start_\([qs]\?v\|x\)ga\[\]\[2\][ ]=' drivers/media/video/gspca/ov534_9.c
+ defsnc 'static[ ]const[ ]u8[ ]\(bridge\|sensor\)_init_7\(67\|72\)x\[\]\[2\][ ]=' drivers/media/video/gspca/ov534.c
+ defsnc '[ ]*static[ ]u8[ ]color_tb\[\]\[6\][ ]=' drivers/media/video/gspca/ov534.c
+ initnc 'static[ ]const[ ]__u8[ ]pac207_sensor_init\[\]\[8\][ ]=' drivers/media/video/gspca/pac207.c
+ defsnc 'static[ ]const[ ]u8[ ]\(start\|page3\)_7302\[\][ ]=' drivers/media/video/gspca/pac7302.c
+ initnc 'static[ ]const[ ]__u8[ ]pac7311_jpeg_header\[\][ ]=' drivers/media/video/gspca/pac7311.c
+ defsnc 'static[ ]const[ ]__u8[ ]\(start\|page[34]\)_73\(02\|11\)\[\][ ]=' drivers/media/video/gspca/pac7311.c
+ defsnc '[ ]struct[ ]init_command[ ]\(spy\|cif\|ms350\|genius\|vivitar\)_start_commands\[\][ ]=' drivers/media/video/gspca/sn9c2028.c
+ defsnc 'static[ ]const[ ]\(int\|s16\)[ ]hsv_\(red\|green\|blue\)_[xy]\[\][ ]=' drivers/media/video/gspca/sn9c20x.c
+ defsnc 'static[ ]const[ ]u16[ ]bridge_init\[\]\[2\][ ]=' drivers/media/video/gspca/sn9c20x.c
+ defsnc 'static[ ]const[ ]struct[ ]i2c_reg_u8[ ]\(soi968\|ov\(7670\|965[05]\)\|hv7131r\)_init\[\][ ]=' drivers/media/video/gspca/sn9c20x.c
+ defsnc 'static[ ]const[ ]struct[ ]i2c_reg_u16[ ]\(mt9v[01]1[12]\)_init\[\][ ]=' drivers/media/video/gspca/sn9c20x.c
+ initnc 'static[ ]const[ ]__u8[ ]init\(Hv7131\|Ov\(6650\|7630\(_3\)\?\)\|Pas\(106\|202\)\|Tas51[13]0\)\[\][ ]=' drivers/media/video/gspca/sonixb.c
+ initnc 'static[ ]const[ ]__u8[ ]\(hv7131\|ov\(6650\|7630\(_3\)\?\)\|pas\(106\|202\)\|tas51[13]0\)_sensor_init\(_com\)\?\[\]\[8\][ ]=' drivers/media/video/gspca/sonixb.c
+ defsnc 'static[ ]const[ ]u8[ ]\(adcm1700\|om6802\|po1030\)_sensor_\(init\|param1\)\[\]\[8\][ ]=' drivers/media/video/gspca/sonixj.c
+ defsnc 'static[ ]const[ ]u8[ ]\(gc0307\|po2030n\|soi768\)_sensor_\(init\|param1\)\[\]\[8\][ ]=' drivers/media/video/gspca/sonixj.c
+ defsnc 'static[ ]\(const[ ]\)\?\(__\)\?u8[ ]\(mt9v111\|sp80708\|hv7131[rd]\|mi0360b\?\|mo4000\|ov76\([36]0\|48\)\|om6802\|po1030\)_sensor_\(init\|param1\)\[\]\[8\][ ]=' drivers/media/video/gspca/sonixj.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]probe_tb\[\]\[4\]\[8\][ ]=' drivers/media/video/gspca/sonixj.c
+ initnc 'static[ ]const[ ]__u16[ ]\(spca500_visual\|Clicksmart510\)_defaults\[\]\[3\][ ]=' drivers/media/video/gspca/spca500.c
+ initnc 'static[ ]const[ ]__u8[ ]qtable_\(creative_pccam\|kodak_ez200\|pocketdv\)\[2\]\[64\][ ]=' drivers/media/video/gspca/spca500.c
+ initnc 'static[ ]const[ ]__u16[ ]spca501c\?_\(\(3com\|arowana\|mysterious\)_\)\?\(init\|open\)_data\[\]\[3\][ ]=' drivers/media/video/gspca/spca501.c
+ defsnc 'static[ ]const[ ]\(__u16\|u8\)[ ]spca505b\?_\(init\|open\)_data\(_ccd\)\?\[\]\[3\][ ]=' drivers/media/video/gspca/spca505.c
+ defsnc 'static[ ]const[ ]\(__\)\?u16[ ]spca508\(cs110\|_sightcam2\?\|_vista\)\?_init_data\[\]\[[23]\][ ]=' drivers/media/video/gspca/spca508.c
+ defsnc 'static[ ]const[ ]struct[ ]ucbus_write_cmd[ ]\(icx098bq\|lz24bp\)_start_[012]\[\][ ]=' drivers/media/video/gspca/sq930x.c
+ defsnc '[}][ ]capconfig\[4\]\[2\][ ]=' drivers/media/video/gspca/sq930x.c
+ defsnc 'static[ ]const[ ]\(__u16\|struct[ ]cmd\)[ ]spca504\(_pccam600\|A_clicksmart420\)_\(init\|open\)_data\[\]\(\[3\]\)\?[ ]=' drivers/media/video/gspca/sunplus.c
+ defsnc 'static[ ]const[ ]\(__\)\?u8[ ]qtable_\(creative_pccam\|spca504_default\)\[2\]\[64\][ ]=' drivers/media/video/gspca/sunplus.c
+ defsnc 'static[ ]const[ ]u8[ ]n4_\(om6802\|other\|tas5130a\)\[\][ ]=' drivers/media/video/gspca/t613.c
+ defsnc 'static[ ]const[ ]u8[ ]n4_lt168g\[\][ ]=' drivers/media/video/gspca/t613.c
+ defsnc 'static[ ]const[ ]u8[ ]DQT\[17\]\[130\][ ]=' drivers/media/video/gspca/topro.c
+ defsnc 'static[ ]const[ ]struct[ ]cmd[ ]tp6810_late_start\[\][ ]=' drivers/media/video/gspca/topro.c
+ defsnc '[ ]static[ ]const[ ]struct[ ]cmd[ ]sensor_init\[\][ ]=' drivers/media/video/gspca/topro.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]gamma_tb\[NGAMMA\]\[3\]\[1024\][ ]=' drivers/media/video/gspca/topro.c
+ defsnc 'static[ ]const[ ]u8[ ]eeprom_data\[\]\[3\][ ]=' drivers/media/gspca/tv8532.c
+ initc 'static[ ]const[ ]\(__\)\?u8[ ]\(mi\(0360\|13[12]0\)\|po\(1200\|3130\)\|hv7131r\|ov76[67]0\)_\(\(soc\)\?_\?[iI]nit\(Q\?V\|SX\)GA\(_\(JPG\|data\)\)\?\|rundata\)\[\]\[4\][ ]=\([ ][{][*][/][;]\)\?' drivers/media/video/gspca/vc032x.c
+ defsnc 'static[ ]const[ ]u8[ ]poxxxx_\(init\(_common\|Q\?VGA\|_end_1\|_start_3\)\|gamma\)\[\]\[4\][ ]=' drivers/media/video/gspca/vc032x.c
+ defsnc 'static[ ]const[ ]u16[ ]rca_initdata\[\]\[3\][ ]=' drivers/media/video/gspca/xirlink_cit.c
+ defsnc 'static[ ]const[ ]struct[ ]usb_action[ ]\(cs2102\|hdcs2020xx\|icm105a\(xx\)\?\|ov7630c\|mt9v111_[13]\|pb0330\([3x]x\)\?\|mi0360soc\)_Initial\(Scale\)\?\[\][ ]=' drivers/media/video/gspca/zc3xx.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]gamma_tb\[6\]\[16\][ ]=' drivers/media/video/gspca/zc3xx.c
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]hash_table_ops\[64[*]4\][ ]=' drivers/media/usb/pwc/pwc-dec23.c
+ defsnc 'static[ ]const[ ]unsigned[ ]int[ ]MulIdx\[16\]\[16\][ ]=' drivers/media/usb/pwc/pwc-dec23.c
+ defsnc 'const[ ]struct[ ]Kiara_table_entry[ ]Kiara_table\[PSZ_MAX\]\[6\]\[4\][ ]=' drivers/media/video/pwc/pwc-kiara.c
+ defsnc 'const[ ]unsigned[ ]int[ ]KiaraRomTable[ ]\[8\]\[2\]\[16\]\[8\][ ]=' drivers/media/video/pwc/pwc-kiara.c
+ defsnc 'const[ ]struct[ ]Timon_table_entry[ ]Timon_table\[PSZ_MAX\]\[PWC_FPS_MAX_TIMON\]\[4\][ ]=' drivers/media/video/pwc/pwc-timon.c
+ defsnc 'const[ ]unsigned[ ]int[ ]TimonRomTable[ ]\[16\]\[2\]\[16\]\[8\][ ]=' drivers/media/video/pwc/pwc-timon.c
+ initnc 'static[ ]const[ ]u8[ ]SN9C102_\(Y\|UV\)_QTABLE[01]\[64\][ ]=[ ][{]' drivers/media/usb/sn9c102/sn9c102_config.h
+ initnc '[ ]static[ ]\(const[ ]\)\?u8[ ]jpeg_header\[589\][ ]=[ ][{]' media/video/sn9c102/sn9c102_core.c
+ accept '[ ][ ]\?err[ ]=[ ]sn9c102_write_const_regs[(]cam\(,[ \n]\+[{]0x[0-9a-fA-F][0-9a-fA-F],[ ]0x[0-9a-fA-F][0-9a-fA-F][}]\)*[)][;]'
+ initnc 'static[ ]struct[ ]regval[ ]ov_initvals\[\][ ]=' drivers/media/usb/stkwebcam/stk-sensor.c
+ initnc 'static[ ]struct[ ]regval[ ]stk1125_initvals\[\][ ]=' drivers/media/usb/stkwebcam/stk-webcam.c
+ defsnc 'static[ ]u8[ ]dvbc_philips_tdm1316l_inittab\[\][ ]=' drivers/media/dvb/ttpci/budget-ci.c
+ defsnc '[ ]u8[ ]b\[\][ ]=' drivers/media/usb/ttusb-dec/ttusbdecfe.c
+ defsnc '[ ]static[ ]char[ ]init_values\[38\]\[3\][ ]=' drivers/media/video/usbvision/usbvision-core.c
+ defsnc 'static[ ]unsigned[ ]char[ ]header2\[\][ ]=' drivers/media/usb/zr364xx/zr364xx.c
+ defsnc '[ ]static[ ]const[ ]char[ ][*][ ]const[ ]vui_sar_idc\[\][ ]=' drivers/media/video/v4l2-ctrls.c
+ defsnc '[ ]static[ ]unsigned[ ]char[ ]static_pad\[\][ ]=' drivers/s390/crypto/zcrypt_msgtype6.c
+ defsnc 'static[ ]const[ ]unsigned[ ]int[ ]muxonechan\[\][ ]=' drivers/staging/comedi/drivers/adv_pci1710.c
+ accept '#define[ ]_MAP_0_32_ASCII_SEG7_NON_PRINTABLE[ ]\\[\n][ ]\(0,\)\+$' 'drivers/input/misc/map_to_7segment\.h\|include/linux/map_to_7segment\.h'
+ defsnc 'static[ ]yyconst[ ]\(flex_int\(16\|32\)_t\|\(\(short[ ]\)\?int\)\)[ ]yy_[^[]*\[[][0-9]*\][ ]='
+ defsnc 'static[ ]const[ ]\(yytype_u\?int\(8\|16\)\|\(unsigned[ ]\)\?\(short\([ ]int\)\?\|char\)\)[ ]yy[^[]*\[\][ ]='
+ defsnc 'static[ ]int[ ]__devinit[ ]azx_probe[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*request_firmware[^\n]*' sound/pci/hda/hda_intel.c
+ # New in 3.7:
+ blobname 'imx[/]sdma[/]sdma-imx6q-to1\.bin' arch/arm/boot/dts/imx6q.dtsi
+ accept 'AES_T[ed]:\([\n]\.word[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*[\n][@][ ]T[ed]4\[256\]\([\n]\.byte[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*\([\n][@][ ]rcon\[\]\([\n]\.word[ ]0x[0-9a-f]*\([,][ ]0x[0-9a-f]*\)*\)*\([,][ ]0\)*\)\?' arch/arm/crypto/aes-armv4.S
+ defsnc 'const[ ]u32[ ]cast5_s[1234]\[256\][ ]=' crypto/cast5_generic.c
+ defsnc 'const[ ]u32[ ]cast6_s[1234]\[256\][ ]=' crypto/cast6_generic.c
+ accept '[ ][*][ ]Once[ ]it[ ]returns[ ]successfully[,][ ]driver[ ]can[ ]use[ ]request_firmware' drivers/base/firmware_class.c
+ accept 'int[\n ]cache_firmware[(]const[ ]char[ ][*]fw_name[)][\n][{]\([\n]\+[^\n}][^\n]*\)*ret[ ]=[ ]request_firmware[(][^\n]*\([\n]\+[^\n}][^\n]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept '[ ][*][ ]If[ ]one[ ]device[ ]called[ ]request_firmware' drivers/base/firmware_class.c
+ defsnc 'static[ ]const[ ]struct[ ]mV_pos[ ]__cpuinitconst[ ]\(vrm85\|mobilevrm\)_mV\[32\][ ]=' drivers/cpufreq/longhaul.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]__cpuinitconst[ ]mV_\(vrm85\|mobilevrm\)\[32\][ ]=' drivers/cpufreq/longhaul.h
+ # Sources for these are in the corresponding .fuc files.
+ defsnc 'static[ ]u32[ ]nva3_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
+ defsnc 'static[ ]u32[ ]nvc0_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
+ defsnc 'static[ ]uint32_t[ ]nv98_pcrypt_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
+ defsnc 'uint32_t[ ]nve0_grgpc_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
+ defsnc 'uint32_t[ ]nve0_grhub_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
+ defsnc 'nv04_graph_ctx_regs\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nv04.c
+ accept '[ ]*ret[ ]=[ ]request_firmware[(]&fw[,][ ]source[,][ ]&nv_device[(]bios[)]->pdev->dev[)][;]' drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+ defsnc 'static[ ]u8[ ][*]edid_load[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*err[ ]=[ ]request_firmware[(][&]fw[,][ ]name[,][ ][&]pdev' drivers/gpu/drm/drm_edid_load.c
+ defsnc 'static[ ]const[ ]RegInitializer[ ]initData\[\][ ]__initconst[ ]=' drivers/ide/ali14xx.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_val[ ]tuner_init_fc2580\[\][ ]=' drivers/media/dvb-frontends/af9033_priv.h
+ defsnc '[ ]static[ ]const[ ]u8[ ]bw_params1\[3\]\[34\][ ]=' drivers/media/dvb-frontends/rtl2830.c
+ blobname 's5k4ecgx\.bin' drivers/media/i2c/s5k4ecgx.c
+ blobname 'v4l-coda\(dx6-imx27\|7541-imx53\)\.bin' drivers/media/platform/coda.c
+ blobname 's5p-mfc\(-v6\)\?\.fw' drivers/media/platform/s5p-mfc/s5p_mfc.c
+ defsnc 'static[ ]const[ ]struct[ ]e4000_lna_filter[ ]e400_lna_filter_lut\[\][ ]=' drivers/media/tuners/e4000_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]e4000_if_filter[ ]e4000_if_filter_lut\[\][ ]=' drivers/media/tuners/e4000_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]fc2580_reg_val[ ]fc2580_init_reg_vals\[\][ ]=' drivers/media/tuners/fc2580_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]fc2580_freq_regs[ ]fc2580_freq_regs_lut\[\][ ]=' drivers/media/tuners/fc2580_priv.h
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5110_revb_patch\[\][ ]=' drivers/mfd/wm5110-tables.c
+ defsnc 'static[ ]struct[ ]nand_ecclayout[ ]lpc32xx_nand_oob[ ]=' drivers/mtd/nand/lpc32xx_mlc.c
+ defsnc 'static[ ]struct[ ]nand_ecclayout[ ]flctl_4secc_oob_64[ ]=' drivers/mtd/nand/sh_flctl.c
+ defsnc 'static[ ]const[ ]struct[ ]atl1c_platform_patch[ ]plats\[\][ ]__devinitconst[ ]=' drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+ defsnc 'static[ ]const[ ]u32[ ]ar9565_1p0_\(\(mac\|baseband\|radio\)_core\|[Cc]ommon_\(wo_xlna_\)\?rx_gain_table\)\[\]\[2\][ ]=' drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+ defsnc 'static[ ]const[ ]u32[ ]ar9565_1p0_\(\(mac\|baseband\)_postamble\|[Mm]odes_\(low\(est\)\?\|high\)_\(ob_db\|power\)_tx_gain_table\)\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+ defsnc 'static[ ]u16[ ]r2057_rev[4578]a\?_init\[[45][245]\]\[2\][ ]=' drivers/net/wireless/b43/radio_2057.c
+ defsnc '[ ]*tbl_rf_control_override_rev7_over[01]\[\][ ]=' drivers/net/wireless/b43/tables_nphy.c
+ defsnc 'static[ ]const[ ]unsigned[ ]pci_pins\[\][ ]=' drivers/pinctrl/spear/pinctrl-spear1310.c
+ defsnc 'static[ ]int[ ]array_soc\[\]\[2\][ ]=' drivers/power/88pm860x_battery.c
+ defsnc 'static[ ]const[ ]int[ ]mc13783_sw[12]x_val\[\][ ]=' drivers/regulator/mc13783-regulator.c
+ # remoteproc uses request_firmware, but it is generic and names
+ # no blobs of its own, so we change it to maybe_request_firmware.
+ accept '[ ]ret[ ]=[ ]request_firmware_nowait[(]THIS_MODULE[,][ ]FW_ACTION_HOTPLUG[,][\n][ ]*rproc->firmware[,][ ][&]rproc->dev[,][ ]GFP_KERNEL[,][\n][ ]*rproc[,][ ]rproc_fw_config_virtio[)][;][\n][ ]if[ ][(]ret[ ]<[ ]0[)][ ][{][\n][ ][ ]dev_err[(][&]rproc->dev[,][ ]["]request_firmware_nowait[ ]err' drivers/remoteproc/remoteproc_core.c
+ # This remoteproc client does name blobs, but we discard it
+ # with undefine_macro.
+ blob 'SPROC_MODEM_NAME[ ]["]-fw\.bin["]' drivers/remoteproc/ste_modem_rproc.c
+ accept '[ ]if[ ][(]request_firmware[(]&fw_entry,[ ]fname,[ ]&ioa_cfg->pdev->dev[)][)]' drivers/scsi/ipr.c
+ blobname 'daqboard2000_firmware\.bin' drivers/staging/comedi/drivers/daqboard2000.c
+ blobname 'me2600_firmware\.bin' drivers/staging/comedi/drivers/me_daq.c
+ blobname 'ni6534a\.bin' drivers/staging/comedi/drivers/ni_pcidio.c
+ blobname 'niscrb0[12]\.bin' drivers/staging/comedi/drivers/ni_pcidio.c
+ defsnc 'static[ ]const[ ]struct[ ]SiS_TVData[ ]XGI_\(St\|Ext\)\(PAL\|NTSC\|YPbPr\(525\|750\)[ip]\)Data\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]XGI330_\(NTSC\|PAL\|HiTV\(Ext\|St[12]\|Text\)\|YPbPr\(525\|750\)[ip]\)Timing\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]XGI330_\(HiTV\|Ren\(525\|750\)p\)Group3\(Data\|Simu\|Text\)\?\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ accept 'static[ ]inline[ ]int[\n]\(maybe_\)\?reject_ihex_firmware\(_nowait\)\?[(][^{;]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*[\n]\+[}]' include/linux/firmware.h
+ defsnc '[/][*][ ]callback[ ]from[ ]request_firmware_nowait' sound/pci/hda/hda_intel.c
+ defsnc 'static[ ]int[ ]__devinit[ ]azx_probe[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*request_firmware[^\n]*' sound/pci/hda/hda_intel.c
+ defsnc 'static[ ]struct[ ]reg_default[ ]da9055_reg_defaults\[\][ ]=' sound/soc/codecs/da9055.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]sta32x_regs\[\][ ]=' sound/soc/codecs/sta32x.c
+ blobname 'wm0010\(_stage2\.bin\|\.dfw\)' sound/soc/codecs/wm0010.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5102_sysclk_reva_patch\[\][ ]=' sound/soc/codecs/wm5102.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8510_reg_defaults\[\][ ]=' sound/soc/codecs/wm8510.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8580_reg_defaults\[\][ ]=' sound/soc/codecs/wm8580.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8776_reg_defaults\[\][ ]=' sound/soc/codecs/wm8776.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8900_reg_defaults\[\][ ]=' sound/soc/codecs/wm8900.c
+ defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8960_reg_defaults\[\][ ]=' sound/soc/codecs/wm8960.c
+ accept '[ ][ ]priv->firmware[ ]=[ ]true[;]' drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+ accept '[ ][ ]*\(if[ ][(]\|[ ][ ][ ][ ]\)nvc0_graph_ctor_fw[(]priv[,][ ]["]fuc4\(09\|1a\)[cd]["][,][ ][&]priv->fuc4\(09\|1a\)[cd][)]' 'drivers/gpu/drm/nouveau/core/engine/graph/nv[ce]0\.c'
+ accept '[ ][ ]*nvc0_graph_dtor_fw[(]&priv->fuc4\(09\|1a\)[cd][)][;]' 'drivers/gpu/drm/nouveau/nv[ce]0\.c'
+ accept '[ ][ ]*nvc0_graph_init_fw[(]priv[,][ ]0x4\(09\|1a\)000[,][ ][&]priv->fuc4\(09\|1a\)c[,][ \n ]*[&]priv->fuc4\(09\|1a\)d[)][;]' 'drivers/gpu/drm/nouveau/core/engine/graph/nv[ce]0\.c'
+ blobname 'dvb-fe-xc5000c-4\.1\.30\.7\.fw' drivers/media/tuners/xc5000.c
+ accept '[ ]\.firmware[ ]=[ ]AF9015_FIRMWARE' drivers/media/usb/dvb-usb-v2/af9015.c
+ accept '[ ]\.firmware[ ]=[ ]AF9035_FIRMWARE' drivers/media/usb/dvb-usb-v2/af9035.c
+ accept '[ ]\.firmware[ ]*=[ ]AZ6007_FIRMWARE' drivers/media/usb/dvb-usb-v2/az6007.c
+ accept '[ ]\.firmware[ ]=[ ]EC168_FIRMWARE' drivers/media/usb/dvb-usb-v2/ec168.c
+ blobname 'brcm[/]brcmfmac43\(143\|242a\)\.bin' drivers/net/wireless/brcm80211/brcmfmac/usb.c
+ accept '[ ]priv->firmware[ ]=[ ]fw[;]' drivers/net/wireless/p54/p54pci.c
+ blobname 'c[bt]2\?fw-3\.1\.0\.0\.bin' drivers/scsi/bfa/bfad.c
+ blobname 'gdmuimg\.bin' drivers/staging/gdm72xx/usb_boot.c
+ blobname 'CMV4[pi]\.bin\(\.v2\)\?' drivers/usb/atm/ueagle-atm.c
+ blobname 'dvb-fe-tda10071\.fw' drivers/media/dvb/frontends/tda10071_priv.h
+ accept '[ ]st->it913x_config\.firmware[ ]=' drivers/media/usb/dvb-usb-v2/it913x.c
+ # Present in 3.6 but removed in the patch:
+ defsnc 'static[ ]const[ ]unsigned[ ]char[ ]__\(cpu\)\?initdata[ ]mV_vrm85\[32\][ ]=' arch/x86/kernel/cpu/cpufreq/longhaul.h
+ accept '[ ][ ]snprintf[(]fname[,][ ]sizeof[(]fname[)][,][ ]["]nouveau[/]%s["][,][ ]nouveau_vbios[)][;][\n][ ][ ]ret[ ]=[ ]request_firmware[(]' drivers/gpu/drm/nouveau/nouveau_bios.c
+ defsnc '\(static[ ]uint32_t\|[}]\)[ ]nv04_graph_ctx_regs[ ]\?\[\][ ]=' drivers/char/drm/nv04_graph.c
+ defsc 'uint32_t[ ]nv98_pcrypt_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/nv98_crypt.fuc.h
+ defsnc '\(uint32_t\|u32\)[ ]nva3_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/nva3_copy.fuc.h
+ defsnc '\(uint32_t\|u32\)[ ]nvc0_pcopy_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/nvc0_copy.fuc.h
+ accept '[ ]it913x_config\.firmware[ ]=[ ]' drivers/media/dvb/dvb-usb/it913x.c
+ accept '[ ]*props->firmware[ ]=[ ]fw_it913\(5_v[12]\|7\)' drivers/media/dvb/dvb-usb/it913x.c
+ defsnc '[ ]static[ ]const[ ]u8[ ]rsshash\[40\][ ]=' drivers/net/igb/igb_main.c
+ accept '[ ]hif_dev->firmware[ ]=[ ]fw[;]' drivers/net/wireless/ath/ath9k/hif_usb.c
+ accept '[ ]hif_dev->firmware[ ]=[ ]NULL[;]' drivers/net/wireless/ath/ath9k/hif_usb.c
+ defsnc 'static[ ]const[ ]unsigned[ ]\(rgmii\|smii_0_1_2\|nand_8bit\|mcif\|pci_sata\|clcd\|arm_trace\|miphy_dbg\|emi\)_pins\[\][ ]=' drivers/pinctrl/spear/pinctrl-spear1310.c
+ accept '[ ]ret[ ]=[ ]request_firmware\([(][&]firmware_p[,][ ]rproc->firmware[,][ ]dev[)]\|_nowait[(]THIS_MODULE[,][ ]FW_ACTION_HOTPLUG[,][\n][ ]*rproc->firmware[,][ ]dev[,][ ]GFP_KERNEL[,][\n][ ]*rproc[,][ ]rproc_fw_config_virtio[)]\)[;][\n][ ]if[ ][(]ret[ ]<[ ]0[)][ ][{][\n][ ][ ]dev_err[(]dev[,][ ]["]request_firmware\(_nowait\)\?[ ]failed' drivers/remoteproc/remoteproc_core.c
+ accept '[ ]if[(]request_firmware[(]&fw_entry,[ ]fname,[ ]&ioa_cfg->pdev->dev[)][)]' drivers/scsi/ipr.c
+ defsnc 'const[ ]unsigned[ ]char[ ]map_table\[\][ ]=' drivers/staging/lirc/lirc_ttusbir.c
+ defsnc 'static[ ]struct[ ]SiS_\(LCD\|LVDS\)Data[ ][ ]*XGI_\(\(\(St\|Ext\)LCD\|LVDS\)\(1024x768\|1280x1024\|1400x1050\)\|NoScaling\)Data\(_[12]\)\?\[\][ ]=' drivers/staging/xgifb/vb_table.h
+ accept '[ ]if[ ][(][/][*]KEYSPAN_PDA[*][/]request_ihex_firmware' drivers/usb/serial/keyspan_pda.c
+ defsnc 'static[ ]const[ ]u8[ ]sta32x_regs\[STA32X_REGISTER_COUNT\][ ]=' sound/soc/codecs/sta32x.c
+ defsnc 'static[ ]const[ ]u16[ ]wm8510_reg\[WM8510_CACHEREGNUM\][ ]=' sound/soc/codecs/wm8510.c
+ defsnc 'static[ ]const[ ]u16[ ]wm8900_reg_defaults\[WM8900_MAXREG\][ ]=' sound/soc/wm8900.c
+ defsnc 'static[ ]const[ ]u16[ ]wm8960_reg\[WM8960_CACHEREGNUM\][ ]=' sound/soc/codecs/wm8960.c
+ # Specific for the 3.7-to-3.6 reverse patch:
+ accept '[ ]err[ ]=[ ]request_firmware[(]&fw,[ ]patch,[ ]dev[)][;]' sound/pci/hda/hda_hwdep.c
+ defsnc '\(static[ ]const[ ]struct[ ]\(stk1160\|saa7113\)config\|[}]\)[ ]\(stk1160\|saa7113\)config\(PAL\|NTSC\)\?\[\(256\)\?\][ ]=' drivers/staging/easycap/easycap_low.c
+ accept '[ ]kernel[(]driver[)]:[ ]calls[ ]request_firmware[(]' Documentation/firmware_class/README
+ accept '[ ]kernel:[ ]request_firmware[(]' Documentation/firmware_class/README
+ accept '[ ][ ]\.firmware[ ]*=[ ]["][/][*][(]DEBLOBBED[)][*][/]["]'
+ accept '[;][/][*]@@[ ]-418,45[ ][+]446,68[ ]@@[*][/][;][\n]\([ ]*[2],\)*[\n]\(\([ ]*[1-4],\)*[\n]\)*\([ ]*[ 1][0-9],\)*[ ]*12' scripts/dtc/dtc-parser.tab.c_shipped
;;
*/patch-3.5*)
diff --git a/freed-ora/current/f18/deblob-main b/freed-ora/current/f18/deblob-main
index 63d0c9325..3a85cdc96 100755
--- a/freed-ora/current/f18/deblob-main
+++ b/freed-ora/current/f18/deblob-main
@@ -271,35 +271,35 @@ xdelta3 -e -9 -S djw -s linux-$kver.tar linux-libre-$kver-$gnu.tar linux-libre-$
echo Creating xdelta between linux-$kver.tar and linux-libre-$kver-$gnu.tar
xdelta delta -0 linux-$kver.tar linux-libre-$kver-$gnu.tar linux-libre-$kver-$gnu.xdelta || : # xdelta returns nonzero on success
+cleanup="linux-libre-$kver-$gnu.tar linux-libre-$kver-$gnu.vcdiff linux-libre-$kver-$gnu.xdelta"
+
echo Compressing binary deltas and linux-libre-$kver-$gnu.tar
rm -f linux-$kver.tar
if test -f linux-libre-$kver-$gnu.vcdiff; then
bzip2 -k9 linux-libre-$kver-$gnu.vcdiff
xz -k9 linux-libre-$kver-$gnu.vcdiff || :
lzip -k9 linux-libre-$kver-$gnu.vcdiff || :
- rm -f linux-libre-$kver-$gnu.vcdiff
fi
if test -f linux-libre-$kver-$gnu.xdelta; then
bzip2 -k9 linux-libre-$kver-$gnu.xdelta
xz -k9 linux-libre-$kver-$gnu.xdelta || :
lzip -k9 linux-libre-$kver-$gnu.xdelta || :
- rm -f linux-libre-$kver-$gnu.xdelta
fi
bzip2 -k9 linux-libre-$kver-$gnu.tar
xz -k9 linux-libre-$kver-$gnu.tar || :
lzip -k9 linux-libre-$kver-$gnu.tar || :
-cleanup=linux-libre-$kver-$gnu.tar
-
echo Done except for signing, feel free to interrupt
for f in \
linux-libre-$kver-$gnu.tar \
linux-libre-$kver-$gnu.tar.bz2 \
linux-libre-$kver-$gnu.tar.xz \
linux-libre-$kver-$gnu.tar.lz \
+ linux-libre-$kver-$gnu.vcdiff \
linux-libre-$kver-$gnu.vcdiff.bz2 \
linux-libre-$kver-$gnu.vcdiff.xz \
linux-libre-$kver-$gnu.vcdiff.lz \
+ linux-libre-$kver-$gnu.xdelta \
linux-libre-$kver-$gnu.xdelta.bz2 \
linux-libre-$kver-$gnu.xdelta.xz \
linux-libre-$kver-$gnu.xdelta.lz \
@@ -310,8 +310,7 @@ for f in \
fi
done
-rm -f linux-libre-$kver-$gnu.tar
-
+rm -f $cleanup
cleanup=
trap 'status=$?; (exit $status); exit' 0 1 2 15
diff --git a/freed-ora/current/f18/efivarfs-3.7.patch b/freed-ora/current/f18/efivarfs-3.7.patch
new file mode 100644
index 000000000..300910716
--- /dev/null
+++ b/freed-ora/current/f18/efivarfs-3.7.patch
@@ -0,0 +1,1630 @@
+From cb6f23ee9601297c3c70d0cfe3d77dfde9bd119d Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <mjg@redhat.com>
+Date: Fri, 5 Oct 2012 13:54:56 +0800
+Subject: [PATCH 01/17] efi: Add support for a UEFI variable filesystem
+
+The existing EFI variables code only supports variables of up to 1024
+bytes. This limitation existed in version 0.99 of the EFI specification,
+but was removed before any full releases. Since variables can now be
+larger than a single page, sysfs isn't the best interface for this. So,
+instead, let's add a filesystem. Variables can be read, written and
+created, with the first 4 bytes of each variable representing its UEFI
+attributes. The create() method doesn't actually commit to flash since
+zero-length variables can't exist per-spec.
+
+Updates from Jeremy Kerr <jeremy.kerr@canonical.com>.
+
+Signed-off-by: Matthew Garrett <mjg@redhat.com>
+Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 384 ++++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/efi.h | 5 +
+ 2 files changed, 383 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index d10c987..b605c48 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -80,6 +80,10 @@
+ #include <linux/slab.h>
+ #include <linux/pstore.h>
+
++#include <linux/fs.h>
++#include <linux/ramfs.h>
++#include <linux/pagemap.h>
++
+ #include <asm/uaccess.h>
+
+ #define EFIVARS_VERSION "0.08"
+@@ -91,6 +95,7 @@ MODULE_LICENSE("GPL");
+ MODULE_VERSION(EFIVARS_VERSION);
+
+ #define DUMP_NAME_LEN 52
++#define GUID_LEN 37
+
+ /*
+ * The maximum size of VariableName + Data = 1024
+@@ -108,7 +113,6 @@ struct efi_variable {
+ __u32 Attributes;
+ } __attribute__((packed));
+
+-
+ struct efivar_entry {
+ struct efivars *efivars;
+ struct efi_variable var;
+@@ -122,6 +126,9 @@ struct efivar_attribute {
+ ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
+ };
+
++static struct efivars __efivars;
++static struct efivar_operations ops;
++
+ #define PSTORE_EFI_ATTRIBUTES \
+ (EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+@@ -629,14 +636,380 @@ static struct kobj_type efivar_ktype = {
+ .default_attrs = def_attrs,
+ };
+
+-static struct pstore_info efi_pstore_info;
+-
+ static inline void
+ efivar_unregister(struct efivar_entry *var)
+ {
+ kobject_put(&var->kobj);
+ }
+
++static int efivarfs_file_open(struct inode *inode, struct file *file)
++{
++ file->private_data = inode->i_private;
++ return 0;
++}
++
++static ssize_t efivarfs_file_write(struct file *file,
++ const char __user *userbuf, size_t count, loff_t *ppos)
++{
++ struct efivar_entry *var = file->private_data;
++ struct efivars *efivars;
++ efi_status_t status;
++ void *data;
++ u32 attributes;
++ struct inode *inode = file->f_mapping->host;
++ int datasize = count - sizeof(attributes);
++
++ if (count < sizeof(attributes))
++ return -EINVAL;
++
++ data = kmalloc(datasize, GFP_KERNEL);
++
++ if (!data)
++ return -ENOMEM;
++
++ efivars = var->efivars;
++
++ if (copy_from_user(&attributes, userbuf, sizeof(attributes))) {
++ count = -EFAULT;
++ goto out;
++ }
++
++ if (attributes & ~(EFI_VARIABLE_MASK)) {
++ count = -EINVAL;
++ goto out;
++ }
++
++ if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
++ count = -EFAULT;
++ goto out;
++ }
++
++ if (validate_var(&var->var, data, datasize) == false) {
++ count = -EINVAL;
++ goto out;
++ }
++
++ status = efivars->ops->set_variable(var->var.VariableName,
++ &var->var.VendorGuid,
++ attributes, datasize,
++ data);
++
++ switch (status) {
++ case EFI_SUCCESS:
++ mutex_lock(&inode->i_mutex);
++ i_size_write(inode, count);
++ mutex_unlock(&inode->i_mutex);
++ break;
++ case EFI_INVALID_PARAMETER:
++ count = -EINVAL;
++ break;
++ case EFI_OUT_OF_RESOURCES:
++ count = -ENOSPC;
++ break;
++ case EFI_DEVICE_ERROR:
++ count = -EIO;
++ break;
++ case EFI_WRITE_PROTECTED:
++ count = -EROFS;
++ break;
++ case EFI_SECURITY_VIOLATION:
++ count = -EACCES;
++ break;
++ case EFI_NOT_FOUND:
++ count = -ENOENT;
++ break;
++ default:
++ count = -EINVAL;
++ break;
++ }
++out:
++ kfree(data);
++
++ return count;
++}
++
++static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct efivar_entry *var = file->private_data;
++ struct efivars *efivars = var->efivars;
++ efi_status_t status;
++ unsigned long datasize = 0;
++ u32 attributes;
++ void *data;
++ ssize_t size;
++
++ status = efivars->ops->get_variable(var->var.VariableName,
++ &var->var.VendorGuid,
++ &attributes, &datasize, NULL);
++
++ if (status != EFI_BUFFER_TOO_SMALL)
++ return 0;
++
++ data = kmalloc(datasize + 4, GFP_KERNEL);
++
++ if (!data)
++ return 0;
++
++ status = efivars->ops->get_variable(var->var.VariableName,
++ &var->var.VendorGuid,
++ &attributes, &datasize,
++ (data + 4));
++
++ if (status != EFI_SUCCESS)
++ return 0;
++
++ memcpy(data, &attributes, 4);
++ size = simple_read_from_buffer(userbuf, count, ppos,
++ data, datasize + 4);
++ kfree(data);
++
++ return size;
++}
++
++static void efivarfs_evict_inode(struct inode *inode)
++{
++ clear_inode(inode);
++}
++
++static const struct super_operations efivarfs_ops = {
++ .statfs = simple_statfs,
++ .drop_inode = generic_delete_inode,
++ .evict_inode = efivarfs_evict_inode,
++ .show_options = generic_show_options,
++};
++
++static struct super_block *efivarfs_sb;
++
++static const struct inode_operations efivarfs_dir_inode_operations;
++
++static const struct file_operations efivarfs_file_operations = {
++ .open = efivarfs_file_open,
++ .read = efivarfs_file_read,
++ .write = efivarfs_file_write,
++ .llseek = no_llseek,
++};
++
++static struct inode *efivarfs_get_inode(struct super_block *sb,
++ const struct inode *dir, int mode, dev_t dev)
++{
++ struct inode *inode = new_inode(sb);
++
++ if (inode) {
++ inode->i_ino = get_next_ino();
++ inode->i_uid = inode->i_gid = 0;
++ inode->i_mode = mode;
++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++ switch (mode & S_IFMT) {
++ case S_IFREG:
++ inode->i_fop = &efivarfs_file_operations;
++ break;
++ case S_IFDIR:
++ inode->i_op = &efivarfs_dir_inode_operations;
++ inode->i_fop = &simple_dir_operations;
++ inc_nlink(inode);
++ break;
++ }
++ }
++ return inode;
++}
++
++static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
++{
++ guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]);
++ guid->b[1] = hex_to_bin(str[4]) << 4 | hex_to_bin(str[5]);
++ guid->b[2] = hex_to_bin(str[2]) << 4 | hex_to_bin(str[3]);
++ guid->b[3] = hex_to_bin(str[0]) << 4 | hex_to_bin(str[1]);
++ guid->b[4] = hex_to_bin(str[11]) << 4 | hex_to_bin(str[12]);
++ guid->b[5] = hex_to_bin(str[9]) << 4 | hex_to_bin(str[10]);
++ guid->b[6] = hex_to_bin(str[16]) << 4 | hex_to_bin(str[17]);
++ guid->b[7] = hex_to_bin(str[14]) << 4 | hex_to_bin(str[15]);
++ guid->b[8] = hex_to_bin(str[19]) << 4 | hex_to_bin(str[20]);
++ guid->b[9] = hex_to_bin(str[21]) << 4 | hex_to_bin(str[22]);
++ guid->b[10] = hex_to_bin(str[24]) << 4 | hex_to_bin(str[25]);
++ guid->b[11] = hex_to_bin(str[26]) << 4 | hex_to_bin(str[27]);
++ guid->b[12] = hex_to_bin(str[28]) << 4 | hex_to_bin(str[29]);
++ guid->b[13] = hex_to_bin(str[30]) << 4 | hex_to_bin(str[31]);
++ guid->b[14] = hex_to_bin(str[32]) << 4 | hex_to_bin(str[33]);
++ guid->b[15] = hex_to_bin(str[34]) << 4 | hex_to_bin(str[35]);
++}
++
++static int efivarfs_create(struct inode *dir, struct dentry *dentry,
++ umode_t mode, bool excl)
++{
++ struct inode *inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
++ struct efivars *efivars = &__efivars;
++ struct efivar_entry *var;
++ int namelen, i = 0, err = 0;
++
++ if (dentry->d_name.len < 38)
++ return -EINVAL;
++
++ if (!inode)
++ return -ENOSPC;
++
++ var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
++
++ if (!var)
++ return -ENOMEM;
++
++ namelen = dentry->d_name.len - GUID_LEN;
++
++ efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
++ &var->var.VendorGuid);
++
++ for (i = 0; i < namelen; i++)
++ var->var.VariableName[i] = dentry->d_name.name[i];
++
++ var->var.VariableName[i] = '\0';
++
++ inode->i_private = var;
++ var->efivars = efivars;
++ var->kobj.kset = efivars->kset;
++
++ err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s",
++ dentry->d_name.name);
++ if (err)
++ goto out;
++
++ kobject_uevent(&var->kobj, KOBJ_ADD);
++ spin_lock(&efivars->lock);
++ list_add(&var->list, &efivars->list);
++ spin_unlock(&efivars->lock);
++ d_instantiate(dentry, inode);
++ dget(dentry);
++out:
++ if (err)
++ kfree(var);
++ return err;
++}
++
++static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++ struct efivar_entry *var = dentry->d_inode->i_private;
++ struct efivars *efivars = var->efivars;
++ efi_status_t status;
++
++ spin_lock(&efivars->lock);
++
++ status = efivars->ops->set_variable(var->var.VariableName,
++ &var->var.VendorGuid,
++ 0, 0, NULL);
++
++ if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) {
++ list_del(&var->list);
++ spin_unlock(&efivars->lock);
++ efivar_unregister(var);
++ drop_nlink(dir);
++ dput(dentry);
++ return 0;
++ }
++
++ spin_unlock(&efivars->lock);
++ return -EINVAL;
++};
++
++int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
++{
++ struct inode *inode = NULL;
++ struct dentry *root;
++ struct efivar_entry *entry, *n;
++ struct efivars *efivars = &__efivars;
++ int err;
++
++ efivarfs_sb = sb;
++
++ sb->s_maxbytes = MAX_LFS_FILESIZE;
++ sb->s_blocksize = PAGE_CACHE_SIZE;
++ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
++ sb->s_magic = PSTOREFS_MAGIC;
++ sb->s_op = &efivarfs_ops;
++ sb->s_time_gran = 1;
++
++ inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
++ if (!inode) {
++ err = -ENOMEM;
++ goto fail;
++ }
++ inode->i_op = &efivarfs_dir_inode_operations;
++
++ root = d_make_root(inode);
++ sb->s_root = root;
++ if (!root) {
++ err = -ENOMEM;
++ goto fail;
++ }
++
++ list_for_each_entry_safe(entry, n, &efivars->list, list) {
++ struct inode *inode;
++ struct dentry *dentry, *root = efivarfs_sb->s_root;
++ char *name;
++ unsigned long size = 0;
++ int len, i;
++
++ len = utf16_strlen(entry->var.VariableName);
++
++ /* GUID plus trailing NULL */
++ name = kmalloc(len + 38, GFP_ATOMIC);
++
++ for (i = 0; i < len; i++)
++ name[i] = entry->var.VariableName[i] & 0xFF;
++
++ name[len] = '-';
++
++ efi_guid_unparse(&entry->var.VendorGuid, name + len + 1);
++
++ name[len+GUID_LEN] = '\0';
++
++ inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
++ S_IFREG | 0644, 0);
++ dentry = d_alloc_name(root, name);
++
++ efivars->ops->get_variable(entry->var.VariableName,
++ &entry->var.VendorGuid,
++ &entry->var.Attributes,
++ &size,
++ NULL);
++
++ mutex_lock(&inode->i_mutex);
++ inode->i_private = entry;
++ i_size_write(inode, size+4);
++ mutex_unlock(&inode->i_mutex);
++ d_add(dentry, inode);
++ }
++
++ return 0;
++fail:
++ iput(inode);
++ return err;
++}
++
++static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
++ int flags, const char *dev_name, void *data)
++{
++ return mount_single(fs_type, flags, data, efivarfs_fill_super);
++}
++
++static void efivarfs_kill_sb(struct super_block *sb)
++{
++ kill_litter_super(sb);
++ efivarfs_sb = NULL;
++}
++
++static struct file_system_type efivarfs_type = {
++ .name = "efivarfs",
++ .mount = efivarfs_mount,
++ .kill_sb = efivarfs_kill_sb,
++};
++
++static const struct inode_operations efivarfs_dir_inode_operations = {
++ .lookup = simple_lookup,
++ .unlink = efivarfs_unlink,
++ .create = efivarfs_create,
++};
++
++static struct pstore_info efi_pstore_info;
++
+ #ifdef CONFIG_PSTORE
+
+ static int efi_pstore_open(struct pstore_info *psi)
+@@ -1198,6 +1571,8 @@ int register_efivars(struct efivars *efivars,
+ pstore_register(&efivars->efi_pstore_info);
+ }
+
++ register_filesystem(&efivarfs_type);
++
+ out:
+ kfree(variable_name);
+
+@@ -1205,9 +1580,6 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(register_efivars);
+
+-static struct efivars __efivars;
+-static struct efivar_operations ops;
+-
+ /*
+ * For now we register the efi subsystem with the firmware subsystem
+ * and the vars subsystem with the efi subsystem. In the future, it
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 8670eb1..b2af157 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -29,7 +29,12 @@
+ #define EFI_UNSUPPORTED ( 3 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_BUFFER_TOO_SMALL ( 5 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_NOT_READY ( 6 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_DEVICE_ERROR ( 7 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
+
+ typedef unsigned long efi_status_t;
+ typedef u8 efi_bool_t;
+--
+1.7.12.1
+
+
+From 2fc1dc88e97665c70f203f0132232ea55e8dd7eb Mon Sep 17 00:00:00 2001
+From: Jeremy Kerr <jeremy.kerr@canonical.com>
+Date: Fri, 5 Oct 2012 13:54:56 +0800
+Subject: [PATCH 02/17] efi: Handle deletions and size changes in
+ efivarfs_write_file
+
+A write to an efivarfs file will not always result in a variable of
+'count' size after the EFI SetVariable() call. We may have appended to
+the existing data (ie, with the EFI_VARIABLE_APPEND_WRITE attribute), or
+even have deleted the variable (with an authenticated variable update,
+with a zero datasize).
+
+This change re-reads the updated variable from firmware, to check for
+size changes and deletions. In the latter case, we need to drop the
+dentry.
+
+Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 49 ++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 39 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index b605c48..d7658b4 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -658,6 +658,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ u32 attributes;
+ struct inode *inode = file->f_mapping->host;
+ int datasize = count - sizeof(attributes);
++ unsigned long newdatasize;
+
+ if (count < sizeof(attributes))
+ return -EINVAL;
+@@ -696,32 +697,60 @@ static ssize_t efivarfs_file_write(struct file *file,
+
+ switch (status) {
+ case EFI_SUCCESS:
+- mutex_lock(&inode->i_mutex);
+- i_size_write(inode, count);
+- mutex_unlock(&inode->i_mutex);
+ break;
+ case EFI_INVALID_PARAMETER:
+ count = -EINVAL;
+- break;
++ goto out;
+ case EFI_OUT_OF_RESOURCES:
+ count = -ENOSPC;
+- break;
++ goto out;
+ case EFI_DEVICE_ERROR:
+ count = -EIO;
+- break;
++ goto out;
+ case EFI_WRITE_PROTECTED:
+ count = -EROFS;
+- break;
++ goto out;
+ case EFI_SECURITY_VIOLATION:
+ count = -EACCES;
+- break;
++ goto out;
+ case EFI_NOT_FOUND:
+ count = -ENOENT;
+- break;
++ goto out;
+ default:
+ count = -EINVAL;
+- break;
++ goto out;
+ }
++
++ /*
++ * Writing to the variable may have caused a change in size (which
++ * could either be an append or an overwrite), or the variable to be
++ * deleted. Perform a GetVariable() so we can tell what actually
++ * happened.
++ */
++ newdatasize = 0;
++ status = efivars->ops->get_variable(var->var.VariableName,
++ &var->var.VendorGuid,
++ NULL, &newdatasize,
++ NULL);
++
++ if (status == EFI_BUFFER_TOO_SMALL) {
++ mutex_lock(&inode->i_mutex);
++ i_size_write(inode, newdatasize + sizeof(attributes));
++ mutex_unlock(&inode->i_mutex);
++
++ } else if (status == EFI_NOT_FOUND) {
++ spin_lock(&efivars->lock);
++ list_del(&var->list);
++ spin_unlock(&efivars->lock);
++ efivar_unregister(var);
++ drop_nlink(inode);
++ dput(file->f_dentry);
++
++ } else {
++ pr_warn("efivarfs: inconsistent EFI variable implementation? "
++ "status = %lx\n", status);
++ }
++
+ out:
+ kfree(data);
+
+--
+1.7.12.1
+
+
+From c98611fc95672862950c9bc4d6a3a4c4453a3c3e Mon Sep 17 00:00:00 2001
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Fri, 5 Oct 2012 13:54:56 +0800
+Subject: [PATCH 03/17] efi: add efivars kobject to efi sysfs folder
+
+UEFI variable filesystem need a new mount point, so this patch add
+efivars kobject to efi_kobj for create a /sys/firmware/efi/efivars
+folder.
+
+Cc: Matthew Garrett <mjg@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
+Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 9 +++++++++
+ include/linux/efi.h | 1 +
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index d7658b4..6793965 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -1527,6 +1527,7 @@ void unregister_efivars(struct efivars *efivars)
+ sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
+ kfree(efivars->new_var);
+ kfree(efivars->del_var);
++ kobject_put(efivars->kobject);
+ kset_unregister(efivars->kset);
+ }
+ EXPORT_SYMBOL_GPL(unregister_efivars);
+@@ -1558,6 +1559,14 @@ int register_efivars(struct efivars *efivars,
+ goto out;
+ }
+
++ efivars->kobject = kobject_create_and_add("efivars", parent_kobj);
++ if (!efivars->kobject) {
++ pr_err("efivars: Subsystem registration failed.\n");
++ error = -ENOMEM;
++ kset_unregister(efivars->kset);
++ goto out;
++ }
++
+ /*
+ * Per EFI spec, the maximum storage allocated for both
+ * the variable name and variable data is 1024 bytes.
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index b2af157..337aefb 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -662,6 +662,7 @@ struct efivars {
+ spinlock_t lock;
+ struct list_head list;
+ struct kset *kset;
++ struct kobject *kobject;
+ struct bin_attribute *new_var, *del_var;
+ const struct efivar_operations *ops;
+ struct efivar_entry *walk_entry;
+--
+1.7.12.1
+
+
+From 8ef5f49da57087022f2031820ceb3b1c6101d76c Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Thu, 4 Oct 2012 09:57:31 +0100
+Subject: [PATCH 04/17] efivarfs: Add documentation for the EFI variable
+ filesystem
+
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ Documentation/filesystems/00-INDEX | 2 ++
+ Documentation/filesystems/efivarfs.txt | 16 ++++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100644 Documentation/filesystems/efivarfs.txt
+
+diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
+index 8c624a1..7b52ba7 100644
+--- a/Documentation/filesystems/00-INDEX
++++ b/Documentation/filesystems/00-INDEX
+@@ -38,6 +38,8 @@ dnotify_test.c
+ - example program for dnotify
+ ecryptfs.txt
+ - docs on eCryptfs: stacked cryptographic filesystem for Linux.
++efivarfs.txt
++ - info for the efivarfs filesystem.
+ exofs.txt
+ - info, usage, mount options, design about EXOFS.
+ ext2.txt
+diff --git a/Documentation/filesystems/efivarfs.txt b/Documentation/filesystems/efivarfs.txt
+new file mode 100644
+index 0000000..c477af0
+--- /dev/null
++++ b/Documentation/filesystems/efivarfs.txt
+@@ -0,0 +1,16 @@
++
++efivarfs - a (U)EFI variable filesystem
++
++The efivarfs filesystem was created to address the shortcomings of
++using entries in sysfs to maintain EFI variables. The old sysfs EFI
++variables code only supported variables of up to 1024 bytes. This
++limitation existed in version 0.99 of the EFI specification, but was
++removed before any full releases. Since variables can now be larger
++than a single page, sysfs isn't the best interface for this.
++
++Variables can be created, deleted and modified with the efivarfs
++filesystem.
++
++efivarfs is typically mounted like this,
++
++ mount -t efivarfs none /sys/firmware/efi/efivars
+--
+1.7.12.1
+
+
+From f69c39248e2f1eebf24f5ee55139602c56d15aec Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 11 Oct 2012 11:32:17 +0100
+Subject: [PATCH 05/17] efivarfs: efivarfs_file_read ensure we free data in
+ error paths
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 6793965..b7c9a32 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -766,7 +766,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ unsigned long datasize = 0;
+ u32 attributes;
+ void *data;
+- ssize_t size;
++ ssize_t size = 0;
+
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+@@ -784,13 +784,13 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ &var->var.VendorGuid,
+ &attributes, &datasize,
+ (data + 4));
+-
+ if (status != EFI_SUCCESS)
+- return 0;
++ goto out_free;
+
+ memcpy(data, &attributes, 4);
+ size = simple_read_from_buffer(userbuf, count, ppos,
+ data, datasize + 4);
++out_free:
+ kfree(data);
+
+ return size;
+--
+1.7.12.1
+
+
+From 429136e16c7c43bbebb8b8030203161a2d3fc3ce Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 11 Oct 2012 11:32:18 +0100
+Subject: [PATCH 06/17] efivarfs: efivarfs_create() ensure we drop our
+ reference on inode on error
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index b7c9a32..6e5f367 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -866,7 +866,7 @@ static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
+ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ umode_t mode, bool excl)
+ {
+- struct inode *inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
++ struct inode *inode;
+ struct efivars *efivars = &__efivars;
+ struct efivar_entry *var;
+ int namelen, i = 0, err = 0;
+@@ -874,13 +874,15 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ if (dentry->d_name.len < 38)
+ return -EINVAL;
+
++ inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
+ if (!inode)
+ return -ENOSPC;
+
+ var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+-
+- if (!var)
+- return -ENOMEM;
++ if (!var) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+ namelen = dentry->d_name.len - GUID_LEN;
+
+@@ -908,8 +910,10 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ out:
+- if (err)
++ if (err) {
+ kfree(var);
++ iput(inode);
++ }
+ return err;
+ }
+
+--
+1.7.12.1
+
+
+From 1a19268e8a4bae43c1feb3f71ee468c6bc70aca6 Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 11 Oct 2012 11:32:19 +0100
+Subject: [PATCH 07/17] efivarfs: efivarfs_fill_super() fix inode reference
+ counts
+
+When d_make_root() fails it will automatically drop the reference
+on the root inode. We should not be doing so as well.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 6e5f367..adfc486 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -948,7 +948,6 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ struct dentry *root;
+ struct efivar_entry *entry, *n;
+ struct efivars *efivars = &__efivars;
+- int err;
+
+ efivarfs_sb = sb;
+
+@@ -960,18 +959,14 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ sb->s_time_gran = 1;
+
+ inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
+- if (!inode) {
+- err = -ENOMEM;
+- goto fail;
+- }
++ if (!inode)
++ return -ENOMEM;
+ inode->i_op = &efivarfs_dir_inode_operations;
+
+ root = d_make_root(inode);
+ sb->s_root = root;
+- if (!root) {
+- err = -ENOMEM;
+- goto fail;
+- }
++ if (!root)
++ return -ENOMEM;
+
+ list_for_each_entry_safe(entry, n, &efivars->list, list) {
+ struct inode *inode;
+@@ -1012,9 +1007,6 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ }
+
+ return 0;
+-fail:
+- iput(inode);
+- return err;
+ }
+
+ static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
+--
+1.7.12.1
+
+
+From f0d90a4024493aed6fc77ce5cd3b93f278fed9c0 Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 11 Oct 2012 11:32:20 +0100
+Subject: [PATCH 08/17] efivarfs: efivarfs_fill_super() ensure we free our
+ temporary name
+
+d_alloc_name() copies the passed name to new storage, once complete we
+no longer need our name.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index adfc486..36b3dd6 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -992,6 +992,8 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
+ S_IFREG | 0644, 0);
+ dentry = d_alloc_name(root, name);
++ /* copied by the above to local storage in the dentry. */
++ kfree(name);
+
+ efivars->ops->get_variable(entry->var.VariableName,
+ &entry->var.VendorGuid,
+--
+1.7.12.1
+
+
+From c4cf244c318218153200d0011d8ef0ebcf3146ea Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 11 Oct 2012 11:32:21 +0100
+Subject: [PATCH 09/17] efivarfs: efivarfs_fill_super() ensure we clean up
+ correctly on error
+
+Ensure we free both the name and inode on error when building the
+individual variables.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 36b3dd6..216086d 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -948,6 +948,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ struct dentry *root;
+ struct efivar_entry *entry, *n;
+ struct efivars *efivars = &__efivars;
++ char *name;
+
+ efivarfs_sb = sb;
+
+@@ -969,16 +970,18 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ return -ENOMEM;
+
+ list_for_each_entry_safe(entry, n, &efivars->list, list) {
+- struct inode *inode;
+ struct dentry *dentry, *root = efivarfs_sb->s_root;
+- char *name;
+ unsigned long size = 0;
+ int len, i;
+
++ inode = NULL;
++
+ len = utf16_strlen(entry->var.VariableName);
+
+ /* GUID plus trailing NULL */
+ name = kmalloc(len + 38, GFP_ATOMIC);
++ if (!name)
++ goto fail;
+
+ for (i = 0; i < len; i++)
+ name[i] = entry->var.VariableName[i] & 0xFF;
+@@ -991,7 +994,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+
+ inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
+ S_IFREG | 0644, 0);
++ if (!inode)
++ goto fail_name;
++
+ dentry = d_alloc_name(root, name);
++ if (!dentry)
++ goto fail_inode;
++
+ /* copied by the above to local storage in the dentry. */
+ kfree(name);
+
+@@ -1009,6 +1018,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ }
+
+ return 0;
++
++fail_inode:
++ iput(inode);
++fail_name:
++ kfree(name);
++fail:
++ return -ENOMEM;
+ }
+
+ static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
+--
+1.7.12.1
+
+
+From d3b7165568bcb50e4526c3dadda59e43f6681bc0 Mon Sep 17 00:00:00 2001
+From: Jeremy Kerr <jeremy.kerr@canonical.com>
+Date: Thu, 11 Oct 2012 21:19:11 +0800
+Subject: [PATCH 10/17] efivarfs: Implement exclusive access for
+ {get,set}_variable
+
+Currently, efivarfs does not enforce exclusion over the get_variable and
+set_variable operations. Section 7.1 of UEFI requires us to only allow a
+single processor to enter {get,set}_variable services at once.
+
+This change acquires the efivars->lock over calls to these operations
+from the efivarfs paths.
+
+Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 68 +++++++++++++++++++++++++++++-----------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 216086d..d478c56 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -690,35 +690,45 @@ static ssize_t efivarfs_file_write(struct file *file,
+ goto out;
+ }
+
++ /*
++ * The lock here protects the get_variable call, the conditional
++ * set_variable call, and removal of the variable from the efivars
++ * list (in the case of an authenticated delete).
++ */
++ spin_lock(&efivars->lock);
++
+ status = efivars->ops->set_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ attributes, datasize,
+ data);
+
+- switch (status) {
+- case EFI_SUCCESS:
+- break;
+- case EFI_INVALID_PARAMETER:
+- count = -EINVAL;
+- goto out;
+- case EFI_OUT_OF_RESOURCES:
+- count = -ENOSPC;
+- goto out;
+- case EFI_DEVICE_ERROR:
+- count = -EIO;
+- goto out;
+- case EFI_WRITE_PROTECTED:
+- count = -EROFS;
+- goto out;
+- case EFI_SECURITY_VIOLATION:
+- count = -EACCES;
+- goto out;
+- case EFI_NOT_FOUND:
+- count = -ENOENT;
+- goto out;
+- default:
+- count = -EINVAL;
+- goto out;
++ if (status != EFI_SUCCESS) {
++ spin_unlock(&efivars->lock);
++ kfree(data);
++
++ switch (status) {
++ case EFI_INVALID_PARAMETER:
++ count = -EINVAL;
++ break;
++ case EFI_OUT_OF_RESOURCES:
++ count = -ENOSPC;
++ break;
++ case EFI_DEVICE_ERROR:
++ count = -EIO;
++ break;
++ case EFI_WRITE_PROTECTED:
++ count = -EROFS;
++ break;
++ case EFI_SECURITY_VIOLATION:
++ count = -EACCES;
++ break;
++ case EFI_NOT_FOUND:
++ count = -ENOENT;
++ break;
++ default:
++ count = -EINVAL;
++ }
++ return count;
+ }
+
+ /*
+@@ -734,12 +744,12 @@ static ssize_t efivarfs_file_write(struct file *file,
+ NULL);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
++ spin_unlock(&efivars->lock);
+ mutex_lock(&inode->i_mutex);
+ i_size_write(inode, newdatasize + sizeof(attributes));
+ mutex_unlock(&inode->i_mutex);
+
+ } else if (status == EFI_NOT_FOUND) {
+- spin_lock(&efivars->lock);
+ list_del(&var->list);
+ spin_unlock(&efivars->lock);
+ efivar_unregister(var);
+@@ -747,6 +757,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ dput(file->f_dentry);
+
+ } else {
++ spin_unlock(&efivars->lock);
+ pr_warn("efivarfs: inconsistent EFI variable implementation? "
+ "status = %lx\n", status);
+ }
+@@ -768,9 +779,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ void *data;
+ ssize_t size = 0;
+
++ spin_lock(&efivars->lock);
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ &attributes, &datasize, NULL);
++ spin_unlock(&efivars->lock);
+
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return 0;
+@@ -780,10 +793,13 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ if (!data)
+ return 0;
+
++ spin_lock(&efivars->lock);
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ &attributes, &datasize,
+ (data + 4));
++ spin_unlock(&efivars->lock);
++
+ if (status != EFI_SUCCESS)
+ goto out_free;
+
+@@ -1004,11 +1020,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ /* copied by the above to local storage in the dentry. */
+ kfree(name);
+
++ spin_lock(&efivars->lock);
+ efivars->ops->get_variable(entry->var.VariableName,
+ &entry->var.VendorGuid,
+ &entry->var.Attributes,
+ &size,
+ NULL);
++ spin_unlock(&efivars->lock);
+
+ mutex_lock(&inode->i_mutex);
+ inode->i_private = entry;
+--
+1.7.12.1
+
+
+From 90a462e9cf439a1987e0f9434d1f615addcc1970 Mon Sep 17 00:00:00 2001
+From: Jeremy Kerr <jeremy.kerr@canonical.com>
+Date: Fri, 19 Oct 2012 15:16:45 +0800
+Subject: [PATCH 11/17] efi: Clarify GUID length calculations
+
+At present, the handling of GUIDs in efivar file names isn't consistent.
+We use GUID_LEN in some places, and 38 in others (GUID_LEN plus
+separator), and implicitly use the presence of the trailing NUL.
+
+This change removes the trailing NUL from GUID_LEN, so that we're
+explicitly adding it when required. We also replace magic numbers
+with GUID_LEN, and clarify the comments where appropriate.
+
+We also fix the allocation size in efivar_create_sysfs_entry, where
+we're allocating one byte too much, due to counting the trailing NUL
+twice - once when calculating short_name_size, and once in the kzalloc.
+
+Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 33 +++++++++++++++++++++++++--------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index d478c56..a93e401 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -95,7 +95,12 @@ MODULE_LICENSE("GPL");
+ MODULE_VERSION(EFIVARS_VERSION);
+
+ #define DUMP_NAME_LEN 52
+-#define GUID_LEN 37
++
++/*
++ * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
++ * not including trailing NUL
++ */
++#define GUID_LEN 36
+
+ /*
+ * The maximum size of VariableName + Data = 1024
+@@ -887,7 +892,11 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ struct efivar_entry *var;
+ int namelen, i = 0, err = 0;
+
+- if (dentry->d_name.len < 38)
++ /*
++ * We need a GUID, plus at least one letter for the variable name,
++ * plus the '-' separator
++ */
++ if (dentry->d_name.len < GUID_LEN + 2)
+ return -EINVAL;
+
+ inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
+@@ -900,7 +909,8 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ goto out;
+ }
+
+- namelen = dentry->d_name.len - GUID_LEN;
++ /* length of the variable name itself: remove GUID and separator */
++ namelen = dentry->d_name.len - GUID_LEN - 1;
+
+ efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
+ &var->var.VendorGuid);
+@@ -994,8 +1004,8 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+
+ len = utf16_strlen(entry->var.VariableName);
+
+- /* GUID plus trailing NULL */
+- name = kmalloc(len + 38, GFP_ATOMIC);
++ /* name, plus '-', plus GUID, plus NUL*/
++ name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC);
+ if (!name)
+ goto fail;
+
+@@ -1006,7 +1016,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+
+ efi_guid_unparse(&entry->var.VendorGuid, name + len + 1);
+
+- name[len+GUID_LEN] = '\0';
++ name[len+GUID_LEN+1] = '\0';
+
+ inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
+ S_IFREG | 0644, 0);
+@@ -1435,11 +1445,18 @@ efivar_create_sysfs_entry(struct efivars *efivars,
+ efi_char16_t *variable_name,
+ efi_guid_t *vendor_guid)
+ {
+- int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
++ int i, short_name_size;
+ char *short_name;
+ struct efivar_entry *new_efivar;
+
+- short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
++ /*
++ * Length of the variable bytes in ASCII, plus the '-' separator,
++ * plus the GUID, plus trailing NUL
++ */
++ short_name_size = variable_name_size / sizeof(efi_char16_t)
++ + 1 + GUID_LEN + 1;
++
++ short_name = kzalloc(short_name_size, GFP_KERNEL);
+ new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+
+ if (!short_name || !new_efivar) {
+--
+1.7.12.1
+
+
+From ecbf90823d85ebb41e68e6be01f476862d184825 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Tue, 16 Oct 2012 15:58:07 +0100
+Subject: [PATCH 12/17] efivarfs: Return an error if we fail to read a
+ variable
+
+Instead of always returning 0 in efivarfs_file_read(), even when we
+fail to successfully read the variable, convert the EFI status to
+something meaningful and return that to the caller. This way the user
+will have some hint as to why the read failed.
+
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 62 +++++++++++++++++++++++++++-------------------
+ 1 file changed, 36 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index a93e401..277e426 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -653,6 +653,36 @@ static int efivarfs_file_open(struct inode *inode, struct file *file)
+ return 0;
+ }
+
++static int efi_status_to_err(efi_status_t status)
++{
++ int err;
++
++ switch (status) {
++ case EFI_INVALID_PARAMETER:
++ err = -EINVAL;
++ break;
++ case EFI_OUT_OF_RESOURCES:
++ err = -ENOSPC;
++ break;
++ case EFI_DEVICE_ERROR:
++ err = -EIO;
++ break;
++ case EFI_WRITE_PROTECTED:
++ err = -EROFS;
++ break;
++ case EFI_SECURITY_VIOLATION:
++ err = -EACCES;
++ break;
++ case EFI_NOT_FOUND:
++ err = -ENOENT;
++ break;
++ default:
++ err = -EINVAL;
++ }
++
++ return err;
++}
++
+ static ssize_t efivarfs_file_write(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *ppos)
+ {
+@@ -711,29 +741,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ spin_unlock(&efivars->lock);
+ kfree(data);
+
+- switch (status) {
+- case EFI_INVALID_PARAMETER:
+- count = -EINVAL;
+- break;
+- case EFI_OUT_OF_RESOURCES:
+- count = -ENOSPC;
+- break;
+- case EFI_DEVICE_ERROR:
+- count = -EIO;
+- break;
+- case EFI_WRITE_PROTECTED:
+- count = -EROFS;
+- break;
+- case EFI_SECURITY_VIOLATION:
+- count = -EACCES;
+- break;
+- case EFI_NOT_FOUND:
+- count = -ENOENT;
+- break;
+- default:
+- count = -EINVAL;
+- }
+- return count;
++ return efi_status_to_err(status);
+ }
+
+ /*
+@@ -791,12 +799,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ spin_unlock(&efivars->lock);
+
+ if (status != EFI_BUFFER_TOO_SMALL)
+- return 0;
++ return efi_status_to_err(status);
+
+ data = kmalloc(datasize + 4, GFP_KERNEL);
+
+ if (!data)
+- return 0;
++ return -ENOMEM;
+
+ spin_lock(&efivars->lock);
+ status = efivars->ops->get_variable(var->var.VariableName,
+@@ -805,8 +813,10 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ (data + 4));
+ spin_unlock(&efivars->lock);
+
+- if (status != EFI_SUCCESS)
++ if (status != EFI_SUCCESS) {
++ size = efi_status_to_err(status);
+ goto out_free;
++ }
+
+ memcpy(data, &attributes, 4);
+ size = simple_read_from_buffer(userbuf, count, ppos,
+--
+1.7.12.1
+
+
+From 39210330739b943856ff21b29b4a0804f4e8349f Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Mon, 22 Oct 2012 15:23:29 +0100
+Subject: [PATCH 13/17] efivarfs: Replace magic number with sizeof(attributes)
+
+Seeing "+ 4" littered throughout the functions gets a bit
+confusing. Use "sizeof(attributes)" which clearly explains what
+quantity we're adding.
+
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 277e426..2c04434 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -801,7 +801,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return efi_status_to_err(status);
+
+- data = kmalloc(datasize + 4, GFP_KERNEL);
++ data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);
+
+ if (!data)
+ return -ENOMEM;
+@@ -810,7 +810,7 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ &attributes, &datasize,
+- (data + 4));
++ (data + sizeof(attributes)));
+ spin_unlock(&efivars->lock);
+
+ if (status != EFI_SUCCESS) {
+@@ -818,9 +818,9 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ goto out_free;
+ }
+
+- memcpy(data, &attributes, 4);
++ memcpy(data, &attributes, sizeof(attributes));
+ size = simple_read_from_buffer(userbuf, count, ppos,
+- data, datasize + 4);
++ data, datasize + sizeof(attributes));
+ out_free:
+ kfree(data);
+
+--
+1.7.12.1
+
+
+From 5555f0af6294b3675a95a06da23101150644936d Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Mon, 22 Oct 2012 15:51:45 +0100
+Subject: [PATCH 14/17] efivarfs: Add unique magic number
+
+Using pstore's superblock magic number is no doubt going to cause
+problems in the future. Give efivarfs its own magic number.
+
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 2 +-
+ include/uapi/linux/magic.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 2c04434..3b0cf9a 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -991,7 +991,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+- sb->s_magic = PSTOREFS_MAGIC;
++ sb->s_magic = EFIVARFS_MAGIC;
+ sb->s_op = &efivarfs_ops;
+ sb->s_time_gran = 1;
+
+diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
+index e15192c..12f68c7 100644
+--- a/include/uapi/linux/magic.h
++++ b/include/uapi/linux/magic.h
+@@ -27,6 +27,7 @@
+ #define ISOFS_SUPER_MAGIC 0x9660
+ #define JFFS2_SUPER_MAGIC 0x72b6
+ #define PSTOREFS_MAGIC 0x6165676C
++#define EFIVARFS_MAGIC 0xde5e81e4
+
+ #define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */
+ #define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */
+--
+1.7.12.1
+
+
+From a42845c67f2386b164d0c5d8220838d7faf5a409 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Tue, 23 Oct 2012 12:35:43 +0100
+Subject: [PATCH 15/17] efivarfs: Make 'datasize' unsigned long
+
+There's no reason to declare 'datasize' as an int, since the majority
+of the functions it's passed to expect an unsigned long anyway. Plus,
+this way we avoid any sign problems during arithmetic.
+
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 3b0cf9a..6a858d1 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -692,7 +692,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ void *data;
+ u32 attributes;
+ struct inode *inode = file->f_mapping->host;
+- int datasize = count - sizeof(attributes);
++ unsigned long datasize = count - sizeof(attributes);
+ unsigned long newdatasize;
+
+ if (count < sizeof(attributes))
+--
+1.7.12.1
+
+
+From a268bdf6d7ce623ea4bdfcf39aa52ed3fbfdfd65 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Tue, 23 Oct 2012 12:41:03 +0100
+Subject: [PATCH 16/17] efivarfs: Return a consistent error when
+ efivarfs_get_inode() fails
+
+Instead of returning -ENOSPC if efivarfs_get_inode() fails we should
+be returning -ENOMEM, since running out of memory is the only reason
+it can fail. Furthermore, that's the error value used everywhere else
+in this file. It's also less likely to confuse users that hit this
+error case.
+
+Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 6a858d1..58cec62 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -911,7 +911,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+
+ inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
+ if (!inode)
+- return -ENOSPC;
++ return -ENOMEM;
+
+ var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+ if (!var) {
+--
+1.7.12.1
+
+
+From 9c3136c987175b179c0aa725d76cda156894f918 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Fri, 26 Oct 2012 12:18:53 +0100
+Subject: [PATCH 17/17] efivarfs: Fix return value of efivarfs_file_write()
+
+We're stuffing a variable of type size_t (unsigned) into a ssize_t
+(signed) which, even though both types should be the same number of
+bits, it's just asking for sign issues to be introduced.
+
+Cc: Jeremy Kerr <jeremy.kerr@canonical.com>
+Reported-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+---
+ drivers/firmware/efivars.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 58cec62..9ac9340 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -694,6 +694,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ struct inode *inode = file->f_mapping->host;
+ unsigned long datasize = count - sizeof(attributes);
+ unsigned long newdatasize;
++ ssize_t bytes = 0;
+
+ if (count < sizeof(attributes))
+ return -EINVAL;
+@@ -706,22 +707,22 @@ static ssize_t efivarfs_file_write(struct file *file,
+ efivars = var->efivars;
+
+ if (copy_from_user(&attributes, userbuf, sizeof(attributes))) {
+- count = -EFAULT;
++ bytes = -EFAULT;
+ goto out;
+ }
+
+ if (attributes & ~(EFI_VARIABLE_MASK)) {
+- count = -EINVAL;
++ bytes = -EINVAL;
+ goto out;
+ }
+
+ if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
+- count = -EFAULT;
++ bytes = -EFAULT;
+ goto out;
+ }
+
+ if (validate_var(&var->var, data, datasize) == false) {
+- count = -EINVAL;
++ bytes = -EINVAL;
+ goto out;
+ }
+
+@@ -744,6 +745,8 @@ static ssize_t efivarfs_file_write(struct file *file,
+ return efi_status_to_err(status);
+ }
+
++ bytes = count;
++
+ /*
+ * Writing to the variable may have caused a change in size (which
+ * could either be an append or an overwrite), or the variable to be
+@@ -778,7 +781,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ out:
+ kfree(data);
+
+- return count;
++ return bytes;
+ }
+
+ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+--
+1.7.12.1
+
diff --git a/freed-ora/current/f18/exec-do-not-leave-bprm-interp-on-stack.patch b/freed-ora/current/f18/exec-do-not-leave-bprm-interp-on-stack.patch
index 2a4b2dd28..5198824ed 100644
--- a/freed-ora/current/f18/exec-do-not-leave-bprm-interp-on-stack.patch
+++ b/freed-ora/current/f18/exec-do-not-leave-bprm-interp-on-stack.patch
@@ -1,6 +1,6 @@
-From 20ae2081584450e552735a3df968ce5b5946a607 Mon Sep 17 00:00:00 2001
+From 6752ab4cb863fc63ed85f1ca78a42235c09fad83 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
-Date: Mon, 26 Nov 2012 08:56:37 -0500
+Date: Mon, 26 Nov 2012 09:07:50 -0500
Subject: [PATCH 1/2] exec: do not leave bprm->interp on stack
If a series of scripts are executed, each triggering module loading via
@@ -73,10 +73,10 @@ index d3b8c1f..df49d48 100644
/*
* OK, now restart the process with the interpreter's dentry.
diff --git a/fs/exec.c b/fs/exec.c
-index fab2c6d..59896ae 100644
+index 0039055..c6e6de4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
-@@ -1202,9 +1202,24 @@ void free_bprm(struct linux_binprm *bprm)
+@@ -1175,9 +1175,24 @@ void free_bprm(struct linux_binprm *bprm)
mutex_unlock(&current->signal->cred_guard_mutex);
abort_creds(bprm->cred);
}
@@ -102,10 +102,10 @@ index fab2c6d..59896ae 100644
* install the new credentials for this executable
*/
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
-index 366422b..eb53e15 100644
+index cfcc6bf..de0628e 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
-@@ -128,6 +128,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
+@@ -114,6 +114,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
unsigned long stack_top,
int executable_stack);
extern int bprm_mm_init(struct linux_binprm *bprm);
diff --git a/freed-ora/current/f18/exec-use-eloop-for-max-recursion-depth.patch b/freed-ora/current/f18/exec-use-eloop-for-max-recursion-depth.patch
index cbaff2f7a..a3c48884f 100644
--- a/freed-ora/current/f18/exec-use-eloop-for-max-recursion-depth.patch
+++ b/freed-ora/current/f18/exec-use-eloop-for-max-recursion-depth.patch
@@ -1,4 +1,4 @@
-From 4ae8186cd77835b45f1b35edb4ce70309287bfc3 Mon Sep 17 00:00:00 2001
+From ba1b23d05259e31d30a78017cdfbc010dcb08aa6 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Mon, 26 Nov 2012 09:02:11 -0500
Subject: [PATCH 2/2] exec: use -ELOOP for max recursion depth
@@ -98,10 +98,10 @@ index df49d48..8ae4be1 100644
fput(bprm->file);
bprm->file = NULL;
diff --git a/fs/exec.c b/fs/exec.c
-index 59896ae..541cc51 100644
+index c6e6de4..85c1f9e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
-@@ -1398,6 +1398,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1371,6 +1371,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
struct linux_binfmt *fmt;
pid_t old_pid, old_vpid;
@@ -112,7 +112,7 @@ index 59896ae..541cc51 100644
retval = security_bprm_check(bprm);
if (retval)
return retval;
-@@ -1422,12 +1426,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1395,12 +1399,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
if (!try_module_get(fmt->module))
continue;
read_unlock(&binfmt_lock);
@@ -127,10 +127,10 @@ index 59896ae..541cc51 100644
if (retval >= 0) {
if (depth == 0) {
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
-index eb53e15..5bab59b 100644
+index de0628e..54135f6 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
-@@ -68,8 +68,6 @@ struct linux_binprm {
+@@ -54,8 +54,6 @@ struct linux_binprm {
#define BINPRM_FLAGS_EXECFD_BIT 1
#define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT)
@@ -138,7 +138,7 @@ index eb53e15..5bab59b 100644
-
/* Function parameter for binfmt->coredump */
struct coredump_params {
- long signr;
+ siginfo_t *siginfo;
--
1.8.0
diff --git a/freed-ora/current/f18/fs-lock-splice_read-and-splice_write-functions.patch b/freed-ora/current/f18/fs-lock-splice_read-and-splice_write-functions.patch
deleted file mode 100644
index 938cbd9f5..000000000
--- a/freed-ora/current/f18/fs-lock-splice_read-and-splice_write-functions.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-Lock splice_read and splice_write functions
-
-commit 1a25b1c4ce189e3926f2981f3302352a930086db
-Author: Mikulas Patocka <mpatocka@redhat.com>
-Date: Mon Oct 15 17:20:17 2012 -0400
-
- Lock splice_read and splice_write functions
-
- Functions generic_file_splice_read and generic_file_splice_write access
- the pagecache directly. For block devices these functions must be locked
- so that block size is not changed while they are in progress.
-
- This patch is an additional fix for commit b87570f5d349 ("Fix a crash
- when block device is read and block size is changed at the same time")
- that locked aio_read, aio_write and mmap against block size change.
-
- Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
- Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-
-Index: linux-3.6.x86_64/fs/block_dev.c
-===================================================================
---- linux-3.6.x86_64.orig/fs/block_dev.c 2012-11-16 17:12:57.352936580 -0500
-+++ linux-3.6.x86_64/fs/block_dev.c 2012-11-16 17:13:11.908887989 -0500
-@@ -1662,6 +1662,39 @@
- return ret;
- }
-
-+static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
-+ struct pipe_inode_info *pipe, size_t len,
-+ unsigned int flags)
-+{
-+ ssize_t ret;
-+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
-+
-+ percpu_down_read(&bdev->bd_block_size_semaphore);
-+
-+ ret = generic_file_splice_read(file, ppos, pipe, len, flags);
-+
-+ percpu_up_read(&bdev->bd_block_size_semaphore);
-+
-+ return ret;
-+}
-+
-+static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
-+ struct file *file, loff_t *ppos, size_t len,
-+ unsigned int flags)
-+{
-+ ssize_t ret;
-+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
-+
-+ percpu_down_read(&bdev->bd_block_size_semaphore);
-+
-+ ret = generic_file_splice_write(pipe, file, ppos, len, flags);
-+
-+ percpu_up_read(&bdev->bd_block_size_semaphore);
-+
-+ return ret;
-+}
-+
-+
- /*
- * Try to release a page associated with block device when the system
- * is under memory pressure.
-@@ -1700,8 +1733,8 @@
- #ifdef CONFIG_COMPAT
- .compat_ioctl = compat_blkdev_ioctl,
- #endif
-- .splice_read = generic_file_splice_read,
-- .splice_write = generic_file_splice_write,
-+ .splice_read = blkdev_splice_read,
-+ .splice_write = blkdev_splice_write,
- };
-
- int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
diff --git a/freed-ora/current/f18/handle-efi-roms.patch b/freed-ora/current/f18/handle-efi-roms.patch
index 3002b1f89..bc080542b 100644
--- a/freed-ora/current/f18/handle-efi-roms.patch
+++ b/freed-ora/current/f18/handle-efi-roms.patch
@@ -131,62 +131,6 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c .
/*
* See if we have Graphics Output Protocol
*/
-@@ -276,8 +392,9 @@
- nr_gops = size / sizeof(void *);
- for (i = 0; i < nr_gops; i++) {
- struct efi_graphics_output_mode_info *info;
-- efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
-- void *pciio;
-+ efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
-+ bool conout_found = false;
-+ void *dummy;
- void *h = gop_handle[i];
-
- status = efi_call_phys3(sys_table->boottime->handle_protocol,
-@@ -285,19 +402,21 @@
- if (status != EFI_SUCCESS)
- continue;
-
-- efi_call_phys3(sys_table->boottime->handle_protocol,
-- h, &pciio_proto, &pciio);
-+ status = efi_call_phys3(sys_table->boottime->handle_protocol,
-+ h, &conout_proto, &dummy);
-+
-+ if (status == EFI_SUCCESS)
-+ conout_found = true;
-
- status = efi_call_phys4(gop->query_mode, gop,
- gop->mode->mode, &size, &info);
-- if (status == EFI_SUCCESS && (!first_gop || pciio)) {
-+ if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
- /*
-- * Apple provide GOPs that are not backed by
-- * real hardware (they're used to handle
-- * multiple displays). The workaround is to
-- * search for a GOP implementing the PCIIO
-- * protocol, and if one isn't found, to just
-- * fallback to the first GOP.
-+ * Systems that use the UEFI Console Splitter may
-+ * provide multiple GOP devices, not all of which are
-+ * backed by real hardware. The workaround is to search
-+ * for a GOP implementing the ConOut protocol, and if
-+ * one isn't found, to just fall back to the first GOP.
- */
- width = info->horizontal_resolution;
- height = info->vertical_resolution;
-@@ -308,10 +427,10 @@
- pixels_per_scan_line = info->pixels_per_scan_line;
-
- /*
-- * Once we've found a GOP supporting PCIIO,
-+ * Once we've found a GOP supporting ConOut,
- * don't bother looking any further.
- */
-- if (pciio)
-+ if (conout_found)
- break;
-
- first_gop = gop;
@@ -1052,6 +1171,8 @@
setup_graphics(boot_params);
@@ -196,20 +140,6 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.c .
status = efi_call_phys3(sys_table->boottime->allocate_pool,
EFI_LOADER_DATA, sizeof(*gdt),
(void **)&gdt);
-diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h
---- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h 2012-07-21 16:58:29.000000000 -0400
-+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/boot/compressed/eboot.h 2012-08-22 15:25:40.530244882 -0400
-@@ -14,6 +14,10 @@
- #define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
- #define EFI_READ_CHUNK_SIZE (1024 * 1024)
-
-+#define EFI_CONSOLE_OUT_DEVICE_GUID \
-+ EFI_GUID( 0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \
-+ 0x3f, 0xc1, 0x4d )
-+
- #define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0
- #define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1
- #define PIXEL_BIT_MASK 2
diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h
--- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:26:32.485522068 -0400
+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/arch/x86/include/asm/bootparam.h 2012-08-22 15:25:40.530244882 -0400
@@ -332,25 +262,19 @@ diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/pci.c ../kernel-3.5.fc
diff -ur linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c
--- linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-07-21 16:58:29.000000000 -0400
+++ ../kernel-3.5.fc18.bak/linux-3.6.0-0.rc2.git2.1.fc18.x86_64/drivers/pci/rom.c 2012-08-22 15:25:40.531244893 -0400
-@@ -118,11 +118,17 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
- void __iomem *rom;
-
- /*
+@@ -126,6 +126,12 @@
+ /* primary video rom always starts here */
+ start = (loff_t)0xC0000;
+ *size = 0x20000; /* cover C000:0 through E000:0 */
++ /*
+ * Some devices may provide ROMs via a source other than the BAR
+ */
-+ if (pdev->rom && pdev->romlen) {
++ } else if (pdev->rom && pdev->romlen) {
+ *size = pdev->romlen;
+ return phys_to_virt(pdev->rom);
-+ /*
- * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
- * memory map if the VGA enable bit of the Bridge Control register is
- * set for embedded VGA.
- */
-- if (res->flags & IORESOURCE_ROM_SHADOW) {
-+ } else if (res->flags & IORESOURCE_ROM_SHADOW) {
- /* primary video rom always starts here */
- start = (loff_t)0xC0000;
- *size = 0x20000; /* cover C000:0 through E000:0 */
+ } else {
+ if (res->flags &
+ (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
@@ -219,7 +225,8 @@
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
return;
diff --git a/freed-ora/current/f18/kernel.spec b/freed-ora/current/f18/kernel.spec
index bd7df2941..3e0678fc8 100644
--- a/freed-ora/current/f18/kernel.spec
+++ b/freed-ora/current/f18/kernel.spec
@@ -62,13 +62,13 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 3
+%global baserelease 2
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
# on top of -- for example, 3.1-rc7-git1 starts with a 3.0 base,
# which yields a base_sublevel of 0.
-%define base_sublevel 6
+%define base_sublevel 7
# librev starts empty, then 1, etc, as the linux-libre tarball
# changes. This is only used to determine which tarball to use.
@@ -78,9 +78,9 @@ Summary: The Linux kernel
%define basegnu -gnu%{?librev}
# To be inserted between "patch" and "-2.6.".
-%define stablelibre -3.6%{?stablegnux}
-#define rcrevlibre -3.6%{?rcrevgnux}
-#define gitrevlibre -3.6%{?gitrevgnux}
+#define stablelibre -3.7%{?stablegnux}
+#define rcrevlibre -3.7%{?rcrevgnux}
+#define gitrevlibre -3.7%{?gitrevgnux}
%if 0%{?stablelibre:1}
%define stablegnu -gnu%{?librev}
@@ -112,7 +112,7 @@ Summary: The Linux kernel
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
-%define stable_update 11
+%define stable_update 1
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@@ -468,6 +468,14 @@ Summary: The Linux kernel
%endif
%endif
+# Should make listnewconfig fail if there's config options
+# printed out?
+%if %{nopatches}%{using_upstream_branch}
+%define listnewconfig_fail 0
+%else
+%define listnewconfig_fail 1
+%endif
+
# To temporarily exclude an architecture from being built, add it to
# %%nobuildarches. Do _NOT_ use the ExclusiveArch: line, because if we
# don't build kernel-headers then the new build system will no longer let
@@ -582,7 +590,7 @@ ExclusiveOS: Linux
BuildRequires: module-init-tools, patch >= 2.5.4, bash >= 2.03, sh-utils, tar
BuildRequires: bzip2, xz, findutils, gzip, m4, perl, make >= 3.78, diffutils, gawk
BuildRequires: gcc >= 3.4.2, binutils >= 2.12, redhat-rpm-config, hmaccalc
-BuildRequires: net-tools
+BuildRequires: net-tools, hostname
BuildRequires: xmlto, asciidoc
%if %{with_sparse}
BuildRequires: sparse >= 0.4.1
@@ -720,10 +728,6 @@ Patch100: taint-vbox.patch
Patch110: vmbugon-warnon.patch
-Patch150: team-net-next-20120808.patch
-Patch151: team-net-next-update-20120927.patch
-Patch152: team-net-next-20121205.patch
-
Patch390: linux-2.6-defaults-acpi-video.patch
Patch391: linux-2.6-acpi-video-dos.patch
Patch394: linux-2.6-acpi-debug-infinite-loop.patch
@@ -745,12 +749,11 @@ Patch700: linux-2.6-e1000-ich9-montevina.patch
Patch800: linux-2.6-crash-driver.patch
# crypto/
-Patch900: modsign-upstream-3.7.patch
Patch901: modsign-post-KS-jwb.patch
# secure boot
Patch1000: secure-boot-20121212.patch
-Patch1001: efivarfs-3.6.patch
+Patch1001: efivarfs-3.7.patch
# Improve PCI support on UEFI
Patch1100: handle-efi-roms.patch
@@ -799,7 +802,6 @@ Patch20001: 0002-x86-EFI-Calculate-the-EFI-framebuffer-size-instead-o.patch
# ARM
Patch21000: arm-read_current_timer.patch
Patch21001: arm-fix-omapdrm.patch
-Patch21002: arm-fix_radio_shark.patch
Patch21003: arm-alignment-faults.patch
# OMAP
@@ -809,7 +811,6 @@ Patch21005: arm-tegra-usb-no-reset-linux33.patch
Patch21006: arm-tegra-sdhci-module-fix.patch
# ARM highbank patches
-Patch21010: arm-highbank-sata-fix.patch
# ARM exynos4
Patch21020: arm-smdk310-regulator-fix.patch
@@ -823,33 +824,9 @@ Patch22000: weird-root-dentry-name-debug.patch
#selinux ptrace child permissions
Patch22001: selinux-apply-different-permission-to-ptrace-child.patch
-#rhbz 869904 869909 CVE-2012-4508
-Patch22080: 0001-ext4-ext4_inode_info-diet.patch
-Patch22081: 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
-Patch22082: 0003-ext4-fix-unwritten-counter-leakage.patch
-Patch22083: 0004-ext4-completed_io-locking-cleanup.patch
-Patch22084: 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
-Patch22085: 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
-Patch22086: 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
-Patch22087: 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
-Patch22088: 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
-Patch22089: 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
-Patch22090: 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
-Patch22091: 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
-
-Patch22100: uprobes-upstream-backport.patch
-
#rhbz 871078
Patch22112: USB-report-submission-of-active-URBs.patch
-#rhbz 869341
-Patch22113: smp_irq_move_cleanup_interrupt.patch
-
-#rhbz 812129
-Patch22120: block-fix-a-crash-when-block-device-is.patch
-Patch22121: blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
-Patch22122: fs-lock-splice_read-and-splice_write-functions.patch
-
#rhbz 874791
Patch22125: Bluetooth-Add-support-for-BCM20702A0.patch
@@ -860,9 +837,6 @@ Patch21226: vt-Drop-K_OFF-for-VC_MUTE.patch
Patch21228: exec-do-not-leave-bprm-interp-on-stack.patch
Patch21229: exec-use-eloop-for-max-recursion-depth.patch
-#rhbz 869629
-Patch21230: SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
-
#rhbz 851278
Patch21231: 8139cp-revert-set-ring-address-before-enabling-receiver.patch
Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch
@@ -1505,23 +1479,17 @@ ApplyPatch taint-vbox.patch
ApplyPatch vmbugon-warnon.patch
-ApplyPatch team-net-next-20120808.patch
-ApplyPatch team-net-next-update-20120927.patch
-ApplyPatch team-net-next-20121205.patch
-
# Architecture patches
# x86(-64)
#
# ARM
#
-ApplyPatch arm-read_current_timer.patch
-ApplyPatch arm-fix-omapdrm.patch
-ApplyPatch arm-fix_radio_shark.patch
+#ApplyPatch arm-read_current_timer.patch
+#ApplyPatch arm-fix-omapdrm.patch
ApplyPatch arm-tegra-nvec-kconfig.patch
ApplyPatch arm-tegra-usb-no-reset-linux33.patch
ApplyPatch arm-tegra-sdhci-module-fix.patch
-ApplyPatch arm-highbank-sata-fix.patch
ApplyPatch arm-alignment-faults.patch
ApplyPatch arm-smdk310-regulator-fix.patch
ApplyPatch arm-origen-regulator-fix.patch
@@ -1592,11 +1560,10 @@ ApplyPatch linux-2.6-crash-driver.patch
ApplyPatch linux-2.6-e1000-ich9-montevina.patch
# crypto/
-ApplyPatch modsign-upstream-3.7.patch
ApplyPatch modsign-post-KS-jwb.patch
# secure boot
-ApplyPatch efivarfs-3.6.patch
+ApplyPatch efivarfs-3.7.patch
ApplyPatch secure-boot-20121212.patch
# Improved PCI support for UEFI
@@ -1639,8 +1606,8 @@ ApplyPatch efi-dont-map-boot-services-on-32bit.patch
ApplyPatch lis3-improve-handling-of-null-rate.patch
-ApplyPatch 0001-efifb-Skip-DMI-checks-if-the-bootloader-knows-what-i.patch
-ApplyPatch 0002-x86-EFI-Calculate-the-EFI-framebuffer-size-instead-o.patch
+#ApplyPatch 0001-efifb-Skip-DMI-checks-if-the-bootloader-knows-what-i.patch
+#ApplyPatch 0002-x86-EFI-Calculate-the-EFI-framebuffer-size-instead-o.patch
#rhbz 754518
ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
@@ -1650,33 +1617,9 @@ ApplyPatch weird-root-dentry-name-debug.patch
#selinux ptrace child permissions
ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch
-#rhbz 869904 869909 CVE-2012-4508
-ApplyPatch 0001-ext4-ext4_inode_info-diet.patch
-ApplyPatch 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch
-ApplyPatch 0003-ext4-fix-unwritten-counter-leakage.patch
-ApplyPatch 0004-ext4-completed_io-locking-cleanup.patch
-ApplyPatch 0005-ext4-serialize-dio-nonlocked-reads-with-defrag-worke.patch
-ApplyPatch 0006-ext4-serialize-unlocked-dio-reads-with-truncate.patch
-ApplyPatch 0007-ext4-endless-truncate-due-to-nonlocked-dio-readers.patch
-ApplyPatch 0008-ext4-serialize-truncate-with-owerwrite-DIO-workers.patch
-ApplyPatch 0009-ext4-punch_hole-should-wait-for-DIO-writers.patch
-ApplyPatch 0010-ext4-fix-ext_remove_space-for-punch_hole-case.patch
-ApplyPatch 0011-ext4-fix-ext4_flush_completed_IO-wait-semantics.patch
-ApplyPatch 0012-ext4-serialize-fallocate-with-ext4_convert_unwritten.patch
-
-ApplyPatch uprobes-upstream-backport.patch
-
#rhbz 871078
ApplyPatch USB-report-submission-of-active-URBs.patch
-#rhbz 869341
-ApplyPatch smp_irq_move_cleanup_interrupt.patch
-
-#rhbz 812129
-ApplyPatch block-fix-a-crash-when-block-device-is.patch
-ApplyPatch blockdev-turn-a-rw-semaphore-into-a-percpu-rw-sem.patch
-ApplyPatch fs-lock-splice_read-and-splice_write-functions.patch
-
#rhbz 874791
ApplyPatch Bluetooth-Add-support-for-BCM20702A0.patch
@@ -1687,9 +1630,6 @@ ApplyPatch vt-Drop-K_OFF-for-VC_MUTE.patch
ApplyPatch exec-do-not-leave-bprm-interp-on-stack.patch
ApplyPatch exec-use-eloop-for-max-recursion-depth.patch
-#rhbz 869629
-ApplyPatch SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
-
#rhbz 851278
ApplyPatch 8139cp-revert-set-ring-address-before-enabling-receiver.patch -R
ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch
@@ -1729,17 +1669,23 @@ done
rm -f kernel-%{version}-*debug.config
%endif
-# run oldconfig over the config files (except when noarch)
-if [ "%{_target_cpu}" != "noarch" ]; then
- for i in kernel-*-%{_target_cpu}*.config
- do
- mv $i .config
- Arch=`head -1 .config | cut -b 3-`
- make ARCH=$Arch oldnoconfig
- echo "# $Arch" > configs/$i
- cat .config >> configs/$i
- done
-fi
+# now run oldconfig over all the config files
+for i in *.config
+do
+ mv $i .config
+ Arch=`head -1 .config | cut -b 3-`
+ make ARCH=$Arch listnewconfig | grep -E '^CONFIG_' >.newoptions || true
+%if %{listnewconfig_fail}
+ if [ -s .newoptions ]; then
+ cat .newoptions
+ exit 1
+ fi
+%endif
+ rm -f .newoptions
+ make ARCH=$Arch oldnoconfig
+ echo "# $Arch" > configs/$i
+ cat .config >> configs/$i
+done
# end of kernel config
%endif
@@ -2459,6 +2405,7 @@ fi
%dir %{_libexecdir}/perf-core
%{_libexecdir}/perf-core/*
%{_mandir}/man[1-8]/perf*
+%{_sysconfdir}/bash_completion.d/perf
%doc linux-%{KVERREL}/tools/perf/Documentation/examples.txt
%files -n python-perf-libre
@@ -2578,6 +2525,20 @@ fi
# ||----w |
# || ||
%changelog
+* Fri Jan 4 2013 Alexandre Oliva <lxoliva@fsfla.org> -libre
+- GNU Linux-libre 3.7.1
+
+* Thu Jan 03 2013 Josh Boyer <jwboyer@redhat.com> - 3.7.1-2
+- Fixup secure boot patchset for 3.7 rebase
+- Package bash completion script for perf
+
+* Thu Jan 03 2013 Dave Jones <davej@redhat.com>
+- Rebase to 3.7.1
+
+* Wed Jan 02 2013 Josh Boyer <jwboyer@redhat.com>
+- Fix autofs issue in 3.6 (rhbz 874372)
+- BR the hostname package (rhbz 886113)
+
* Mon Dec 17 2012 Alexandre Oliva <lxoliva@fsfla.org> -libre
- GNU Linux-libre 3.6.11-gnu
@@ -2799,6 +2760,7 @@ fi
- Linux 3.6.0
- Disable debugging options.
+<<<<<<< HEAD
* Fri Sep 28 2012 Josh Boyer <jwboyer@redhat.com> - 3.6.0-0.rc7.git3.1
- Linux v3.6-rc7-103-g6672d90
@@ -4866,6 +4828,8 @@ fi
* Mon May 30 2011 Kyle McMartin <kyle@redhat.com>
- Trimmed changelog, see fedpkg git for earlier history.
+=======
+>>>>>>> 1c6f1e3
###
# The following Emacs magic makes C-c C-e use UTC dates.
# Local Variables:
diff --git a/freed-ora/current/f18/linux-2.6-serial-460800.patch b/freed-ora/current/f18/linux-2.6-serial-460800.patch
index 979b248d5..0e68378e7 100644
--- a/freed-ora/current/f18/linux-2.6-serial-460800.patch
+++ b/freed-ora/current/f18/linux-2.6-serial-460800.patch
@@ -28,14 +28,14 @@ index 2209620..659c1bb 100644
quot = uart_get_divisor(port, baud);
@@ -2240,7 +2251,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
- struct uart_8250_port *up = (struct uart_8250_port *)port;
+ container_of(port, struct uart_8250_port, port);
unsigned char cval, fcr = 0;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, max_baud;
+ int fifo_bug = 0;
switch (termios->c_cflag & CSIZE) {
- case CS5:
@@ -2272,9 +2283,10 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* Ask the core to calculate the divisor for us.
diff --git a/freed-ora/current/f18/linux-libre-3.6-gnu.tar.xz.sign b/freed-ora/current/f18/linux-libre-3.6-gnu.tar.xz.sign
deleted file mode 100644
index dbdf5e6d0..000000000
--- a/freed-ora/current/f18/linux-libre-3.6-gnu.tar.xz.sign
+++ /dev/null
@@ -1,7 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.18 (GNU/Linux)
-
-iEYEABECAAYFAlBo9TQACgkQvLfPh359R6c5GACgkzXtyZfBtqJqbVGOvIoSvtHh
-RQEAn3ZxxgMk1RVT75ywYpP3gbz7QZjV
-=VOuw
------END PGP SIGNATURE-----
diff --git a/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz b/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz
deleted file mode 100644
index 4f3f73070..000000000
--- a/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz
+++ /dev/null
Binary files differ
diff --git a/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz.sign b/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz.sign
deleted file mode 100644
index 295579272..000000000
--- a/freed-ora/current/f18/linux-libre-3.6-gnu.xdelta.xz.sign
+++ /dev/null
@@ -1,7 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.18 (GNU/Linux)
-
-iEYEABECAAYFAlBo9TUACgkQvLfPh359R6cCLACfcy8Pd21g94qq7+3hYtLaowT4
-J7wAoJDOcfwOJHwN8SkxfmkEonO8V0Bm
-=A8ay
------END PGP SIGNATURE-----
diff --git a/freed-ora/current/f18/linux-libre-3.7-gnu.tar.xz.sign b/freed-ora/current/f18/linux-libre-3.7-gnu.tar.xz.sign
new file mode 100644
index 000000000..c49487a65
--- /dev/null
+++ b/freed-ora/current/f18/linux-libre-3.7-gnu.tar.xz.sign
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.0.18 (GNU/Linux)
+
+iEYEABECAAYFAlDGubkACgkQvLfPh359R6dyvQCgn1oX7jcr2tiBiabLjHDwuHD/
+bfYAoKmSnj+Ks8sWyLmQVNRlEc/jtdY1
+=Fa9B
+-----END PGP SIGNATURE-----
diff --git a/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz b/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz
new file mode 100644
index 000000000..f1929c01b
--- /dev/null
+++ b/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz
Binary files differ
diff --git a/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz.sign b/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz.sign
new file mode 100644
index 000000000..123cb9ef3
--- /dev/null
+++ b/freed-ora/current/f18/linux-libre-3.7-gnu.xdelta.xz.sign
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.0.18 (GNU/Linux)
+
+iEYEABECAAYFAlDGuboACgkQvLfPh359R6d/4ACePuNek3206kBQyeD1OBcLkNIy
+kCIAnRlb9I2DMFdBXFh+/bj0CaX1NpPR
+=ppPM
+-----END PGP SIGNATURE-----
diff --git a/freed-ora/current/f18/lis3-improve-handling-of-null-rate.patch b/freed-ora/current/f18/lis3-improve-handling-of-null-rate.patch
index 98512564a..30ed26d80 100644
--- a/freed-ora/current/f18/lis3-improve-handling-of-null-rate.patch
+++ b/freed-ora/current/f18/lis3-improve-handling-of-null-rate.patch
@@ -28,9 +28,9 @@ index 35c67e0..42dce2a 100644
-static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
+/* LIS3DC: 0 = power off, above 9 = undefined */
+static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000, -1, -1, -1, -1, -1, -1};
+ static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
/* ODR is Output Data Rate */
- static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
@@ -202,12 +203,11 @@ static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
return lis3->odrs[(ctrl >> shift)];
}
diff --git a/freed-ora/current/f18/modsign-upstream-3.7.patch b/freed-ora/current/f18/modsign-upstream-3.7.patch
deleted file mode 100644
index 33fd0592f..000000000
--- a/freed-ora/current/f18/modsign-upstream-3.7.patch
+++ /dev/null
@@ -1,10997 +0,0 @@
-From 9d501208ff48eb3ecc0d1ac8d897c38e99d18161 Mon Sep 17 00:00:00 2001
-From: Rusty Russell <rusty@rustcorp.com.au>
-Date: Wed, 26 Sep 2012 10:09:40 +0100
-Subject: [PATCH 01/37] module: signature checking hook
-
-We do a very simple search for a particular string appended to the module
-(which is cache-hot and about to be SHA'd anyway). There's both a config
-option and a boot parameter which control whether we accept or fail with
-unsigned modules and modules that are signed with an unknown key.
-
-If module signing is enabled, the kernel will be tainted if a module is
-loaded that is unsigned or has a signature for which we don't have the
-key.
-
-(Useful feedback and tweaks by David Howells <dhowells@redhat.com>)
-
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- Documentation/kernel-parameters.txt | 6 +++
- include/linux/module.h | 8 ++++
- init/Kconfig | 14 ++++++
- kernel/Makefile | 1 +
- kernel/module-internal.h | 13 ++++++
- kernel/module.c | 93 ++++++++++++++++++++++++++++++++++++-
- kernel/module_signing.c | 23 +++++++++
- 7 files changed, 157 insertions(+), 1 deletion(-)
- create mode 100644 kernel/module-internal.h
- create mode 100644 kernel/module_signing.c
-
-diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index ad7e2e5..9b2b8d3 100644
---- a/Documentation/kernel-parameters.txt
-+++ b/Documentation/kernel-parameters.txt
-@@ -1582,6 +1582,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
- log everything. Information is printed at KERN_DEBUG
- so loglevel=8 may also need to be specified.
-
-+ module.sig_enforce
-+ [KNL] When CONFIG_MODULE_SIG is set, this means that
-+ modules without (valid) signatures will fail to load.
-+ Note that if CONFIG_MODULE_SIG_ENFORCE is set, that
-+ is always true, so this option does nothing.
-+
- mousedev.tap_time=
- [MOUSE] Maximum time between finger touching and
- leaving touchpad surface for touch to be considered
-diff --git a/include/linux/module.h b/include/linux/module.h
-index fbcafe2..7760c6d 100644
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -21,6 +21,9 @@
- #include <linux/percpu.h>
- #include <asm/module.h>
-
-+/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
-+#define MODULE_SIG_STRING "~Module signature appended~\n"
-+
- /* Not Yet Implemented */
- #define MODULE_SUPPORTED_DEVICE(name)
-
-@@ -260,6 +263,11 @@ struct module
- const unsigned long *unused_gpl_crcs;
- #endif
-
-+#ifdef CONFIG_MODULE_SIG
-+ /* Signature was verified. */
-+ bool sig_ok;
-+#endif
-+
- /* symbols that will be GPL-only in the near future. */
- const struct kernel_symbol *gpl_future_syms;
- const unsigned long *gpl_future_crcs;
-diff --git a/init/Kconfig b/init/Kconfig
-index af6c7f8..7452e19 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1585,6 +1585,20 @@ config MODULE_SRCVERSION_ALL
- the version). With this option, such a "srcversion" field
- will be created for all modules. If unsure, say N.
-
-+config MODULE_SIG
-+ bool "Module signature verification"
-+ depends on MODULES
-+ help
-+ Check modules for valid signatures upon load: the signature
-+ is simply appended to the module. For more information see
-+ Documentation/module-signing.txt.
-+
-+config MODULE_SIG_FORCE
-+ bool "Require modules to be validly signed"
-+ depends on MODULE_SIG
-+ help
-+ Reject unsigned modules or signed modules for which we don't have a
-+ key. Without this, such modules will simply taint the kernel.
- endif # MODULES
-
- config INIT_ALL_POSSIBLE
-diff --git a/kernel/Makefile b/kernel/Makefile
-index c0cc67a..08ba8a6 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -55,6 +55,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
- obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
- obj-$(CONFIG_UID16) += uid16.o
- obj-$(CONFIG_MODULES) += module.o
-+obj-$(CONFIG_MODULE_SIG) += module_signing.o
- obj-$(CONFIG_KALLSYMS) += kallsyms.o
- obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
- obj-$(CONFIG_KEXEC) += kexec.o
-diff --git a/kernel/module-internal.h b/kernel/module-internal.h
-new file mode 100644
-index 0000000..033c17f
---- /dev/null
-+++ b/kernel/module-internal.h
-@@ -0,0 +1,13 @@
-+/* Module internals
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+extern int mod_verify_sig(const void *mod, unsigned long modlen,
-+ const void *sig, unsigned long siglen);
-diff --git a/kernel/module.c b/kernel/module.c
-index 9ad9ee9..7efb415 100644
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -58,6 +58,7 @@
- #include <linux/jump_label.h>
- #include <linux/pfn.h>
- #include <linux/bsearch.h>
-+#include "module-internal.h"
-
- #define CREATE_TRACE_POINTS
- #include <trace/events/module.h>
-@@ -102,6 +103,43 @@ static LIST_HEAD(modules);
- struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
- #endif /* CONFIG_KGDB_KDB */
-
-+#ifdef CONFIG_MODULE_SIG
-+#ifdef CONFIG_MODULE_SIG_FORCE
-+static bool sig_enforce = true;
-+#else
-+static bool sig_enforce = false;
-+
-+static int param_set_bool_enable_only(const char *val,
-+ const struct kernel_param *kp)
-+{
-+ int err;
-+ bool test;
-+ struct kernel_param dummy_kp = *kp;
-+
-+ dummy_kp.arg = &test;
-+
-+ err = param_set_bool(val, &dummy_kp);
-+ if (err)
-+ return err;
-+
-+ /* Don't let them unset it once it's set! */
-+ if (!test && sig_enforce)
-+ return -EROFS;
-+
-+ if (test)
-+ sig_enforce = true;
-+ return 0;
-+}
-+
-+static const struct kernel_param_ops param_ops_bool_enable_only = {
-+ .set = param_set_bool_enable_only,
-+ .get = param_get_bool,
-+};
-+#define param_check_bool_enable_only param_check_bool
-+
-+module_param(sig_enforce, bool_enable_only, 0644);
-+#endif /* !CONFIG_MODULE_SIG_FORCE */
-+#endif /* CONFIG_MODULE_SIG */
-
- /* Block module loading/unloading? */
- int modules_disabled = 0;
-@@ -136,6 +174,7 @@ struct load_info {
- unsigned long symoffs, stroffs;
- struct _ddebug *debug;
- unsigned int num_debug;
-+ bool sig_ok;
- struct {
- unsigned int sym, str, mod, vers, info, pcpu;
- } index;
-@@ -2399,7 +2438,49 @@ static inline void kmemleak_load_module(const struct module *mod,
- }
- #endif
-
--/* Sets info->hdr and info->len. */
-+#ifdef CONFIG_MODULE_SIG
-+static int module_sig_check(struct load_info *info,
-+ const void *mod, unsigned long *len)
-+{
-+ int err = -ENOKEY;
-+ const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-+ const void *p = mod, *end = mod + *len;
-+
-+ /* Poor man's memmem. */
-+ while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) {
-+ if (p + markerlen > end)
-+ break;
-+
-+ if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) {
-+ const void *sig = p + markerlen;
-+ /* Truncate module up to signature. */
-+ *len = p - mod;
-+ err = mod_verify_sig(mod, *len, sig, end - sig);
-+ break;
-+ }
-+ p++;
-+ }
-+
-+ if (!err) {
-+ info->sig_ok = true;
-+ return 0;
-+ }
-+
-+ /* Not having a signature is only an error if we're strict. */
-+ if (err == -ENOKEY && !sig_enforce)
-+ err = 0;
-+
-+ return err;
-+}
-+#else /* !CONFIG_MODULE_SIG */
-+static int module_sig_check(struct load_info *info,
-+ void *mod, unsigned long *len)
-+{
-+ return 0;
-+}
-+#endif /* !CONFIG_MODULE_SIG */
-+
-+/* Sets info->hdr, info->len and info->sig_ok. */
- static int copy_and_check(struct load_info *info,
- const void __user *umod, unsigned long len,
- const char __user *uargs)
-@@ -2419,6 +2500,10 @@ static int copy_and_check(struct load_info *info,
- goto free_hdr;
- }
-
-+ err = module_sig_check(info, hdr, &len);
-+ if (err)
-+ goto free_hdr;
-+
- /* Sanity checks against insmoding binaries or wrong arch,
- weird elf version */
- if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
-@@ -2890,6 +2975,12 @@ static struct module *load_module(void __user *umod,
- goto free_copy;
- }
-
-+#ifdef CONFIG_MODULE_SIG
-+ mod->sig_ok = info.sig_ok;
-+ if (!mod->sig_ok)
-+ add_taint_module(mod, TAINT_FORCED_MODULE);
-+#endif
-+
- /* Now module is in final location, initialize linked lists, etc. */
- err = module_unload_init(mod);
- if (err)
-diff --git a/kernel/module_signing.c b/kernel/module_signing.c
-new file mode 100644
-index 0000000..499728a
---- /dev/null
-+++ b/kernel/module_signing.c
-@@ -0,0 +1,23 @@
-+/* Module signature checker
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/err.h>
-+#include "module-internal.h"
-+
-+/*
-+ * Verify the signature on a module.
-+ */
-+int mod_verify_sig(const void *mod, unsigned long modlen,
-+ const void *sig, unsigned long siglen)
-+{
-+ return -ENOKEY;
-+}
---
-1.7.12.1
-
-
-From 82400c211d81ea36338fb8266b5c41710101a013 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 13 Sep 2012 13:06:29 +0100
-Subject: [PATCH 02/37] KEYS: Add payload preparsing opportunity prior to key
- instantiate or update
-
-Give the key type the opportunity to preparse the payload prior to the
-instantiation and update routines being called. This is done with the
-provision of two new key type operations:
-
- int (*preparse)(struct key_preparsed_payload *prep);
- void (*free_preparse)(struct key_preparsed_payload *prep);
-
-If the first operation is present, then it is called before key creation (in
-the add/update case) or before the key semaphore is taken (in the update and
-instantiate cases). The second operation is called to clean up if the first
-was called.
-
-preparse() is given the opportunity to fill in the following structure:
-
- struct key_preparsed_payload {
- char *description;
- void *type_data[2];
- void *payload;
- const void *data;
- size_t datalen;
- size_t quotalen;
- };
-
-Before the preparser is called, the first three fields will have been cleared,
-the payload pointer and size will be stored in data and datalen and the default
-quota size from the key_type struct will be stored into quotalen.
-
-The preparser may parse the payload in any way it likes and may store data in
-the type_data[] and payload fields for use by the instantiate() and update()
-ops.
-
-The preparser may also propose a description for the key by attaching it as a
-string to the description field. This can be used by passing a NULL or ""
-description to the add_key() system call or the key_create_or_update()
-function. This cannot work with request_key() as that required the description
-to tell the upcall about the key to be created.
-
-This, for example permits keys that store PGP public keys to generate their own
-name from the user ID and public key fingerprint in the key.
-
-The instantiate() and update() operations are then modified to look like this:
-
- int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
- int (*update)(struct key *key, struct key_preparsed_payload *prep);
-
-and the new payload data is passed in *prep, whether or not it was preparsed.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- Documentation/security/keys.txt | 50 +++++++++++++-
- fs/cifs/cifs_spnego.c | 6 +-
- fs/cifs/cifsacl.c | 8 +--
- include/keys/user-type.h | 6 +-
- include/linux/key-type.h | 35 +++++++++-
- net/ceph/crypto.c | 9 +--
- net/dns_resolver/dns_key.c | 6 +-
- net/rxrpc/ar-key.c | 40 +++++------
- security/keys/encrypted-keys/encrypted.c | 16 +++--
- security/keys/key.c | 114 ++++++++++++++++++++++---------
- security/keys/keyctl.c | 18 +++--
- security/keys/keyring.c | 6 +-
- security/keys/request_key_auth.c | 8 +--
- security/keys/trusted.c | 16 +++--
- security/keys/user_defined.c | 14 ++--
- 15 files changed, 250 insertions(+), 102 deletions(-)
-
-diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
-index aa0dbd7..7d9ca92 100644
---- a/Documentation/security/keys.txt
-+++ b/Documentation/security/keys.txt
-@@ -412,6 +412,10 @@ The main syscalls are:
- to the keyring. In this case, an error will be generated if the process
- does not have permission to write to the keyring.
-
-+ If the key type supports it, if the description is NULL or an empty
-+ string, the key type will try and generate a description from the content
-+ of the payload.
-+
- The payload is optional, and the pointer can be NULL if not required by
- the type. The payload is plen in size, and plen can be zero for an empty
- payload.
-@@ -1114,12 +1118,53 @@ The structure has a number of fields, some of which are mandatory:
- it should return 0.
-
-
-- (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
-+ (*) int (*preparse)(struct key_preparsed_payload *prep);
-+
-+ This optional method permits the key type to attempt to parse payload
-+ before a key is created (add key) or the key semaphore is taken (update or
-+ instantiate key). The structure pointed to by prep looks like:
-+
-+ struct key_preparsed_payload {
-+ char *description;
-+ void *type_data[2];
-+ void *payload;
-+ const void *data;
-+ size_t datalen;
-+ size_t quotalen;
-+ };
-+
-+ Before calling the method, the caller will fill in data and datalen with
-+ the payload blob parameters; quotalen will be filled in with the default
-+ quota size from the key type and the rest will be cleared.
-+
-+ If a description can be proposed from the payload contents, that should be
-+ attached as a string to the description field. This will be used for the
-+ key description if the caller of add_key() passes NULL or "".
-+
-+ The method can attach anything it likes to type_data[] and payload. These
-+ are merely passed along to the instantiate() or update() operations.
-+
-+ The method should return 0 if success ful or a negative error code
-+ otherwise.
-+
-+
-+ (*) void (*free_preparse)(struct key_preparsed_payload *prep);
-+
-+ This method is only required if the preparse() method is provided,
-+ otherwise it is unused. It cleans up anything attached to the
-+ description, type_data and payload fields of the key_preparsed_payload
-+ struct as filled in by the preparse() method.
-+
-+
-+ (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
-
- This method is called to attach a payload to a key during construction.
- The payload attached need not bear any relation to the data passed to this
- function.
-
-+ The prep->data and prep->datalen fields will define the original payload
-+ blob. If preparse() was supplied then other fields may be filled in also.
-+
- If the amount of data attached to the key differs from the size in
- keytype->def_datalen, then key_payload_reserve() should be called.
-
-@@ -1135,6 +1180,9 @@ The structure has a number of fields, some of which are mandatory:
- If this type of key can be updated, then this method should be provided.
- It is called to update a key's payload from the blob of data provided.
-
-+ The prep->data and prep->datalen fields will define the original payload
-+ blob. If preparse() was supplied then other fields may be filled in also.
-+
- key_payload_reserve() should be called if the data length might change
- before any changes are actually made. Note that if this succeeds, the type
- is committed to changing the key because it's already been altered, so all
-diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
-index e622863..086f381 100644
---- a/fs/cifs/cifs_spnego.c
-+++ b/fs/cifs/cifs_spnego.c
-@@ -31,18 +31,18 @@
-
- /* create a new cifs key */
- static int
--cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen)
-+cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- char *payload;
- int ret;
-
- ret = -ENOMEM;
-- payload = kmalloc(datalen, GFP_KERNEL);
-+ payload = kmalloc(prep->datalen, GFP_KERNEL);
- if (!payload)
- goto error;
-
- /* attach the data */
-- memcpy(payload, data, datalen);
-+ memcpy(payload, prep->data, prep->datalen);
- key->payload.data = payload;
- ret = 0;
-
-diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
-index 05f4dc2..f3c60e2 100644
---- a/fs/cifs/cifsacl.c
-+++ b/fs/cifs/cifsacl.c
-@@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = {
- };
-
- static int
--cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen)
-+cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- char *payload;
-
-- payload = kmalloc(datalen, GFP_KERNEL);
-+ payload = kmalloc(prep->datalen, GFP_KERNEL);
- if (!payload)
- return -ENOMEM;
-
-- memcpy(payload, data, datalen);
-+ memcpy(payload, prep->data, prep->datalen);
- key->payload.data = payload;
-- key->datalen = datalen;
-+ key->datalen = prep->datalen;
- return 0;
- }
-
-diff --git a/include/keys/user-type.h b/include/keys/user-type.h
-index bc9ec1d..5e452c8 100644
---- a/include/keys/user-type.h
-+++ b/include/keys/user-type.h
-@@ -35,8 +35,10 @@ struct user_key_payload {
- extern struct key_type key_type_user;
- extern struct key_type key_type_logon;
-
--extern int user_instantiate(struct key *key, const void *data, size_t datalen);
--extern int user_update(struct key *key, const void *data, size_t datalen);
-+struct key_preparsed_payload;
-+
-+extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep);
-+extern int user_update(struct key *key, struct key_preparsed_payload *prep);
- extern int user_match(const struct key *key, const void *criterion);
- extern void user_revoke(struct key *key);
- extern void user_destroy(struct key *key);
-diff --git a/include/linux/key-type.h b/include/linux/key-type.h
-index f0c651c..518a53a 100644
---- a/include/linux/key-type.h
-+++ b/include/linux/key-type.h
-@@ -26,6 +26,27 @@ struct key_construction {
- struct key *authkey;/* authorisation for key being constructed */
- };
-
-+/*
-+ * Pre-parsed payload, used by key add, update and instantiate.
-+ *
-+ * This struct will be cleared and data and datalen will be set with the data
-+ * and length parameters from the caller and quotalen will be set from
-+ * def_datalen from the key type. Then if the preparse() op is provided by the
-+ * key type, that will be called. Then the struct will be passed to the
-+ * instantiate() or the update() op.
-+ *
-+ * If the preparse() op is given, the free_preparse() op will be called to
-+ * clear the contents.
-+ */
-+struct key_preparsed_payload {
-+ char *description; /* Proposed key description (or NULL) */
-+ void *type_data[2]; /* Private key-type data */
-+ void *payload; /* Proposed payload */
-+ const void *data; /* Raw data */
-+ size_t datalen; /* Raw datalen */
-+ size_t quotalen; /* Quota length for proposed payload */
-+};
-+
- typedef int (*request_key_actor_t)(struct key_construction *key,
- const char *op, void *aux);
-
-@@ -45,18 +66,28 @@ struct key_type {
- /* vet a description */
- int (*vet_description)(const char *description);
-
-+ /* Preparse the data blob from userspace that is to be the payload,
-+ * generating a proposed description and payload that will be handed to
-+ * the instantiate() and update() ops.
-+ */
-+ int (*preparse)(struct key_preparsed_payload *prep);
-+
-+ /* Free a preparse data structure.
-+ */
-+ void (*free_preparse)(struct key_preparsed_payload *prep);
-+
- /* instantiate a key of this type
- * - this method should call key_payload_reserve() to determine if the
- * user's quota will hold the payload
- */
-- int (*instantiate)(struct key *key, const void *data, size_t datalen);
-+ int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
-
- /* update a key of this type (optional)
- * - this method should call key_payload_reserve() to recalculate the
- * quota consumption
- * - the key must be locked against read when modifying
- */
-- int (*update)(struct key *key, const void *data, size_t datalen);
-+ int (*update)(struct key *key, struct key_preparsed_payload *prep);
-
- /* match a key against a description */
- int (*match)(const struct key *key, const void *desc);
-diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
-index 9da7fdd..af14cb4 100644
---- a/net/ceph/crypto.c
-+++ b/net/ceph/crypto.c
-@@ -423,14 +423,15 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
- }
- }
-
--int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
-+int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- struct ceph_crypto_key *ckey;
-+ size_t datalen = prep->datalen;
- int ret;
- void *p;
-
- ret = -EINVAL;
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- goto err;
-
- ret = key_payload_reserve(key, datalen);
-@@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
- goto err;
-
- /* TODO ceph_crypto_key_decode should really take const input */
-- p = (void *)data;
-- ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
-+ p = (void *)prep->data;
-+ ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen);
- if (ret < 0)
- goto err_ckey;
-
-diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
-index d9507dd..859ab8b 100644
---- a/net/dns_resolver/dns_key.c
-+++ b/net/dns_resolver/dns_key.c
-@@ -59,13 +59,13 @@ const struct cred *dns_resolver_cache;
- * "ip1,ip2,...#foo=bar"
- */
- static int
--dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
-+dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- struct user_key_payload *upayload;
- unsigned long derrno;
- int ret;
-- size_t result_len = 0;
-- const char *data = _data, *end, *opt;
-+ size_t datalen = prep->datalen, result_len = 0;
-+ const char *data = prep->data, *end, *opt;
-
- kenter("%%%d,%s,'%*.*s',%zu",
- key->serial, key->description,
-diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
-index 8b1f9f4..106c5a6 100644
---- a/net/rxrpc/ar-key.c
-+++ b/net/rxrpc/ar-key.c
-@@ -26,8 +26,8 @@
- #include "ar-internal.h"
-
- static int rxrpc_vet_description_s(const char *);
--static int rxrpc_instantiate(struct key *, const void *, size_t);
--static int rxrpc_instantiate_s(struct key *, const void *, size_t);
-+static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *);
-+static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *);
- static void rxrpc_destroy(struct key *);
- static void rxrpc_destroy_s(struct key *);
- static void rxrpc_describe(const struct key *, struct seq_file *);
-@@ -678,7 +678,7 @@ error:
- *
- * if no data is provided, then a no-security key is made
- */
--static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
-+static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- const struct rxrpc_key_data_v1 *v1;
- struct rxrpc_key_token *token, **pp;
-@@ -686,26 +686,26 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
- u32 kver;
- int ret;
-
-- _enter("{%x},,%zu", key_serial(key), datalen);
-+ _enter("{%x},,%zu", key_serial(key), prep->datalen);
-
- /* handle a no-security key */
-- if (!data && datalen == 0)
-+ if (!prep->data && prep->datalen == 0)
- return 0;
-
- /* determine if the XDR payload format is being used */
-- if (datalen > 7 * 4) {
-- ret = rxrpc_instantiate_xdr(key, data, datalen);
-+ if (prep->datalen > 7 * 4) {
-+ ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen);
- if (ret != -EPROTO)
- return ret;
- }
-
- /* get the key interface version number */
- ret = -EINVAL;
-- if (datalen <= 4 || !data)
-+ if (prep->datalen <= 4 || !prep->data)
- goto error;
-- memcpy(&kver, data, sizeof(kver));
-- data += sizeof(kver);
-- datalen -= sizeof(kver);
-+ memcpy(&kver, prep->data, sizeof(kver));
-+ prep->data += sizeof(kver);
-+ prep->datalen -= sizeof(kver);
-
- _debug("KEY I/F VERSION: %u", kver);
-
-@@ -715,11 +715,11 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
-
- /* deal with a version 1 key */
- ret = -EINVAL;
-- if (datalen < sizeof(*v1))
-+ if (prep->datalen < sizeof(*v1))
- goto error;
-
-- v1 = data;
-- if (datalen != sizeof(*v1) + v1->ticket_length)
-+ v1 = prep->data;
-+ if (prep->datalen != sizeof(*v1) + v1->ticket_length)
- goto error;
-
- _debug("SCIX: %u", v1->security_index);
-@@ -784,17 +784,17 @@ error:
- * instantiate a server secret key
- * data should be a pointer to the 8-byte secret key
- */
--static int rxrpc_instantiate_s(struct key *key, const void *data,
-- size_t datalen)
-+static int rxrpc_instantiate_s(struct key *key,
-+ struct key_preparsed_payload *prep)
- {
- struct crypto_blkcipher *ci;
-
-- _enter("{%x},,%zu", key_serial(key), datalen);
-+ _enter("{%x},,%zu", key_serial(key), prep->datalen);
-
-- if (datalen != 8)
-+ if (prep->datalen != 8)
- return -EINVAL;
-
-- memcpy(&key->type_data, data, 8);
-+ memcpy(&key->type_data, prep->data, 8);
-
- ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(ci)) {
-@@ -802,7 +802,7 @@ static int rxrpc_instantiate_s(struct key *key, const void *data,
- return PTR_ERR(ci);
- }
-
-- if (crypto_blkcipher_setkey(ci, data, 8) < 0)
-+ if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
- BUG();
-
- key->payload.data = ci;
-diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
-index 2d1bb8a..9e1e005 100644
---- a/security/keys/encrypted-keys/encrypted.c
-+++ b/security/keys/encrypted-keys/encrypted.c
-@@ -773,8 +773,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
- *
- * On success, return 0. Otherwise return errno.
- */
--static int encrypted_instantiate(struct key *key, const void *data,
-- size_t datalen)
-+static int encrypted_instantiate(struct key *key,
-+ struct key_preparsed_payload *prep)
- {
- struct encrypted_key_payload *epayload = NULL;
- char *datablob = NULL;
-@@ -782,16 +782,17 @@ static int encrypted_instantiate(struct key *key, const void *data,
- char *master_desc = NULL;
- char *decrypted_datalen = NULL;
- char *hex_encoded_iv = NULL;
-+ size_t datalen = prep->datalen;
- int ret;
-
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- return -EINVAL;
-
- datablob = kmalloc(datalen + 1, GFP_KERNEL);
- if (!datablob)
- return -ENOMEM;
- datablob[datalen] = 0;
-- memcpy(datablob, data, datalen);
-+ memcpy(datablob, prep->data, datalen);
- ret = datablob_parse(datablob, &format, &master_desc,
- &decrypted_datalen, &hex_encoded_iv);
- if (ret < 0)
-@@ -834,16 +835,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu)
- *
- * On success, return 0. Otherwise return errno.
- */
--static int encrypted_update(struct key *key, const void *data, size_t datalen)
-+static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
- {
- struct encrypted_key_payload *epayload = key->payload.data;
- struct encrypted_key_payload *new_epayload;
- char *buf;
- char *new_master_desc = NULL;
- const char *format = NULL;
-+ size_t datalen = prep->datalen;
- int ret = 0;
-
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- return -EINVAL;
-
- buf = kmalloc(datalen + 1, GFP_KERNEL);
-@@ -851,7 +853,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
- return -ENOMEM;
-
- buf[datalen] = 0;
-- memcpy(buf, data, datalen);
-+ memcpy(buf, prep->data, datalen);
- ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
- if (ret < 0)
- goto out;
-diff --git a/security/keys/key.c b/security/keys/key.c
-index 50d96d4..1d039af 100644
---- a/security/keys/key.c
-+++ b/security/keys/key.c
-@@ -412,8 +412,7 @@ EXPORT_SYMBOL(key_payload_reserve);
- * key_construction_mutex.
- */
- static int __key_instantiate_and_link(struct key *key,
-- const void *data,
-- size_t datalen,
-+ struct key_preparsed_payload *prep,
- struct key *keyring,
- struct key *authkey,
- unsigned long *_prealloc)
-@@ -431,7 +430,7 @@ static int __key_instantiate_and_link(struct key *key,
- /* can't instantiate twice */
- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
- /* instantiate the key */
-- ret = key->type->instantiate(key, data, datalen);
-+ ret = key->type->instantiate(key, prep);
-
- if (ret == 0) {
- /* mark the key as being instantiated */
-@@ -482,22 +481,37 @@ int key_instantiate_and_link(struct key *key,
- struct key *keyring,
- struct key *authkey)
- {
-+ struct key_preparsed_payload prep;
- unsigned long prealloc;
- int ret;
-
-+ memset(&prep, 0, sizeof(prep));
-+ prep.data = data;
-+ prep.datalen = datalen;
-+ prep.quotalen = key->type->def_datalen;
-+ if (key->type->preparse) {
-+ ret = key->type->preparse(&prep);
-+ if (ret < 0)
-+ goto error;
-+ }
-+
- if (keyring) {
- ret = __key_link_begin(keyring, key->type, key->description,
- &prealloc);
- if (ret < 0)
-- return ret;
-+ goto error_free_preparse;
- }
-
-- ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey,
-+ ret = __key_instantiate_and_link(key, &prep, keyring, authkey,
- &prealloc);
-
- if (keyring)
- __key_link_end(keyring, key->type, prealloc);
-
-+error_free_preparse:
-+ if (key->type->preparse)
-+ key->type->free_preparse(&prep);
-+error:
- return ret;
- }
-
-@@ -706,7 +720,7 @@ void key_type_put(struct key_type *ktype)
- * if we get an error.
- */
- static inline key_ref_t __key_update(key_ref_t key_ref,
-- const void *payload, size_t plen)
-+ struct key_preparsed_payload *prep)
- {
- struct key *key = key_ref_to_ptr(key_ref);
- int ret;
-@@ -722,7 +736,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
-
- down_write(&key->sem);
-
-- ret = key->type->update(key, payload, plen);
-+ ret = key->type->update(key, prep);
- if (ret == 0)
- /* updating a negative key instantiates it */
- clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
-@@ -774,6 +788,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
- unsigned long flags)
- {
- unsigned long prealloc;
-+ struct key_preparsed_payload prep;
- const struct cred *cred = current_cred();
- struct key_type *ktype;
- struct key *keyring, *key = NULL;
-@@ -789,8 +804,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
- }
-
- key_ref = ERR_PTR(-EINVAL);
-- if (!ktype->match || !ktype->instantiate)
-- goto error_2;
-+ if (!ktype->match || !ktype->instantiate ||
-+ (!description && !ktype->preparse))
-+ goto error_put_type;
-
- keyring = key_ref_to_ptr(keyring_ref);
-
-@@ -798,18 +814,37 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
-
- key_ref = ERR_PTR(-ENOTDIR);
- if (keyring->type != &key_type_keyring)
-- goto error_2;
-+ goto error_put_type;
-+
-+ memset(&prep, 0, sizeof(prep));
-+ prep.data = payload;
-+ prep.datalen = plen;
-+ prep.quotalen = ktype->def_datalen;
-+ if (ktype->preparse) {
-+ ret = ktype->preparse(&prep);
-+ if (ret < 0) {
-+ key_ref = ERR_PTR(ret);
-+ goto error_put_type;
-+ }
-+ if (!description)
-+ description = prep.description;
-+ key_ref = ERR_PTR(-EINVAL);
-+ if (!description)
-+ goto error_free_prep;
-+ }
-
- ret = __key_link_begin(keyring, ktype, description, &prealloc);
-- if (ret < 0)
-- goto error_2;
-+ if (ret < 0) {
-+ key_ref = ERR_PTR(ret);
-+ goto error_free_prep;
-+ }
-
- /* if we're going to allocate a new key, we're going to have
- * to modify the keyring */
- ret = key_permission(keyring_ref, KEY_WRITE);
- if (ret < 0) {
- key_ref = ERR_PTR(ret);
-- goto error_3;
-+ goto error_link_end;
- }
-
- /* if it's possible to update this type of key, search for an existing
-@@ -840,25 +875,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
- perm, flags);
- if (IS_ERR(key)) {
- key_ref = ERR_CAST(key);
-- goto error_3;
-+ goto error_link_end;
- }
-
- /* instantiate it and link it into the target keyring */
-- ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL,
-- &prealloc);
-+ ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc);
- if (ret < 0) {
- key_put(key);
- key_ref = ERR_PTR(ret);
-- goto error_3;
-+ goto error_link_end;
- }
-
- key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
-
-- error_3:
-+error_link_end:
- __key_link_end(keyring, ktype, prealloc);
-- error_2:
-+error_free_prep:
-+ if (ktype->preparse)
-+ ktype->free_preparse(&prep);
-+error_put_type:
- key_type_put(ktype);
-- error:
-+error:
- return key_ref;
-
- found_matching_key:
-@@ -866,10 +903,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
- * - we can drop the locks first as we have the key pinned
- */
- __key_link_end(keyring, ktype, prealloc);
-- key_type_put(ktype);
-
-- key_ref = __key_update(key_ref, payload, plen);
-- goto error;
-+ key_ref = __key_update(key_ref, &prep);
-+ goto error_free_prep;
- }
- EXPORT_SYMBOL(key_create_or_update);
-
-@@ -888,6 +924,7 @@ EXPORT_SYMBOL(key_create_or_update);
- */
- int key_update(key_ref_t key_ref, const void *payload, size_t plen)
- {
-+ struct key_preparsed_payload prep;
- struct key *key = key_ref_to_ptr(key_ref);
- int ret;
-
-@@ -900,18 +937,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
-
- /* attempt to update it if supported */
- ret = -EOPNOTSUPP;
-- if (key->type->update) {
-- down_write(&key->sem);
--
-- ret = key->type->update(key, payload, plen);
-- if (ret == 0)
-- /* updating a negative key instantiates it */
-- clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
-+ if (!key->type->update)
-+ goto error;
-
-- up_write(&key->sem);
-+ memset(&prep, 0, sizeof(prep));
-+ prep.data = payload;
-+ prep.datalen = plen;
-+ prep.quotalen = key->type->def_datalen;
-+ if (key->type->preparse) {
-+ ret = key->type->preparse(&prep);
-+ if (ret < 0)
-+ goto error;
- }
-
-- error:
-+ down_write(&key->sem);
-+
-+ ret = key->type->update(key, &prep);
-+ if (ret == 0)
-+ /* updating a negative key instantiates it */
-+ clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
-+
-+ up_write(&key->sem);
-+
-+ if (key->type->preparse)
-+ key->type->free_preparse(&prep);
-+error:
- return ret;
- }
- EXPORT_SYMBOL(key_update);
-diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
-index 3364fbf..505d40b 100644
---- a/security/keys/keyctl.c
-+++ b/security/keys/keyctl.c
-@@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type,
- * Extract the description of a new key from userspace and either add it as a
- * new key to the specified keyring or update a matching key in that keyring.
- *
-+ * If the description is NULL or an empty string, the key type is asked to
-+ * generate one from the payload.
-+ *
- * The keyring must be writable so that we can attach the key to it.
- *
- * If successful, the new key's serial number is returned, otherwise an error
-@@ -72,10 +75,17 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
- if (ret < 0)
- goto error;
-
-- description = strndup_user(_description, PAGE_SIZE);
-- if (IS_ERR(description)) {
-- ret = PTR_ERR(description);
-- goto error;
-+ description = NULL;
-+ if (_description) {
-+ description = strndup_user(_description, PAGE_SIZE);
-+ if (IS_ERR(description)) {
-+ ret = PTR_ERR(description);
-+ goto error;
-+ }
-+ if (!*description) {
-+ kfree(description);
-+ description = NULL;
-+ }
- }
-
- /* pull the payload in if one was supplied */
-diff --git a/security/keys/keyring.c b/security/keys/keyring.c
-index 81e7852..f04d8cf 100644
---- a/security/keys/keyring.c
-+++ b/security/keys/keyring.c
-@@ -66,7 +66,7 @@ static inline unsigned keyring_hash(const char *desc)
- * operations.
- */
- static int keyring_instantiate(struct key *keyring,
-- const void *data, size_t datalen);
-+ struct key_preparsed_payload *prep);
- static int keyring_match(const struct key *keyring, const void *criterion);
- static void keyring_revoke(struct key *keyring);
- static void keyring_destroy(struct key *keyring);
-@@ -121,12 +121,12 @@ static void keyring_publish_name(struct key *keyring)
- * Returns 0 on success, -EINVAL if given any data.
- */
- static int keyring_instantiate(struct key *keyring,
-- const void *data, size_t datalen)
-+ struct key_preparsed_payload *prep)
- {
- int ret;
-
- ret = -EINVAL;
-- if (datalen == 0) {
-+ if (prep->datalen == 0) {
- /* make the keyring available by name if it has one */
- keyring_publish_name(keyring);
- ret = 0;
-diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
-index 60d4e3f..85730d5 100644
---- a/security/keys/request_key_auth.c
-+++ b/security/keys/request_key_auth.c
-@@ -19,7 +19,8 @@
- #include <asm/uaccess.h>
- #include "internal.h"
-
--static int request_key_auth_instantiate(struct key *, const void *, size_t);
-+static int request_key_auth_instantiate(struct key *,
-+ struct key_preparsed_payload *);
- static void request_key_auth_describe(const struct key *, struct seq_file *);
- static void request_key_auth_revoke(struct key *);
- static void request_key_auth_destroy(struct key *);
-@@ -42,10 +43,9 @@ struct key_type key_type_request_key_auth = {
- * Instantiate a request-key authorisation key.
- */
- static int request_key_auth_instantiate(struct key *key,
-- const void *data,
-- size_t datalen)
-+ struct key_preparsed_payload *prep)
- {
-- key->payload.data = (struct request_key_auth *) data;
-+ key->payload.data = (struct request_key_auth *)prep->data;
- return 0;
- }
-
-diff --git a/security/keys/trusted.c b/security/keys/trusted.c
-index 2d5d041..42036c7 100644
---- a/security/keys/trusted.c
-+++ b/security/keys/trusted.c
-@@ -927,22 +927,23 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
- *
- * On success, return 0. Otherwise return errno.
- */
--static int trusted_instantiate(struct key *key, const void *data,
-- size_t datalen)
-+static int trusted_instantiate(struct key *key,
-+ struct key_preparsed_payload *prep)
- {
- struct trusted_key_payload *payload = NULL;
- struct trusted_key_options *options = NULL;
-+ size_t datalen = prep->datalen;
- char *datablob;
- int ret = 0;
- int key_cmd;
-
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- return -EINVAL;
-
- datablob = kmalloc(datalen + 1, GFP_KERNEL);
- if (!datablob)
- return -ENOMEM;
-- memcpy(datablob, data, datalen);
-+ memcpy(datablob, prep->data, datalen);
- datablob[datalen] = '\0';
-
- options = trusted_options_alloc();
-@@ -1011,17 +1012,18 @@ static void trusted_rcu_free(struct rcu_head *rcu)
- /*
- * trusted_update - reseal an existing key with new PCR values
- */
--static int trusted_update(struct key *key, const void *data, size_t datalen)
-+static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
- {
- struct trusted_key_payload *p = key->payload.data;
- struct trusted_key_payload *new_p;
- struct trusted_key_options *new_o;
-+ size_t datalen = prep->datalen;
- char *datablob;
- int ret = 0;
-
- if (!p->migratable)
- return -EPERM;
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- return -EINVAL;
-
- datablob = kmalloc(datalen + 1, GFP_KERNEL);
-@@ -1038,7 +1040,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen)
- goto out;
- }
-
-- memcpy(datablob, data, datalen);
-+ memcpy(datablob, prep->data, datalen);
- datablob[datalen] = '\0';
- ret = datablob_parse(datablob, new_p, new_o);
- if (ret != Opt_update) {
-diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
-index c7660a2..55dc889 100644
---- a/security/keys/user_defined.c
-+++ b/security/keys/user_defined.c
-@@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon);
- /*
- * instantiate a user defined key
- */
--int user_instantiate(struct key *key, const void *data, size_t datalen)
-+int user_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
- struct user_key_payload *upayload;
-+ size_t datalen = prep->datalen;
- int ret;
-
- ret = -EINVAL;
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- goto error;
-
- ret = key_payload_reserve(key, datalen);
-@@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen)
-
- /* attach the data */
- upayload->datalen = datalen;
-- memcpy(upayload->data, data, datalen);
-+ memcpy(upayload->data, prep->data, datalen);
- rcu_assign_keypointer(key, upayload);
- ret = 0;
-
-@@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate);
- * update a user defined key
- * - the key's semaphore is write-locked
- */
--int user_update(struct key *key, const void *data, size_t datalen)
-+int user_update(struct key *key, struct key_preparsed_payload *prep)
- {
- struct user_key_payload *upayload, *zap;
-+ size_t datalen = prep->datalen;
- int ret;
-
- ret = -EINVAL;
-- if (datalen <= 0 || datalen > 32767 || !data)
-+ if (datalen <= 0 || datalen > 32767 || !prep->data)
- goto error;
-
- /* construct a replacement payload */
-@@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen)
- goto error;
-
- upayload->datalen = datalen;
-- memcpy(upayload->data, data, datalen);
-+ memcpy(upayload->data, prep->data, datalen);
-
- /* check the quota and attach the new data */
- zap = upayload;
---
-1.7.12.1
-
-
-From 162ce9c1b0f28d36598975f8931f216245b7e778 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 13 Sep 2012 13:09:33 +0100
-Subject: [PATCH 03/37] MPILIB: Provide count_leading/trailing_zeros() based
- on arch functions
-
-Provide count_leading/trailing_zeros() macros based on extant arch bit scanning
-functions rather than reimplementing from scratch in MPILIB.
-
-Whilst we're at it, turn count_foo_zeros(n, x) into n = count_foo_zeros(x).
-
-Also move the definition to asm-generic as other people may be interested in
-using it.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Cc: David S. Miller <davem@davemloft.net>
-Cc: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
-Cc: Arnd Bergmann <arnd@arndb.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/asm-generic/bitops/count_zeros.h | 57 +++++++++++++
- lib/mpi/longlong.h | 138 +------------------------------
- lib/mpi/mpi-bit.c | 2 +-
- lib/mpi/mpi-pow.c | 4 +-
- 4 files changed, 62 insertions(+), 139 deletions(-)
- create mode 100644 include/asm-generic/bitops/count_zeros.h
-
-diff --git a/include/asm-generic/bitops/count_zeros.h b/include/asm-generic/bitops/count_zeros.h
-new file mode 100644
-index 0000000..97520d2
---- /dev/null
-+++ b/include/asm-generic/bitops/count_zeros.h
-@@ -0,0 +1,57 @@
-+/* Count leading and trailing zeros functions
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
-+#define _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
-+
-+#include <asm/bitops.h>
-+
-+/**
-+ * count_leading_zeros - Count the number of zeros from the MSB back
-+ * @x: The value
-+ *
-+ * Count the number of leading zeros from the MSB going towards the LSB in @x.
-+ *
-+ * If the MSB of @x is set, the result is 0.
-+ * If only the LSB of @x is set, then the result is BITS_PER_LONG-1.
-+ * If @x is 0 then the result is COUNT_LEADING_ZEROS_0.
-+ */
-+static inline int count_leading_zeros(unsigned long x)
-+{
-+ if (sizeof(x) == 4)
-+ return BITS_PER_LONG - fls(x);
-+ else
-+ return BITS_PER_LONG - fls64(x);
-+}
-+
-+#define COUNT_LEADING_ZEROS_0 BITS_PER_LONG
-+
-+/**
-+ * count_trailing_zeros - Count the number of zeros from the LSB forwards
-+ * @x: The value
-+ *
-+ * Count the number of trailing zeros from the LSB going towards the MSB in @x.
-+ *
-+ * If the LSB of @x is set, the result is 0.
-+ * If only the MSB of @x is set, then the result is BITS_PER_LONG-1.
-+ * If @x is 0 then the result is COUNT_TRAILING_ZEROS_0.
-+ */
-+static inline int count_trailing_zeros(unsigned long x)
-+{
-+#define COUNT_TRAILING_ZEROS_0 (-1)
-+
-+ if (sizeof(x) == 4)
-+ return ffs(x);
-+ else
-+ return (x != 0) ? __ffs(x) : COUNT_TRAILING_ZEROS_0;
-+}
-+
-+#endif /* _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ */
-diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
-index 29f9862..678ce4f 100644
---- a/lib/mpi/longlong.h
-+++ b/lib/mpi/longlong.h
-@@ -19,6 +19,8 @@
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA. */
-
-+#include <asm-generic/bitops/count_zeros.h>
-+
- /* You have to define the following before including this file:
- *
- * UWtype -- An unsigned type, default type for operations (typically a "word")
-@@ -146,12 +148,6 @@ do { \
- : "1" ((USItype)(n1)), \
- "r" ((USItype)(n0)), \
- "r" ((USItype)(d)))
--
--#define count_leading_zeros(count, x) \
-- __asm__ ("clz %0,%1" \
-- : "=r" ((USItype)(count)) \
-- : "r" ((USItype)(x)))
--#define COUNT_LEADING_ZEROS_0 32
- #endif /* __a29k__ */
-
- #if defined(__alpha) && W_TYPE_SIZE == 64
-@@ -298,11 +294,6 @@ extern UDItype __udiv_qrnnd();
- : "1" ((USItype)(nh)), \
- "0" ((USItype)(nl)), \
- "g" ((USItype)(d)))
--#define count_leading_zeros(count, x) \
-- __asm__ ("bsch/1 %1,%0" \
-- : "=g" (count) \
-- : "g" ((USItype)(x)), \
-- "0" ((USItype)0))
- #endif
-
- /***************************************
-@@ -354,27 +345,6 @@ do { USItype __r; \
- } while (0)
- extern USItype __udiv_qrnnd();
- #endif /* LONGLONG_STANDALONE */
--#define count_leading_zeros(count, x) \
--do { \
-- USItype __tmp; \
-- __asm__ ( \
-- "ldi 1,%0\n" \
-- "extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
-- "extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
-- "ldo 16(%0),%0 ; Yes. Perform add.\n" \
-- "extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
-- "extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
-- "ldo 8(%0),%0 ; Yes. Perform add.\n" \
-- "extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
-- "extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
-- "ldo 4(%0),%0 ; Yes. Perform add.\n" \
-- "extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
-- "extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
-- "ldo 2(%0),%0 ; Yes. Perform add.\n" \
-- "extru %1,30,1,%1 ; Extract bit 1.\n" \
-- "sub %0,%1,%0 ; Subtract it. " \
-- : "=r" (count), "=r" (__tmp) : "1" (x)); \
--} while (0)
- #endif /* hppa */
-
- /***************************************
-@@ -457,15 +427,6 @@ do { \
- : "0" ((USItype)(n0)), \
- "1" ((USItype)(n1)), \
- "rm" ((USItype)(d)))
--#define count_leading_zeros(count, x) \
--do { \
-- USItype __cbtmp; \
-- __asm__ ("bsrl %1,%0" \
-- : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
-- (count) = __cbtmp ^ 31; \
--} while (0)
--#define count_trailing_zeros(count, x) \
-- __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
- #ifndef UMUL_TIME
- #define UMUL_TIME 40
- #endif
-@@ -536,15 +497,6 @@ do { \
- "dI" ((USItype)(d))); \
- (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
- } while (0)
--#define count_leading_zeros(count, x) \
--do { \
-- USItype __cbtmp; \
-- __asm__ ("scanbit %1,%0" \
-- : "=r" (__cbtmp) \
-- : "r" ((USItype)(x))); \
-- (count) = __cbtmp ^ 31; \
--} while (0)
--#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
- #if defined(__i960mx) /* what is the proper symbol to test??? */
- #define rshift_rhlc(r, h, l, c) \
- do { \
-@@ -603,11 +555,6 @@ do { \
- : "0" ((USItype)(n0)), \
- "1" ((USItype)(n1)), \
- "dmi" ((USItype)(d)))
--#define count_leading_zeros(count, x) \
-- __asm__ ("bfffo %1{%b2:%b2},%0" \
-- : "=d" ((USItype)(count)) \
-- : "od" ((USItype)(x)), "n" (0))
--#define COUNT_LEADING_ZEROS_0 32
- #else /* not mc68020 */
- #define umul_ppmm(xh, xl, a, b) \
- do { USItype __umul_tmp1, __umul_tmp2; \
-@@ -664,15 +611,6 @@ do { USItype __umul_tmp1, __umul_tmp2; \
- "rJ" ((USItype)(bh)), \
- "rJ" ((USItype)(al)), \
- "rJ" ((USItype)(bl)))
--#define count_leading_zeros(count, x) \
--do { \
-- USItype __cbtmp; \
-- __asm__ ("ff1 %0,%1" \
-- : "=r" (__cbtmp) \
-- : "r" ((USItype)(x))); \
-- (count) = __cbtmp ^ 31; \
--} while (0)
--#define COUNT_LEADING_ZEROS_0 63 /* sic */
- #if defined(__m88110__)
- #define umul_ppmm(wh, wl, u, v) \
- do { \
-@@ -779,12 +717,6 @@ do { \
- : "0" (__xx.__ll), \
- "g" ((USItype)(d))); \
- (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
--#define count_trailing_zeros(count, x) \
--do { \
-- __asm__("ffsd %2,%0" \
-- : "=r"((USItype) (count)) \
-- : "0"((USItype) 0), "r"((USItype) (x))); \
-- } while (0)
- #endif /* __ns32000__ */
-
- /***************************************
-@@ -855,11 +787,6 @@ do { \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
- } while (0)
--#define count_leading_zeros(count, x) \
-- __asm__ ("{cntlz|cntlzw} %0,%1" \
-- : "=r" ((USItype)(count)) \
-- : "r" ((USItype)(x)))
--#define COUNT_LEADING_ZEROS_0 32
- #if defined(_ARCH_PPC)
- #define umul_ppmm(ph, pl, m0, m1) \
- do { \
-@@ -1001,19 +928,6 @@ do { \
- } while (0)
- #define UMUL_TIME 20
- #define UDIV_TIME 200
--#define count_leading_zeros(count, x) \
--do { \
-- if ((x) >= 0x10000) \
-- __asm__ ("clz %0,%1" \
-- : "=r" ((USItype)(count)) \
-- : "r" ((USItype)(x) >> 16)); \
-- else { \
-- __asm__ ("clz %0,%1" \
-- : "=r" ((USItype)(count)) \
-- : "r" ((USItype)(x))); \
-- (count) += 16; \
-- } \
--} while (0)
- #endif /* RT/ROMP */
-
- /***************************************
-@@ -1142,13 +1056,6 @@ do { \
- "rI" ((USItype)(d)) \
- : "%g1" __AND_CLOBBER_CC)
- #define UDIV_TIME 37
--#define count_leading_zeros(count, x) \
-- __asm__ ("scan %1,0,%0" \
-- : "=r" ((USItype)(x)) \
-- : "r" ((USItype)(count)))
--/* Early sparclites return 63 for an argument of 0, but they warn that future
-- implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
-- undefined. */
- #endif /* __sparclite__ */
- #endif /* __sparc_v8__ */
- /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
-@@ -1454,47 +1361,6 @@ do { \
- #define udiv_qrnnd __udiv_qrnnd_c
- #endif
-
--#undef count_leading_zeros
--#if !defined(count_leading_zeros)
-- extern
--#ifdef __STDC__
-- const
--#endif
-- unsigned char __clz_tab[];
--#define count_leading_zeros(count, x) \
--do { \
-- UWtype __xr = (x); \
-- UWtype __a; \
-- \
-- if (W_TYPE_SIZE <= 32) { \
-- __a = __xr < ((UWtype) 1 << 2*__BITS4) \
-- ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
-- : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
-- } \
-- else { \
-- for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
-- if (((__xr >> __a) & 0xff) != 0) \
-- break; \
-- } \
-- \
-- (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
--} while (0)
-- /* This version gives a well-defined value for zero. */
--#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
--#endif
--
--#if !defined(count_trailing_zeros)
--/* Define count_trailing_zeros using count_leading_zeros. The latter might be
-- defined in asm, but if it is not, the C version above is good enough. */
--#define count_trailing_zeros(count, x) \
--do { \
-- UWtype __ctz_x = (x); \
-- UWtype __ctz_c; \
-- count_leading_zeros(__ctz_c, __ctz_x & -__ctz_x); \
-- (count) = W_TYPE_SIZE - 1 - __ctz_c; \
--} while (0)
--#endif
--
- #ifndef UDIV_NEEDS_NORMALIZATION
- #define UDIV_NEEDS_NORMALIZATION 0
- #endif
-diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c
-index 5687248..503537e 100644
---- a/lib/mpi/mpi-bit.c
-+++ b/lib/mpi/mpi-bit.c
-@@ -45,7 +45,7 @@ unsigned mpi_get_nbits(MPI a)
- if (a->nlimbs) {
- mpi_limb_t alimb = a->d[a->nlimbs - 1];
- if (alimb)
-- count_leading_zeros(n, alimb);
-+ n = count_leading_zeros(alimb);
- else
- n = BITS_PER_MPI_LIMB;
- n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB;
-diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
-index 67f3e79..5464c87 100644
---- a/lib/mpi/mpi-pow.c
-+++ b/lib/mpi/mpi-pow.c
-@@ -77,7 +77,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
- mp = mp_marker = mpi_alloc_limb_space(msize);
- if (!mp)
- goto enomem;
-- count_leading_zeros(mod_shift_cnt, mod->d[msize - 1]);
-+ mod_shift_cnt = count_leading_zeros(mod->d[msize - 1]);
- if (mod_shift_cnt)
- mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt);
- else
-@@ -169,7 +169,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
-
- i = esize - 1;
- e = ep[i];
-- count_leading_zeros(c, e);
-+ c = count_leading_zeros(e);
- e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
- c = BITS_PER_MPI_LIMB - 1 - c;
-
---
-1.7.12.1
-
-
-From ef184bcab1e58dafae2f02ae30824365bec1d27a Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 13 Sep 2012 15:17:21 +0100
-Subject: [PATCH 04/37] KEYS: Document asymmetric key type
-
-In-source documentation for the asymmetric key type. This will be located in:
-
- Documentation/crypto/asymmetric-keys.txt
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- Documentation/crypto/asymmetric-keys.txt | 312 +++++++++++++++++++++++++++++++
- 1 file changed, 312 insertions(+)
- create mode 100644 Documentation/crypto/asymmetric-keys.txt
-
-diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt
-new file mode 100644
-index 0000000..b767590
---- /dev/null
-+++ b/Documentation/crypto/asymmetric-keys.txt
-@@ -0,0 +1,312 @@
-+ =============================================
-+ ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE
-+ =============================================
-+
-+Contents:
-+
-+ - Overview.
-+ - Key identification.
-+ - Accessing asymmetric keys.
-+ - Signature verification.
-+ - Asymmetric key subtypes.
-+ - Instantiation data parsers.
-+
-+
-+========
-+OVERVIEW
-+========
-+
-+The "asymmetric" key type is designed to be a container for the keys used in
-+public-key cryptography, without imposing any particular restrictions on the
-+form or mechanism of the cryptography or form of the key.
-+
-+The asymmetric key is given a subtype that defines what sort of data is
-+associated with the key and provides operations to describe and destroy it.
-+However, no requirement is made that the key data actually be stored in the
-+key.
-+
-+A completely in-kernel key retention and operation subtype can be defined, but
-+it would also be possible to provide access to cryptographic hardware (such as
-+a TPM) that might be used to both retain the relevant key and perform
-+operations using that key. In such a case, the asymmetric key would then
-+merely be an interface to the TPM driver.
-+
-+Also provided is the concept of a data parser. Data parsers are responsible
-+for extracting information from the blobs of data passed to the instantiation
-+function. The first data parser that recognises the blob gets to set the
-+subtype of the key and define the operations that can be done on that key.
-+
-+A data parser may interpret the data blob as containing the bits representing a
-+key, or it may interpret it as a reference to a key held somewhere else in the
-+system (for example, a TPM).
-+
-+
-+==================
-+KEY IDENTIFICATION
-+==================
-+
-+If a key is added with an empty name, the instantiation data parsers are given
-+the opportunity to pre-parse a key and to determine the description the key
-+should be given from the content of the key.
-+
-+This can then be used to refer to the key, either by complete match or by
-+partial match. The key type may also use other criteria to refer to a key.
-+
-+The asymmetric key type's match function can then perform a wider range of
-+comparisons than just the straightforward comparison of the description with
-+the criterion string:
-+
-+ (1) If the criterion string is of the form "id:<hexdigits>" then the match
-+ function will examine a key's fingerprint to see if the hex digits given
-+ after the "id:" match the tail. For instance:
-+
-+ keyctl search @s asymmetric id:5acc2142
-+
-+ will match a key with fingerprint:
-+
-+ 1A00 2040 7601 7889 DE11 882C 3823 04AD 5ACC 2142
-+
-+ (2) If the criterion string is of the form "<subtype>:<hexdigits>" then the
-+ match will match the ID as in (1), but with the added restriction that
-+ only keys of the specified subtype (e.g. tpm) will be matched. For
-+ instance:
-+
-+ keyctl search @s asymmetric tpm:5acc2142
-+
-+Looking in /proc/keys, the last 8 hex digits of the key fingerprint are
-+displayed, along with the subtype:
-+
-+ 1a39e171 I----- 1 perm 3f010000 0 0 asymmetri modsign.0: DSA 5acc2142 []
-+
-+
-+=========================
-+ACCESSING ASYMMETRIC KEYS
-+=========================
-+
-+For general access to asymmetric keys from within the kernel, the following
-+inclusion is required:
-+
-+ #include <crypto/public_key.h>
-+
-+This gives access to functions for dealing with asymmetric / public keys.
-+Three enums are defined there for representing public-key cryptography
-+algorithms:
-+
-+ enum pkey_algo
-+
-+digest algorithms used by those:
-+
-+ enum pkey_hash_algo
-+
-+and key identifier representations:
-+
-+ enum pkey_id_type
-+
-+Note that the key type representation types are required because key
-+identifiers from different standards aren't necessarily compatible. For
-+instance, PGP generates key identifiers by hashing the key data plus some
-+PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers.
-+
-+The operations defined upon a key are:
-+
-+ (1) Signature verification.
-+
-+Other operations are possible (such as encryption) with the same key data
-+required for verification, but not currently supported, and others
-+(eg. decryption and signature generation) require extra key data.
-+
-+
-+SIGNATURE VERIFICATION
-+----------------------
-+
-+An operation is provided to perform cryptographic signature verification, using
-+an asymmetric key to provide or to provide access to the public key.
-+
-+ int verify_signature(const struct key *key,
-+ const struct public_key_signature *sig);
-+
-+The caller must have already obtained the key from some source and can then use
-+it to check the signature. The caller must have parsed the signature and
-+transferred the relevant bits to the structure pointed to by sig.
-+
-+ struct public_key_signature {
-+ u8 *digest;
-+ u8 digest_size;
-+ enum pkey_hash_algo pkey_hash_algo : 8;
-+ u8 nr_mpi;
-+ union {
-+ MPI mpi[2];
-+ ...
-+ };
-+ };
-+
-+The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that
-+make up the actual signature must be stored in sig->mpi[] and the count of MPIs
-+placed in sig->nr_mpi.
-+
-+In addition, the data must have been digested by the caller and the resulting
-+hash must be pointed to by sig->digest and the size of the hash be placed in
-+sig->digest_size.
-+
-+The function will return 0 upon success or -EKEYREJECTED if the signature
-+doesn't match.
-+
-+The function may also return -ENOTSUPP if an unsupported public-key algorithm
-+or public-key/hash algorithm combination is specified or the key doesn't
-+support the operation; -EBADMSG or -ERANGE if some of the parameters have weird
-+data; or -ENOMEM if an allocation can't be performed. -EINVAL can be returned
-+if the key argument is the wrong type or is incompletely set up.
-+
-+
-+=======================
-+ASYMMETRIC KEY SUBTYPES
-+=======================
-+
-+Asymmetric keys have a subtype that defines the set of operations that can be
-+performed on that key and that determines what data is attached as the key
-+payload. The payload format is entirely at the whim of the subtype.
-+
-+The subtype is selected by the key data parser and the parser must initialise
-+the data required for it. The asymmetric key retains a reference on the
-+subtype module.
-+
-+The subtype definition structure can be found in:
-+
-+ #include <keys/asymmetric-subtype.h>
-+
-+and looks like the following:
-+
-+ struct asymmetric_key_subtype {
-+ struct module *owner;
-+ const char *name;
-+
-+ void (*describe)(const struct key *key, struct seq_file *m);
-+ void (*destroy)(void *payload);
-+ int (*verify_signature)(const struct key *key,
-+ const struct public_key_signature *sig);
-+ };
-+
-+Asymmetric keys point to this with their type_data[0] member.
-+
-+The owner and name fields should be set to the owning module and the name of
-+the subtype. Currently, the name is only used for print statements.
-+
-+There are a number of operations defined by the subtype:
-+
-+ (1) describe().
-+
-+ Mandatory. This allows the subtype to display something in /proc/keys
-+ against the key. For instance the name of the public key algorithm type
-+ could be displayed. The key type will display the tail of the key
-+ identity string after this.
-+
-+ (2) destroy().
-+
-+ Mandatory. This should free the memory associated with the key. The
-+ asymmetric key will look after freeing the fingerprint and releasing the
-+ reference on the subtype module.
-+
-+ (3) verify_signature().
-+
-+ Optional. These are the entry points for the key usage operations.
-+ Currently there is only the one defined. If not set, the caller will be
-+ given -ENOTSUPP. The subtype may do anything it likes to implement an
-+ operation, including offloading to hardware.
-+
-+
-+==========================
-+INSTANTIATION DATA PARSERS
-+==========================
-+
-+The asymmetric key type doesn't generally want to store or to deal with a raw
-+blob of data that holds the key data. It would have to parse it and error
-+check it each time it wanted to use it. Further, the contents of the blob may
-+have various checks that can be performed on it (eg. self-signatures, validity
-+dates) and may contain useful data about the key (identifiers, capabilities).
-+
-+Also, the blob may represent a pointer to some hardware containing the key
-+rather than the key itself.
-+
-+Examples of blob formats for which parsers could be implemented include:
-+
-+ - OpenPGP packet stream [RFC 4880].
-+ - X.509 ASN.1 stream.
-+ - Pointer to TPM key.
-+ - Pointer to UEFI key.
-+
-+During key instantiation each parser in the list is tried until one doesn't
-+return -EBADMSG.
-+
-+The parser definition structure can be found in:
-+
-+ #include <keys/asymmetric-parser.h>
-+
-+and looks like the following:
-+
-+ struct asymmetric_key_parser {
-+ struct module *owner;
-+ const char *name;
-+
-+ int (*parse)(struct key_preparsed_payload *prep);
-+ };
-+
-+The owner and name fields should be set to the owning module and the name of
-+the parser.
-+
-+There is currently only a single operation defined by the parser, and it is
-+mandatory:
-+
-+ (1) parse().
-+
-+ This is called to preparse the key from the key creation and update paths.
-+ In particular, it is called during the key creation _before_ a key is
-+ allocated, and as such, is permitted to provide the key's description in
-+ the case that the caller declines to do so.
-+
-+ The caller passes a pointer to the following struct with all of the fields
-+ cleared, except for data, datalen and quotalen [see
-+ Documentation/security/keys.txt].
-+
-+ struct key_preparsed_payload {
-+ char *description;
-+ void *type_data[2];
-+ void *payload;
-+ const void *data;
-+ size_t datalen;
-+ size_t quotalen;
-+ };
-+
-+ The instantiation data is in a blob pointed to by data and is datalen in
-+ size. The parse() function is not permitted to change these two values at
-+ all, and shouldn't change any of the other values _unless_ they are
-+ recognise the blob format and will not return -EBADMSG to indicate it is
-+ not theirs.
-+
-+ If the parser is happy with the blob, it should propose a description for
-+ the key and attach it to ->description, ->type_data[0] should be set to
-+ point to the subtype to be used, ->payload should be set to point to the
-+ initialised data for that subtype, ->type_data[1] should point to a hex
-+ fingerprint and quotalen should be updated to indicate how much quota this
-+ key should account for.
-+
-+ When clearing up, the data attached to ->type_data[1] and ->description
-+ will be kfree()'d and the data attached to ->payload will be passed to the
-+ subtype's ->destroy() method to be disposed of. A module reference for
-+ the subtype pointed to by ->type_data[0] will be put.
-+
-+
-+ If the data format is not recognised, -EBADMSG should be returned. If it
-+ is recognised, but the key cannot for some reason be set up, some other
-+ negative error code should be returned. On success, 0 should be returned.
-+
-+ The key's fingerprint string may be partially matched upon. For a
-+ public-key algorithm such as RSA and DSA this will likely be a printable
-+ hex version of the key's fingerprint.
-+
-+Functions are provided to register and unregister parsers:
-+
-+ int register_asymmetric_key_parser(struct asymmetric_key_parser *parser);
-+ void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype);
-+
-+Parsers may not have the same name. The names are otherwise only used for
-+displaying in debugging messages.
---
-1.7.12.1
-
-
-From 0e450d75d1067b6f45f1f6b58a530a5d95144373 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 13 Sep 2012 15:17:21 +0100
-Subject: [PATCH 05/37] KEYS: Implement asymmetric key type
-
-Create a key type that can be used to represent an asymmetric key type for use
-in appropriate cryptographic operations, such as encryption, decryption,
-signature generation and signature verification.
-
-The key type is "asymmetric" and can provide access to a variety of
-cryptographic algorithms.
-
-Possibly, this would be better as "public_key" - but that has the disadvantage
-that "public key" is an overloaded term.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/Kconfig | 1 +
- crypto/Makefile | 1 +
- crypto/asymmetric_keys/Kconfig | 13 +++
- crypto/asymmetric_keys/Makefile | 7 ++
- crypto/asymmetric_keys/asymmetric_keys.h | 15 +++
- crypto/asymmetric_keys/asymmetric_type.c | 156 +++++++++++++++++++++++++++++++
- include/keys/asymmetric-subtype.h | 55 +++++++++++
- include/keys/asymmetric-type.h | 25 +++++
- 8 files changed, 273 insertions(+)
- create mode 100644 crypto/asymmetric_keys/Kconfig
- create mode 100644 crypto/asymmetric_keys/Makefile
- create mode 100644 crypto/asymmetric_keys/asymmetric_keys.h
- create mode 100644 crypto/asymmetric_keys/asymmetric_type.c
- create mode 100644 include/keys/asymmetric-subtype.h
- create mode 100644 include/keys/asymmetric-type.h
-
-diff --git a/crypto/Kconfig b/crypto/Kconfig
-index a323805..1ca0b24 100644
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -1043,5 +1043,6 @@ config CRYPTO_USER_API_SKCIPHER
- key cipher algorithms.
-
- source "drivers/crypto/Kconfig"
-+source crypto/asymmetric_keys/Kconfig
-
- endif # if CRYPTO
-diff --git a/crypto/Makefile b/crypto/Makefile
-index 30f33d6..ced472e 100644
---- a/crypto/Makefile
-+++ b/crypto/Makefile
-@@ -96,3 +96,4 @@ obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
- #
- obj-$(CONFIG_XOR_BLOCKS) += xor.o
- obj-$(CONFIG_ASYNC_CORE) += async_tx/
-+obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
-diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
-new file mode 100644
-index 0000000..cad29b3
---- /dev/null
-+++ b/crypto/asymmetric_keys/Kconfig
-@@ -0,0 +1,13 @@
-+menuconfig ASYMMETRIC_KEY_TYPE
-+ tristate "Asymmetric (public-key cryptographic) key type"
-+ depends on KEYS
-+ help
-+ This option provides support for a key type that holds the data for
-+ the asymmetric keys used for public key cryptographic operations such
-+ as encryption, decryption, signature generation and signature
-+ verification.
-+
-+if ASYMMETRIC_KEY_TYPE
-+
-+
-+endif # ASYMMETRIC_KEY_TYPE
-diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
-new file mode 100644
-index 0000000..b725bcc
---- /dev/null
-+++ b/crypto/asymmetric_keys/Makefile
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for asymmetric cryptographic keys
-+#
-+
-+obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
-+
-+asymmetric_keys-y := asymmetric_type.o
-diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
-new file mode 100644
-index 0000000..515b634
---- /dev/null
-+++ b/crypto/asymmetric_keys/asymmetric_keys.h
-@@ -0,0 +1,15 @@
-+/* Internal definitions for asymmetric key type
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+static inline const char *asymmetric_key_id(const struct key *key)
-+{
-+ return key->type_data.p[1];
-+}
-diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
-new file mode 100644
-index 0000000..bfb0424
---- /dev/null
-+++ b/crypto/asymmetric_keys/asymmetric_type.c
-@@ -0,0 +1,156 @@
-+/* Asymmetric public-key cryptography key type
-+ *
-+ * See Documentation/security/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+#include <keys/asymmetric-subtype.h>
-+#include <linux/seq_file.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include "asymmetric_keys.h"
-+
-+MODULE_LICENSE("GPL");
-+
-+/*
-+ * Match asymmetric keys on (part of) their name
-+ * We have some shorthand methods for matching keys. We allow:
-+ *
-+ * "<desc>" - request a key by description
-+ * "id:<id>" - request a key matching the ID
-+ * "<subtype>:<id>" - request a key of a subtype
-+ */
-+static int asymmetric_key_match(const struct key *key, const void *description)
-+{
-+ const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
-+ const char *spec = description;
-+ const char *id, *kid;
-+ ptrdiff_t speclen;
-+ size_t idlen, kidlen;
-+
-+ if (!subtype || !spec || !*spec)
-+ return 0;
-+
-+ /* See if the full key description matches as is */
-+ if (key->description && strcmp(key->description, description) == 0)
-+ return 1;
-+
-+ /* All tests from here on break the criterion description into a
-+ * specifier, a colon and then an identifier.
-+ */
-+ id = strchr(spec, ':');
-+ if (!id)
-+ return 0;
-+
-+ speclen = id - spec;
-+ id++;
-+
-+ /* Anything after here requires a partial match on the ID string */
-+ kid = asymmetric_key_id(key);
-+ if (!kid)
-+ return 0;
-+
-+ idlen = strlen(id);
-+ kidlen = strlen(kid);
-+ if (idlen > kidlen)
-+ return 0;
-+
-+ kid += kidlen - idlen;
-+ if (strcasecmp(id, kid) != 0)
-+ return 0;
-+
-+ if (speclen == 2 &&
-+ memcmp(spec, "id", 2) == 0)
-+ return 1;
-+
-+ if (speclen == subtype->name_len &&
-+ memcmp(spec, subtype->name, speclen) == 0)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Describe the asymmetric key
-+ */
-+static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
-+{
-+ const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
-+ const char *kid = asymmetric_key_id(key);
-+ size_t n;
-+
-+ seq_puts(m, key->description);
-+
-+ if (subtype) {
-+ seq_puts(m, ": ");
-+ subtype->describe(key, m);
-+
-+ if (kid) {
-+ seq_putc(m, ' ');
-+ n = strlen(kid);
-+ if (n <= 8)
-+ seq_puts(m, kid);
-+ else
-+ seq_puts(m, kid + n - 8);
-+ }
-+
-+ seq_puts(m, " [");
-+ /* put something here to indicate the key's capabilities */
-+ seq_putc(m, ']');
-+ }
-+}
-+
-+/*
-+ * Instantiate a asymmetric_key defined key. The key was preparsed, so we just
-+ * have to transfer the data here.
-+ */
-+static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+/*
-+ * dispose of the data dangling from the corpse of a asymmetric key
-+ */
-+static void asymmetric_key_destroy(struct key *key)
-+{
-+ struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
-+ if (subtype) {
-+ subtype->destroy(key->payload.data);
-+ module_put(subtype->owner);
-+ key->type_data.p[0] = NULL;
-+ }
-+ kfree(key->type_data.p[1]);
-+ key->type_data.p[1] = NULL;
-+}
-+
-+struct key_type key_type_asymmetric = {
-+ .name = "asymmetric",
-+ .instantiate = asymmetric_key_instantiate,
-+ .match = asymmetric_key_match,
-+ .destroy = asymmetric_key_destroy,
-+ .describe = asymmetric_key_describe,
-+};
-+EXPORT_SYMBOL_GPL(key_type_asymmetric);
-+
-+/*
-+ * Module stuff
-+ */
-+static int __init asymmetric_key_init(void)
-+{
-+ return register_key_type(&key_type_asymmetric);
-+}
-+
-+static void __exit asymmetric_key_cleanup(void)
-+{
-+ unregister_key_type(&key_type_asymmetric);
-+}
-+
-+module_init(asymmetric_key_init);
-+module_exit(asymmetric_key_cleanup);
-diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h
-new file mode 100644
-index 0000000..4b840e8
---- /dev/null
-+++ b/include/keys/asymmetric-subtype.h
-@@ -0,0 +1,55 @@
-+/* Asymmetric public-key cryptography key subtype
-+ *
-+ * See Documentation/security/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _KEYS_ASYMMETRIC_SUBTYPE_H
-+#define _KEYS_ASYMMETRIC_SUBTYPE_H
-+
-+#include <linux/seq_file.h>
-+#include <keys/asymmetric-type.h>
-+
-+struct public_key_signature;
-+
-+/*
-+ * Keys of this type declare a subtype that indicates the handlers and
-+ * capabilities.
-+ */
-+struct asymmetric_key_subtype {
-+ struct module *owner;
-+ const char *name;
-+ unsigned short name_len; /* length of name */
-+
-+ /* Describe a key of this subtype for /proc/keys */
-+ void (*describe)(const struct key *key, struct seq_file *m);
-+
-+ /* Destroy a key of this subtype */
-+ void (*destroy)(void *payload);
-+
-+ /* Verify the signature on a key of this subtype (optional) */
-+ int (*verify_signature)(const struct key *key,
-+ const struct public_key_signature *sig);
-+};
-+
-+/**
-+ * asymmetric_key_subtype - Get the subtype from an asymmetric key
-+ * @key: The key of interest.
-+ *
-+ * Retrieves and returns the subtype pointer of the asymmetric key from the
-+ * type-specific data attached to the key.
-+ */
-+static inline
-+struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key)
-+{
-+ return key->type_data.p[0];
-+}
-+
-+#endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */
-diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
-new file mode 100644
-index 0000000..7dd4734
---- /dev/null
-+++ b/include/keys/asymmetric-type.h
-@@ -0,0 +1,25 @@
-+/* Asymmetric Public-key cryptography key type interface
-+ *
-+ * See Documentation/security/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _KEYS_ASYMMETRIC_TYPE_H
-+#define _KEYS_ASYMMETRIC_TYPE_H
-+
-+#include <linux/key-type.h>
-+
-+extern struct key_type key_type_asymmetric;
-+
-+/*
-+ * The payload is at the discretion of the subtype.
-+ */
-+
-+#endif /* _KEYS_ASYMMETRIC_TYPE_H */
---
-1.7.12.1
-
-
-From 6ec62201b26995d57fbd457469314bfc5653f2a0 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 13 Sep 2012 15:17:32 +0100
-Subject: [PATCH 06/37] KEYS: Asymmetric key pluggable data parsers
-
-The instantiation data passed to the asymmetric key type are expected to be
-formatted in some way, and there are several possible standard ways to format
-the data.
-
-The two obvious standards are OpenPGP keys and X.509 certificates. The latter
-is especially useful when dealing with UEFI, and the former might be useful
-when dealing with, say, eCryptfs.
-
-Further, it might be desirable to provide formatted blobs that indicate
-hardware is to be accessed to retrieve the keys or that the keys live
-unretrievably in a hardware store, but that the keys can be used by means of
-the hardware.
-
-From userspace, the keys can be loaded using the keyctl command, for example,
-an X.509 binary certificate:
-
- keyctl padd asymmetric foo @s <dhowells.pem
-
-or a PGP key:
-
- keyctl padd asymmetric bar @s <dhowells.pub
-
-or a pointer into the contents of the TPM:
-
- keyctl add asymmetric zebra "TPM:04982390582905f8" @s
-
-Inside the kernel, pluggable parsers register themselves and then get to
-examine the payload data to see if they can handle it. If they can, they get
-to:
-
- (1) Propose a name for the key, to be used it the name is "" or NULL.
-
- (2) Specify the key subtype.
-
- (3) Provide the data for the subtype.
-
-The key type asks the parser to do its stuff before a key is allocated and thus
-before the name is set. If successful, the parser stores the suggested data
-into the key_preparsed_payload struct, which will be either used (if the key is
-successfully created and instantiated or updated) or discarded.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/asymmetric_type.c | 120 ++++++++++++++++++++++++++++++-
- include/keys/asymmetric-parser.h | 37 ++++++++++
- 2 files changed, 156 insertions(+), 1 deletion(-)
- create mode 100644 include/keys/asymmetric-parser.h
-
-diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
-index bfb0424..cf80765 100644
---- a/crypto/asymmetric_keys/asymmetric_type.c
-+++ b/crypto/asymmetric_keys/asymmetric_type.c
-@@ -11,6 +11,7 @@
- * 2 of the Licence, or (at your option) any later version.
- */
- #include <keys/asymmetric-subtype.h>
-+#include <keys/asymmetric-parser.h>
- #include <linux/seq_file.h>
- #include <linux/module.h>
- #include <linux/slab.h>
-@@ -18,6 +19,9 @@
-
- MODULE_LICENSE("GPL");
-
-+static LIST_HEAD(asymmetric_key_parsers);
-+static DECLARE_RWSEM(asymmetric_key_parsers_sem);
-+
- /*
- * Match asymmetric keys on (part of) their name
- * We have some shorthand methods for matching keys. We allow:
-@@ -107,12 +111,79 @@ static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
- }
-
- /*
-+ * Preparse a asymmetric payload to get format the contents appropriately for the
-+ * internal payload to cut down on the number of scans of the data performed.
-+ *
-+ * We also generate a proposed description from the contents of the key that
-+ * can be used to name the key if the user doesn't want to provide one.
-+ */
-+static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
-+{
-+ struct asymmetric_key_parser *parser;
-+ int ret;
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ if (prep->datalen == 0)
-+ return -EINVAL;
-+
-+ down_read(&asymmetric_key_parsers_sem);
-+
-+ ret = -EBADMSG;
-+ list_for_each_entry(parser, &asymmetric_key_parsers, link) {
-+ pr_debug("Trying parser '%s'\n", parser->name);
-+
-+ ret = parser->parse(prep);
-+ if (ret != -EBADMSG) {
-+ pr_debug("Parser recognised the format (ret %d)\n",
-+ ret);
-+ break;
-+ }
-+ }
-+
-+ up_read(&asymmetric_key_parsers_sem);
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ret;
-+}
-+
-+/*
-+ * Clean up the preparse data
-+ */
-+static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
-+{
-+ struct asymmetric_key_subtype *subtype = prep->type_data[0];
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ if (subtype) {
-+ subtype->destroy(prep->payload);
-+ module_put(subtype->owner);
-+ }
-+ kfree(prep->type_data[1]);
-+ kfree(prep->description);
-+}
-+
-+/*
- * Instantiate a asymmetric_key defined key. The key was preparsed, so we just
- * have to transfer the data here.
- */
- static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
- {
-- return -EOPNOTSUPP;
-+ int ret;
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ ret = key_payload_reserve(key, prep->quotalen);
-+ if (ret == 0) {
-+ key->type_data.p[0] = prep->type_data[0];
-+ key->type_data.p[1] = prep->type_data[1];
-+ key->payload.data = prep->payload;
-+ prep->type_data[0] = NULL;
-+ prep->type_data[1] = NULL;
-+ prep->payload = NULL;
-+ }
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ret;
- }
-
- /*
-@@ -132,6 +203,8 @@ static void asymmetric_key_destroy(struct key *key)
-
- struct key_type key_type_asymmetric = {
- .name = "asymmetric",
-+ .preparse = asymmetric_key_preparse,
-+ .free_preparse = asymmetric_key_free_preparse,
- .instantiate = asymmetric_key_instantiate,
- .match = asymmetric_key_match,
- .destroy = asymmetric_key_destroy,
-@@ -139,6 +212,51 @@ struct key_type key_type_asymmetric = {
- };
- EXPORT_SYMBOL_GPL(key_type_asymmetric);
-
-+/**
-+ * register_asymmetric_key_parser - Register a asymmetric key blob parser
-+ * @parser: The parser to register
-+ */
-+int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
-+{
-+ struct asymmetric_key_parser *cursor;
-+ int ret;
-+
-+ down_write(&asymmetric_key_parsers_sem);
-+
-+ list_for_each_entry(cursor, &asymmetric_key_parsers, link) {
-+ if (strcmp(cursor->name, parser->name) == 0) {
-+ pr_err("Asymmetric key parser '%s' already registered\n",
-+ parser->name);
-+ ret = -EEXIST;
-+ goto out;
-+ }
-+ }
-+
-+ list_add_tail(&parser->link, &asymmetric_key_parsers);
-+
-+ pr_notice("Asymmetric key parser '%s' registered\n", parser->name);
-+ ret = 0;
-+
-+out:
-+ up_write(&asymmetric_key_parsers_sem);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(register_asymmetric_key_parser);
-+
-+/**
-+ * unregister_asymmetric_key_parser - Unregister a asymmetric key blob parser
-+ * @parser: The parser to unregister
-+ */
-+void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser)
-+{
-+ down_write(&asymmetric_key_parsers_sem);
-+ list_del(&parser->link);
-+ up_write(&asymmetric_key_parsers_sem);
-+
-+ pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name);
-+}
-+EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser);
-+
- /*
- * Module stuff
- */
-diff --git a/include/keys/asymmetric-parser.h b/include/keys/asymmetric-parser.h
-new file mode 100644
-index 0000000..09b3b48
---- /dev/null
-+++ b/include/keys/asymmetric-parser.h
-@@ -0,0 +1,37 @@
-+/* Asymmetric public-key cryptography data parser
-+ *
-+ * See Documentation/crypto/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _KEYS_ASYMMETRIC_PARSER_H
-+#define _KEYS_ASYMMETRIC_PARSER_H
-+
-+/*
-+ * Key data parser. Called during key instantiation.
-+ */
-+struct asymmetric_key_parser {
-+ struct list_head link;
-+ struct module *owner;
-+ const char *name;
-+
-+ /* Attempt to parse a key from the data blob passed to add_key() or
-+ * keyctl_instantiate(). Should also generate a proposed description
-+ * that the caller can optionally use for the key.
-+ *
-+ * Return EBADMSG if not recognised.
-+ */
-+ int (*parse)(struct key_preparsed_payload *prep);
-+};
-+
-+extern int register_asymmetric_key_parser(struct asymmetric_key_parser *);
-+extern void unregister_asymmetric_key_parser(struct asymmetric_key_parser *);
-+
-+#endif /* _KEYS_ASYMMETRIC_PARSER_H */
---
-1.7.12.1
-
-
-From 390ad626607322c6e4da8a2e6d2a4094e78b919a Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:24:55 +0100
-Subject: [PATCH 07/37] KEYS: Asymmetric public-key algorithm crypto key
- subtype
-
-Add a subtype for supporting asymmetric public-key encryption algorithms such
-as DSA (FIPS-186) and RSA (PKCS#1 / RFC1337).
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/Kconfig | 8 +++
- crypto/asymmetric_keys/Makefile | 2 +
- crypto/asymmetric_keys/public_key.c | 108 ++++++++++++++++++++++++++++++++++++
- crypto/asymmetric_keys/public_key.h | 28 ++++++++++
- include/crypto/public_key.h | 104 ++++++++++++++++++++++++++++++++++
- 5 files changed, 250 insertions(+)
- create mode 100644 crypto/asymmetric_keys/public_key.c
- create mode 100644 crypto/asymmetric_keys/public_key.h
- create mode 100644 include/crypto/public_key.h
-
-diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
-index cad29b3..bbfccaa 100644
---- a/crypto/asymmetric_keys/Kconfig
-+++ b/crypto/asymmetric_keys/Kconfig
-@@ -9,5 +9,13 @@ menuconfig ASYMMETRIC_KEY_TYPE
-
- if ASYMMETRIC_KEY_TYPE
-
-+config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
-+ tristate "Asymmetric public-key crypto algorithm subtype"
-+ select MPILIB
-+ help
-+ This option provides support for asymmetric public key type handling.
-+ If signature generation and/or verification are to be used,
-+ appropriate hash algorithms (such as SHA-1) must be available.
-+ ENOPKG will be reported if the requisite algorithm is unavailable.
-
- endif # ASYMMETRIC_KEY_TYPE
-diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
-index b725bcc..5ed46ee 100644
---- a/crypto/asymmetric_keys/Makefile
-+++ b/crypto/asymmetric_keys/Makefile
-@@ -5,3 +5,5 @@
- obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
-
- asymmetric_keys-y := asymmetric_type.o
-+
-+obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
-new file mode 100644
-index 0000000..cb2e291
---- /dev/null
-+++ b/crypto/asymmetric_keys/public_key.c
-@@ -0,0 +1,108 @@
-+/* In-software asymmetric public-key crypto subtype
-+ *
-+ * See Documentation/crypto/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#define pr_fmt(fmt) "PKEY: "fmt
-+#include <linux/module.h>
-+#include <linux/export.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/seq_file.h>
-+#include <keys/asymmetric-subtype.h>
-+#include "public_key.h"
-+
-+MODULE_LICENSE("GPL");
-+
-+const char *const pkey_algo[PKEY_ALGO__LAST] = {
-+ [PKEY_ALGO_DSA] = "DSA",
-+ [PKEY_ALGO_RSA] = "RSA",
-+};
-+EXPORT_SYMBOL_GPL(pkey_algo);
-+
-+const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
-+ [PKEY_HASH_MD4] = "md4",
-+ [PKEY_HASH_MD5] = "md5",
-+ [PKEY_HASH_SHA1] = "sha1",
-+ [PKEY_HASH_RIPE_MD_160] = "rmd160",
-+ [PKEY_HASH_SHA256] = "sha256",
-+ [PKEY_HASH_SHA384] = "sha384",
-+ [PKEY_HASH_SHA512] = "sha512",
-+ [PKEY_HASH_SHA224] = "sha224",
-+};
-+EXPORT_SYMBOL_GPL(pkey_hash_algo);
-+
-+const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = {
-+ [PKEY_ID_PGP] = "PGP",
-+ [PKEY_ID_X509] = "X509",
-+};
-+EXPORT_SYMBOL_GPL(pkey_id_type);
-+
-+/*
-+ * Provide a part of a description of the key for /proc/keys.
-+ */
-+static void public_key_describe(const struct key *asymmetric_key,
-+ struct seq_file *m)
-+{
-+ struct public_key *key = asymmetric_key->payload.data;
-+
-+ if (key)
-+ seq_printf(m, "%s.%s",
-+ pkey_id_type[key->id_type], key->algo->name);
-+}
-+
-+/*
-+ * Destroy a public key algorithm key.
-+ */
-+void public_key_destroy(void *payload)
-+{
-+ struct public_key *key = payload;
-+ int i;
-+
-+ if (key) {
-+ for (i = 0; i < ARRAY_SIZE(key->mpi); i++)
-+ mpi_free(key->mpi[i]);
-+ kfree(key);
-+ }
-+}
-+EXPORT_SYMBOL_GPL(public_key_destroy);
-+
-+/*
-+ * Verify a signature using a public key.
-+ */
-+static int public_key_verify_signature(const struct key *key,
-+ const struct public_key_signature *sig)
-+{
-+ const struct public_key *pk = key->payload.data;
-+
-+ if (!pk->algo->verify_signature)
-+ return -ENOTSUPP;
-+
-+ if (sig->nr_mpi != pk->algo->n_sig_mpi) {
-+ pr_debug("Signature has %u MPI not %u\n",
-+ sig->nr_mpi, pk->algo->n_sig_mpi);
-+ return -EINVAL;
-+ }
-+
-+ return pk->algo->verify_signature(pk, sig);
-+}
-+
-+/*
-+ * Public key algorithm asymmetric key subtype
-+ */
-+struct asymmetric_key_subtype public_key_subtype = {
-+ .owner = THIS_MODULE,
-+ .name = "public_key",
-+ .describe = public_key_describe,
-+ .destroy = public_key_destroy,
-+ .verify_signature = public_key_verify_signature,
-+};
-+EXPORT_SYMBOL_GPL(public_key_subtype);
-diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
-new file mode 100644
-index 0000000..1f86aad
---- /dev/null
-+++ b/crypto/asymmetric_keys/public_key.h
-@@ -0,0 +1,28 @@
-+/* Public key algorithm internals
-+ *
-+ * See Documentation/crypto/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <crypto/public_key.h>
-+
-+extern struct asymmetric_key_subtype public_key_subtype;
-+
-+/*
-+ * Public key algorithm definition.
-+ */
-+struct public_key_algorithm {
-+ const char *name;
-+ u8 n_pub_mpi; /* Number of MPIs in public key */
-+ u8 n_sec_mpi; /* Number of MPIs in secret key */
-+ u8 n_sig_mpi; /* Number of MPIs in a signature */
-+ int (*verify_signature)(const struct public_key *key,
-+ const struct public_key_signature *sig);
-+};
-diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
-new file mode 100644
-index 0000000..4b8b6c1
---- /dev/null
-+++ b/include/crypto/public_key.h
-@@ -0,0 +1,104 @@
-+/* Asymmetric public-key algorithm definitions
-+ *
-+ * See Documentation/crypto/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_PUBLIC_KEY_H
-+#define _LINUX_PUBLIC_KEY_H
-+
-+#include <linux/mpi.h>
-+
-+enum pkey_algo {
-+ PKEY_ALGO_DSA,
-+ PKEY_ALGO_RSA,
-+ PKEY_ALGO__LAST
-+};
-+
-+extern const char *const pkey_algo[PKEY_ALGO__LAST];
-+
-+enum pkey_hash_algo {
-+ PKEY_HASH_MD4,
-+ PKEY_HASH_MD5,
-+ PKEY_HASH_SHA1,
-+ PKEY_HASH_RIPE_MD_160,
-+ PKEY_HASH_SHA256,
-+ PKEY_HASH_SHA384,
-+ PKEY_HASH_SHA512,
-+ PKEY_HASH_SHA224,
-+ PKEY_HASH__LAST
-+};
-+
-+extern const char *const pkey_hash_algo[PKEY_HASH__LAST];
-+
-+enum pkey_id_type {
-+ PKEY_ID_PGP, /* OpenPGP generated key ID */
-+ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
-+ PKEY_ID_TYPE__LAST
-+};
-+
-+extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST];
-+
-+/*
-+ * Cryptographic data for the public-key subtype of the asymmetric key type.
-+ *
-+ * Note that this may include private part of the key as well as the public
-+ * part.
-+ */
-+struct public_key {
-+ const struct public_key_algorithm *algo;
-+ u8 capabilities;
-+#define PKEY_CAN_ENCRYPT 0x01
-+#define PKEY_CAN_DECRYPT 0x02
-+#define PKEY_CAN_SIGN 0x04
-+#define PKEY_CAN_VERIFY 0x08
-+ enum pkey_id_type id_type : 8;
-+ union {
-+ MPI mpi[5];
-+ struct {
-+ MPI p; /* DSA prime */
-+ MPI q; /* DSA group order */
-+ MPI g; /* DSA group generator */
-+ MPI y; /* DSA public-key value = g^x mod p */
-+ MPI x; /* DSA secret exponent (if present) */
-+ } dsa;
-+ struct {
-+ MPI n; /* RSA public modulus */
-+ MPI e; /* RSA public encryption exponent */
-+ MPI d; /* RSA secret encryption exponent (if present) */
-+ MPI p; /* RSA secret prime (if present) */
-+ MPI q; /* RSA secret prime (if present) */
-+ } rsa;
-+ };
-+};
-+
-+extern void public_key_destroy(void *payload);
-+
-+/*
-+ * Public key cryptography signature data
-+ */
-+struct public_key_signature {
-+ u8 *digest;
-+ u8 digest_size; /* Number of bytes in digest */
-+ u8 nr_mpi; /* Occupancy of mpi[] */
-+ enum pkey_hash_algo pkey_hash_algo : 8;
-+ union {
-+ MPI mpi[2];
-+ struct {
-+ MPI s; /* m^d mod n */
-+ } rsa;
-+ struct {
-+ MPI r;
-+ MPI s;
-+ } dsa;
-+ };
-+};
-+
-+#endif /* _LINUX_PUBLIC_KEY_H */
---
-1.7.12.1
-
-
-From 13d9a26663043faaa37dbe6c2f214ceef5f00b05 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:25:04 +0100
-Subject: [PATCH 08/37] KEYS: Provide signature verification with an
- asymmetric key
-
-Provide signature verification using an asymmetric-type key to indicate the
-public key to be used.
-
-The API is a single function that can be found in crypto/public_key.h:
-
- int verify_signature(const struct key *key,
- const struct public_key_signature *sig)
-
-The first argument is the appropriate key to be used and the second argument
-is the parsed signature data:
-
- struct public_key_signature {
- u8 *digest;
- u16 digest_size;
- enum pkey_hash_algo pkey_hash_algo : 8;
- union {
- MPI mpi[2];
- struct {
- MPI s; /* m^d mod n */
- } rsa;
- struct {
- MPI r;
- MPI s;
- } dsa;
- };
- };
-
-This should be filled in prior to calling the function. The hash algorithm
-should already have been called and the hash finalised and the output should
-be in a buffer pointed to by the 'digest' member.
-
-Any extra data to be added to the hash by the hash format (eg. PGP) should
-have been added by the caller prior to finalising the hash.
-
-It is assumed that the signature is made up of a number of MPI values. If an
-algorithm becomes available for which this is not the case, the above structure
-will have to change.
-
-It is also assumed that it will have been checked that the signature algorithm
-matches the key algorithm.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/Makefile | 2 +-
- crypto/asymmetric_keys/signature.c | 49 ++++++++++++++++++++++++++++++++++++++
- include/crypto/public_key.h | 4 ++++
- 3 files changed, 54 insertions(+), 1 deletion(-)
- create mode 100644 crypto/asymmetric_keys/signature.c
-
-diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
-index 5ed46ee..8dcdf0c 100644
---- a/crypto/asymmetric_keys/Makefile
-+++ b/crypto/asymmetric_keys/Makefile
-@@ -4,6 +4,6 @@
-
- obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
-
--asymmetric_keys-y := asymmetric_type.o
-+asymmetric_keys-y := asymmetric_type.o signature.o
-
- obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
-new file mode 100644
-index 0000000..50b3f88
---- /dev/null
-+++ b/crypto/asymmetric_keys/signature.c
-@@ -0,0 +1,49 @@
-+/* Signature verification with an asymmetric key
-+ *
-+ * See Documentation/security/asymmetric-keys.txt
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <keys/asymmetric-subtype.h>
-+#include <linux/module.h>
-+#include <linux/err.h>
-+#include <crypto/public_key.h>
-+#include "asymmetric_keys.h"
-+
-+/**
-+ * verify_signature - Initiate the use of an asymmetric key to verify a signature
-+ * @key: The asymmetric key to verify against
-+ * @sig: The signature to check
-+ *
-+ * Returns 0 if successful or else an error.
-+ */
-+int verify_signature(const struct key *key,
-+ const struct public_key_signature *sig)
-+{
-+ const struct asymmetric_key_subtype *subtype;
-+ int ret;
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ if (key->type != &key_type_asymmetric)
-+ return -EINVAL;
-+ subtype = asymmetric_key_subtype(key);
-+ if (!subtype ||
-+ !key->payload.data)
-+ return -EINVAL;
-+ if (!subtype->verify_signature)
-+ return -ENOTSUPP;
-+
-+ ret = subtype->verify_signature(key, sig);
-+
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(verify_signature);
-diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
-index 4b8b6c1..f5b0224 100644
---- a/include/crypto/public_key.h
-+++ b/include/crypto/public_key.h
-@@ -101,4 +101,8 @@ struct public_key_signature {
- };
- };
-
-+struct key;
-+extern int verify_signature(const struct key *key,
-+ const struct public_key_signature *sig);
-+
- #endif /* _LINUX_PUBLIC_KEY_H */
---
-1.7.12.1
-
-
-From 3d379de76f21782c611b7d409d7374b82bc90220 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:25:22 +0100
-Subject: [PATCH 09/37] MPILIB: Reinstate mpi_cmp[_ui]() and export for RSA
- signature verification
-
-Reinstate and export mpi_cmp() and mpi_cmp_ui() from the MPI library for use by
-RSA signature verification as per RFC3447 section 5.2.2 step 1.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- lib/mpi/Makefile | 1 +
- lib/mpi/mpi-cmp.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 71 insertions(+)
- create mode 100644 lib/mpi/mpi-cmp.c
-
-diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile
-index 45ca90a..019a68c 100644
---- a/lib/mpi/Makefile
-+++ b/lib/mpi/Makefile
-@@ -14,6 +14,7 @@ mpi-y = \
- generic_mpih-add1.o \
- mpicoder.o \
- mpi-bit.o \
-+ mpi-cmp.o \
- mpih-cmp.o \
- mpih-div.o \
- mpih-mul.o \
-diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c
-new file mode 100644
-index 0000000..1871e7b
---- /dev/null
-+++ b/lib/mpi/mpi-cmp.c
-@@ -0,0 +1,70 @@
-+/* mpi-cmp.c - MPI functions
-+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
-+ *
-+ * This file is part of GnuPG.
-+ *
-+ * GnuPG is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GnuPG is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-+ */
-+
-+#include "mpi-internal.h"
-+
-+int mpi_cmp_ui(MPI u, unsigned long v)
-+{
-+ mpi_limb_t limb = v;
-+
-+ mpi_normalize(u);
-+ if (!u->nlimbs && !limb)
-+ return 0;
-+ if (u->sign)
-+ return -1;
-+ if (u->nlimbs > 1)
-+ return 1;
-+
-+ if (u->d[0] == limb)
-+ return 0;
-+ else if (u->d[0] > limb)
-+ return 1;
-+ else
-+ return -1;
-+}
-+EXPORT_SYMBOL_GPL(mpi_cmp_ui);
-+
-+int mpi_cmp(MPI u, MPI v)
-+{
-+ mpi_size_t usize, vsize;
-+ int cmp;
-+
-+ mpi_normalize(u);
-+ mpi_normalize(v);
-+ usize = u->nlimbs;
-+ vsize = v->nlimbs;
-+ if (!u->sign && v->sign)
-+ return 1;
-+ if (u->sign && !v->sign)
-+ return -1;
-+ if (usize != vsize && !u->sign && !v->sign)
-+ return usize - vsize;
-+ if (usize != vsize && u->sign && v->sign)
-+ return vsize + usize;
-+ if (!usize)
-+ return 0;
-+ cmp = mpihelp_cmp(u->d, v->d, usize);
-+ if (!cmp)
-+ return 0;
-+ if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0))
-+ return 1;
-+ return -1;
-+}
-+EXPORT_SYMBOL_GPL(mpi_cmp);
---
-1.7.12.1
-
-
-From b872c7db2ce34b5f051d1c38216843a1f796aa86 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:25:40 +0100
-Subject: [PATCH 10/37] RSA: Implement signature verification algorithm
- [PKCS#1 / RFC3447]
-
-Implement RSA public key cryptography [PKCS#1 / RFC3447]. At this time, only
-the signature verification algorithm is supported. This uses the asymmetric
-public key subtype to hold its key data.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/Kconfig | 7 +
- crypto/asymmetric_keys/Makefile | 1 +
- crypto/asymmetric_keys/public_key.h | 2 +
- crypto/asymmetric_keys/rsa.c | 269 ++++++++++++++++++++++++++++++++++++
- 4 files changed, 279 insertions(+)
- create mode 100644 crypto/asymmetric_keys/rsa.c
-
-diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
-index bbfccaa..561759d 100644
---- a/crypto/asymmetric_keys/Kconfig
-+++ b/crypto/asymmetric_keys/Kconfig
-@@ -18,4 +18,11 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
- appropriate hash algorithms (such as SHA-1) must be available.
- ENOPKG will be reported if the requisite algorithm is unavailable.
-
-+config PUBLIC_KEY_ALGO_RSA
-+ tristate "RSA public-key algorithm"
-+ depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
-+ select MPILIB_EXTRA
-+ help
-+ This option enables support for the RSA algorithm (PKCS#1, RFC3447).
-+
- endif # ASYMMETRIC_KEY_TYPE
-diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
-index 8dcdf0c..7c92691 100644
---- a/crypto/asymmetric_keys/Makefile
-+++ b/crypto/asymmetric_keys/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
- asymmetric_keys-y := asymmetric_type.o signature.o
-
- obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-+obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
-diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
-index 1f86aad..5e5e356 100644
---- a/crypto/asymmetric_keys/public_key.h
-+++ b/crypto/asymmetric_keys/public_key.h
-@@ -26,3 +26,5 @@ struct public_key_algorithm {
- int (*verify_signature)(const struct public_key *key,
- const struct public_key_signature *sig);
- };
-+
-+extern const struct public_key_algorithm RSA_public_key_algorithm;
-diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
-new file mode 100644
-index 0000000..9b31ee2
---- /dev/null
-+++ b/crypto/asymmetric_keys/rsa.c
-@@ -0,0 +1,269 @@
-+/* RSA asymmetric public-key algorithm [RFC3447]
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#define pr_fmt(fmt) "RSA: "fmt
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include "public_key.h"
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("RSA Public Key Algorithm");
-+
-+#define kenter(FMT, ...) \
-+ pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__)
-+#define kleave(FMT, ...) \
-+ pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
-+
-+/*
-+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
-+ */
-+static const u8 RSA_digest_info_MD5[] = {
-+ 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
-+ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */
-+ 0x05, 0x00, 0x04, 0x10
-+};
-+
-+static const u8 RSA_digest_info_SHA1[] = {
-+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-+ 0x2B, 0x0E, 0x03, 0x02, 0x1A,
-+ 0x05, 0x00, 0x04, 0x14
-+};
-+
-+static const u8 RSA_digest_info_RIPE_MD_160[] = {
-+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-+ 0x2B, 0x24, 0x03, 0x02, 0x01,
-+ 0x05, 0x00, 0x04, 0x14
-+};
-+
-+static const u8 RSA_digest_info_SHA224[] = {
-+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
-+ 0x05, 0x00, 0x04, 0x1C
-+};
-+
-+static const u8 RSA_digest_info_SHA256[] = {
-+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-+ 0x05, 0x00, 0x04, 0x20
-+};
-+
-+static const u8 RSA_digest_info_SHA384[] = {
-+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
-+ 0x05, 0x00, 0x04, 0x30
-+};
-+
-+static const u8 RSA_digest_info_SHA512[] = {
-+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
-+ 0x05, 0x00, 0x04, 0x40
-+};
-+
-+static const struct {
-+ const u8 *data;
-+ size_t size;
-+} RSA_ASN1_templates[PKEY_HASH__LAST] = {
-+#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
-+ [PKEY_HASH_MD5] = _(MD5),
-+ [PKEY_HASH_SHA1] = _(SHA1),
-+ [PKEY_HASH_RIPE_MD_160] = _(RIPE_MD_160),
-+ [PKEY_HASH_SHA256] = _(SHA256),
-+ [PKEY_HASH_SHA384] = _(SHA384),
-+ [PKEY_HASH_SHA512] = _(SHA512),
-+ [PKEY_HASH_SHA224] = _(SHA224),
-+#undef _
-+};
-+
-+/*
-+ * RSAVP1() function [RFC3447 sec 5.2.2]
-+ */
-+static int RSAVP1(const struct public_key *key, MPI s, MPI *_m)
-+{
-+ MPI m;
-+ int ret;
-+
-+ /* (1) Validate 0 <= s < n */
-+ if (mpi_cmp_ui(s, 0) < 0) {
-+ kleave(" = -EBADMSG [s < 0]");
-+ return -EBADMSG;
-+ }
-+ if (mpi_cmp(s, key->rsa.n) >= 0) {
-+ kleave(" = -EBADMSG [s >= n]");
-+ return -EBADMSG;
-+ }
-+
-+ m = mpi_alloc(0);
-+ if (!m)
-+ return -ENOMEM;
-+
-+ /* (2) m = s^e mod n */
-+ ret = mpi_powm(m, s, key->rsa.e, key->rsa.n);
-+ if (ret < 0) {
-+ mpi_free(m);
-+ return ret;
-+ }
-+
-+ *_m = m;
-+ return 0;
-+}
-+
-+/*
-+ * Integer to Octet String conversion [RFC3447 sec 4.1]
-+ */
-+static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
-+{
-+ unsigned X_size, x_size;
-+ int X_sign;
-+ u8 *X;
-+
-+ /* Make sure the string is the right length. The number should begin
-+ * with { 0x00, 0x01, ... } so we have to account for 15 leading zero
-+ * bits not being reported by MPI.
-+ */
-+ x_size = mpi_get_nbits(x);
-+ pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8);
-+ if (x_size != xLen * 8 - 15)
-+ return -ERANGE;
-+
-+ X = mpi_get_buffer(x, &X_size, &X_sign);
-+ if (!X)
-+ return -ENOMEM;
-+ if (X_sign < 0) {
-+ kfree(X);
-+ return -EBADMSG;
-+ }
-+ if (X_size != xLen - 1) {
-+ kfree(X);
-+ return -EBADMSG;
-+ }
-+
-+ *_X = X;
-+ return 0;
-+}
-+
-+/*
-+ * Perform the RSA signature verification.
-+ * @H: Value of hash of data and metadata
-+ * @EM: The computed signature value
-+ * @k: The size of EM (EM[0] is an invalid location but should hold 0x00)
-+ * @hash_size: The size of H
-+ * @asn1_template: The DigestInfo ASN.1 template
-+ * @asn1_size: Size of asm1_template[]
-+ */
-+static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
-+ const u8 *asn1_template, size_t asn1_size)
-+{
-+ unsigned PS_end, T_offset, i;
-+
-+ kenter(",,%zu,%zu,%zu", k, hash_size, asn1_size);
-+
-+ if (k < 2 + 1 + asn1_size + hash_size)
-+ return -EBADMSG;
-+
-+ /* Decode the EMSA-PKCS1-v1_5 */
-+ if (EM[1] != 0x01) {
-+ kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]);
-+ return -EBADMSG;
-+ }
-+
-+ T_offset = k - (asn1_size + hash_size);
-+ PS_end = T_offset - 1;
-+ if (EM[PS_end] != 0x00) {
-+ kleave(" = -EBADMSG [EM[T-1] == %02u]", EM[PS_end]);
-+ return -EBADMSG;
-+ }
-+
-+ for (i = 2; i < PS_end; i++) {
-+ if (EM[i] != 0xff) {
-+ kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]);
-+ return -EBADMSG;
-+ }
-+ }
-+
-+ if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
-+ kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
-+ return -EBADMSG;
-+ }
-+
-+ if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
-+ kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
-+ return -EKEYREJECTED;
-+ }
-+
-+ kleave(" = 0");
-+ return 0;
-+}
-+
-+/*
-+ * Perform the verification step [RFC3447 sec 8.2.2].
-+ */
-+static int RSA_verify_signature(const struct public_key *key,
-+ const struct public_key_signature *sig)
-+{
-+ size_t tsize;
-+ int ret;
-+
-+ /* Variables as per RFC3447 sec 8.2.2 */
-+ const u8 *H = sig->digest;
-+ u8 *EM = NULL;
-+ MPI m = NULL;
-+ size_t k;
-+
-+ kenter("");
-+
-+ if (!RSA_ASN1_templates[sig->pkey_hash_algo].data)
-+ return -ENOTSUPP;
-+
-+ /* (1) Check the signature size against the public key modulus size */
-+ k = (mpi_get_nbits(key->rsa.n) + 7) / 8;
-+
-+ tsize = (mpi_get_nbits(sig->rsa.s) + 7) / 8;
-+ pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize);
-+ if (tsize != k) {
-+ ret = -EBADMSG;
-+ goto error;
-+ }
-+
-+ /* (2b) Apply the RSAVP1 verification primitive to the public key */
-+ ret = RSAVP1(key, sig->rsa.s, &m);
-+ if (ret < 0)
-+ goto error;
-+
-+ /* (2c) Convert the message representative (m) to an encoded message
-+ * (EM) of length k octets.
-+ *
-+ * NOTE! The leading zero byte is suppressed by MPI, so we pass a
-+ * pointer to the _preceding_ byte to RSA_verify()!
-+ */
-+ ret = RSA_I2OSP(m, k, &EM);
-+ if (ret < 0)
-+ goto error;
-+
-+ ret = RSA_verify(H, EM - 1, k, sig->digest_size,
-+ RSA_ASN1_templates[sig->pkey_hash_algo].data,
-+ RSA_ASN1_templates[sig->pkey_hash_algo].size);
-+
-+error:
-+ kfree(EM);
-+ mpi_free(m);
-+ kleave(" = %d", ret);
-+ return ret;
-+}
-+
-+const struct public_key_algorithm RSA_public_key_algorithm = {
-+ .name = "RSA",
-+ .n_pub_mpi = 2,
-+ .n_sec_mpi = 3,
-+ .n_sig_mpi = 1,
-+ .verify_signature = RSA_verify_signature,
-+};
-+EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
---
-1.7.12.1
-
-
-From 362af238a35e095094b3f5a228cf2c0f60c10cd9 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:28:05 +0100
-Subject: [PATCH 11/37] RSA: Fix signature verification for shorter signatures
-
-gpg can produce a signature file where length of signature is less than the
-modulus size because the amount of space an MPI takes up is kept as low as
-possible by discarding leading zeros. This regularly happens for several
-modules during the build.
-
-Fix it by relaxing check in RSA verification code.
-
-Thanks to Tomas Mraz and Miloslav Trmac for help.
-
-Signed-off-by: Milan Broz <mbroz@redhat.com>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/rsa.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
-index 9b31ee2..4a6a069 100644
---- a/crypto/asymmetric_keys/rsa.c
-+++ b/crypto/asymmetric_keys/rsa.c
-@@ -224,15 +224,23 @@ static int RSA_verify_signature(const struct public_key *key,
- return -ENOTSUPP;
-
- /* (1) Check the signature size against the public key modulus size */
-- k = (mpi_get_nbits(key->rsa.n) + 7) / 8;
-+ k = mpi_get_nbits(key->rsa.n);
-+ tsize = mpi_get_nbits(sig->rsa.s);
-
-- tsize = (mpi_get_nbits(sig->rsa.s) + 7) / 8;
-+ /* According to RFC 4880 sec 3.2, length of MPI is computed starting
-+ * from most significant bit. So the RFC 3447 sec 8.2.2 size check
-+ * must be relaxed to conform with shorter signatures - so we fail here
-+ * only if signature length is longer than modulus size.
-+ */
- pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize);
-- if (tsize != k) {
-+ if (k < tsize) {
- ret = -EBADMSG;
- goto error;
- }
-
-+ /* Round up and convert to octets */
-+ k = (k + 7) / 8;
-+
- /* (2b) Apply the RSAVP1 verification primitive to the public key */
- ret = RSAVP1(key, sig->rsa.s, &m);
- if (ret < 0)
---
-1.7.12.1
-
-
-From 81451f08c7db892e06144cf3bc89746e68269624 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:30:46 +0100
-Subject: [PATCH 12/37] X.509: Implement simple static OID registry
-
-Implement a simple static OID registry that allows the mapping of an encoded
-OID to an enum value for ease of use.
-
-The OID registry index enum appears in the:
-
- linux/oid_registry.h
-
-header file. A script generates the registry from lines in the header file
-that look like:
-
- <sp*>OID_foo,<sp*>/*<sp*>1.2.3.4<sp*>*/
-
-The actual OID is taken to be represented by the numbers with interpolated
-dots in the comment.
-
-All other lines in the header are ignored.
-
-The registry is queries by calling:
-
- OID look_up_oid(const void *data, size_t datasize);
-
-This returns a number from the registry enum representing the OID if found or
-OID__NR if not.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/linux/oid_registry.h | 90 +++++++++++++++++++
- lib/.gitignore | 2 +-
- lib/Kconfig | 5 ++
- lib/Makefile | 16 ++++
- lib/build_OID_registry | 209 +++++++++++++++++++++++++++++++++++++++++++
- lib/oid_registry.c | 89 ++++++++++++++++++
- 6 files changed, 410 insertions(+), 1 deletion(-)
- create mode 100644 include/linux/oid_registry.h
- create mode 100755 lib/build_OID_registry
- create mode 100644 lib/oid_registry.c
-
-diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
-new file mode 100644
-index 0000000..5928546
---- /dev/null
-+++ b/include/linux/oid_registry.h
-@@ -0,0 +1,90 @@
-+/* ASN.1 Object identifier (OID) registry
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_OID_REGISTRY_H
-+#define _LINUX_OID_REGISTRY_H
-+
-+#include <linux/types.h>
-+
-+/*
-+ * OIDs are turned into these values if possible, or OID__NR if not held here.
-+ *
-+ * NOTE! Do not mess with the format of each line as this is read by
-+ * build_OID_registry.pl to generate the data for look_up_OID().
-+ */
-+enum OID {
-+ OID_id_dsa_with_sha1, /* 1.2.840.10030.4.3 */
-+ OID_id_dsa, /* 1.2.840.10040.4.1 */
-+ OID_id_ecdsa_with_sha1, /* 1.2.840.10045.4.1 */
-+ OID_id_ecPublicKey, /* 1.2.840.10045.2.1 */
-+
-+ /* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
-+ OID_rsaEncryption, /* 1.2.840.113549.1.1.1 */
-+ OID_md2WithRSAEncryption, /* 1.2.840.113549.1.1.2 */
-+ OID_md3WithRSAEncryption, /* 1.2.840.113549.1.1.3 */
-+ OID_md4WithRSAEncryption, /* 1.2.840.113549.1.1.4 */
-+ OID_sha1WithRSAEncryption, /* 1.2.840.113549.1.1.5 */
-+ OID_sha256WithRSAEncryption, /* 1.2.840.113549.1.1.11 */
-+ OID_sha384WithRSAEncryption, /* 1.2.840.113549.1.1.12 */
-+ OID_sha512WithRSAEncryption, /* 1.2.840.113549.1.1.13 */
-+ OID_sha224WithRSAEncryption, /* 1.2.840.113549.1.1.14 */
-+ /* PKCS#7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)} */
-+ OID_data, /* 1.2.840.113549.1.7.1 */
-+ OID_signed_data, /* 1.2.840.113549.1.7.2 */
-+ /* PKCS#9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)} */
-+ OID_email_address, /* 1.2.840.113549.1.9.1 */
-+ OID_content_type, /* 1.2.840.113549.1.9.3 */
-+ OID_messageDigest, /* 1.2.840.113549.1.9.4 */
-+ OID_signingTime, /* 1.2.840.113549.1.9.5 */
-+ OID_smimeCapabilites, /* 1.2.840.113549.1.9.15 */
-+ OID_smimeAuthenticatedAttrs, /* 1.2.840.113549.1.9.16.2.11 */
-+
-+ /* {iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2)} */
-+ OID_md2, /* 1.2.840.113549.2.2 */
-+ OID_md4, /* 1.2.840.113549.2.4 */
-+ OID_md5, /* 1.2.840.113549.2.5 */
-+
-+ OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */
-+ OID_msOutlookExpress, /* 1.3.6.1.4.1.311.16.4 */
-+ OID_sha1, /* 1.3.14.3.2.26 */
-+
-+ /* Distinguished Name attribute IDs [RFC 2256] */
-+ OID_commonName, /* 2.5.4.3 */
-+ OID_surname, /* 2.5.4.4 */
-+ OID_countryName, /* 2.5.4.6 */
-+ OID_locality, /* 2.5.4.7 */
-+ OID_stateOrProvinceName, /* 2.5.4.8 */
-+ OID_organizationName, /* 2.5.4.10 */
-+ OID_organizationUnitName, /* 2.5.4.11 */
-+ OID_title, /* 2.5.4.12 */
-+ OID_description, /* 2.5.4.13 */
-+ OID_name, /* 2.5.4.41 */
-+ OID_givenName, /* 2.5.4.42 */
-+ OID_initials, /* 2.5.4.43 */
-+ OID_generationalQualifier, /* 2.5.4.44 */
-+
-+ /* Certificate extension IDs */
-+ OID_subjectKeyIdentifier, /* 2.5.29.14 */
-+ OID_keyUsage, /* 2.5.29.15 */
-+ OID_subjectAltName, /* 2.5.29.17 */
-+ OID_issuerAltName, /* 2.5.29.18 */
-+ OID_basicConstraints, /* 2.5.29.19 */
-+ OID_crlDistributionPoints, /* 2.5.29.31 */
-+ OID_certPolicies, /* 2.5.29.32 */
-+ OID_authorityKeyIdentifier, /* 2.5.29.35 */
-+ OID_extKeyUsage, /* 2.5.29.37 */
-+
-+ OID__NR
-+};
-+
-+extern enum OID look_up_OID(const void *data, size_t datasize);
-+
-+#endif /* _LINUX_OID_REGISTRY_H */
-diff --git a/lib/.gitignore b/lib/.gitignore
-index 3bef1ea..09aae85 100644
---- a/lib/.gitignore
-+++ b/lib/.gitignore
-@@ -3,4 +3,4 @@
- #
- gen_crc32table
- crc32table.h
--
-+oid_registry_data.c
-diff --git a/lib/Kconfig b/lib/Kconfig
-index bb94c1b..4b31a46 100644
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -396,4 +396,9 @@ config SIGNATURE
- config LIBFDT
- bool
-
-+config OID_REGISTRY
-+ tristate
-+ help
-+ Enable fast lookup object identifier registry.
-+
- endmenu
-diff --git a/lib/Makefile b/lib/Makefile
-index 42d283e..b042896 100644
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -150,3 +150,19 @@ quiet_cmd_crc32 = GEN $@
-
- $(obj)/crc32table.h: $(obj)/gen_crc32table
- $(call cmd,crc32)
-+
-+#
-+# Build a fast OID lookip registry from include/linux/oid_registry.h
-+#
-+obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
-+
-+$(obj)/oid_registry.c: $(obj)/oid_registry_data.c
-+
-+$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
-+ $(src)/build_OID_registry
-+ $(call cmd,build_OID_registry)
-+
-+quiet_cmd_build_OID_registry = GEN $@
-+ cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@
-+
-+clean-files += oid_registry_data.c
-diff --git a/lib/build_OID_registry b/lib/build_OID_registry
-new file mode 100755
-index 0000000..dfbdaab
---- /dev/null
-+++ b/lib/build_OID_registry
-@@ -0,0 +1,209 @@
-+#!/usr/bin/perl -w
-+#
-+# Build a static ASN.1 Object Identified (OID) registry
-+#
-+# Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+# Written by David Howells (dhowells@redhat.com)
-+#
-+# This program is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU General Public Licence
-+# as published by the Free Software Foundation; either version
-+# 2 of the Licence, or (at your option) any later version.
-+#
-+
-+use strict;
-+
-+my @names = ();
-+my @oids = ();
-+
-+if ($#ARGV != 1) {
-+ print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
-+ exit(2);
-+}
-+
-+#
-+# Open the file to read from
-+#
-+open IN_FILE, "<$ARGV[0]" || die;
-+while (<IN_FILE>) {
-+ chomp;
-+ if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) {
-+ push @names, $1;
-+ push @oids, $2;
-+ }
-+}
-+close IN_FILE || die;
-+
-+#
-+# Open the files to write into
-+#
-+open C_FILE, ">$ARGV[1]" or die;
-+print C_FILE "/*\n";
-+print C_FILE " * Automatically generated by ", $0, ". Do not edit\n";
-+print C_FILE " */\n";
-+
-+#
-+# Split the data up into separate lists and also determine the lengths of the
-+# encoded data arrays.
-+#
-+my @indices = ();
-+my @lengths = ();
-+my $total_length = 0;
-+
-+print "Compiling ", $#names + 1, " OIDs\n";
-+
-+for (my $i = 0; $i <= $#names; $i++) {
-+ my $name = $names[$i];
-+ my $oid = $oids[$i];
-+
-+ my @components = split(/[.]/, $oid);
-+
-+ # Determine the encoded length of this OID
-+ my $size = $#components;
-+ for (my $loop = 2; $loop <= $#components; $loop++) {
-+ my $c = $components[$loop];
-+
-+ # We will base128 encode the number
-+ my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
-+ $tmp = int($tmp / 7);
-+ $size += $tmp;
-+ }
-+ push @lengths, $size;
-+ push @indices, $total_length;
-+ $total_length += $size;
-+}
-+
-+#
-+# Emit the look-up-by-OID index table
-+#
-+print C_FILE "\n";
-+if ($total_length <= 255) {
-+ print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n";
-+} else {
-+ print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n";
-+}
-+for (my $i = 0; $i <= $#names; $i++) {
-+ print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n"
-+}
-+print C_FILE "\t[OID__NR] = ", $total_length, "\n";
-+print C_FILE "};\n";
-+
-+#
-+# Encode the OIDs
-+#
-+my @encoded_oids = ();
-+
-+for (my $i = 0; $i <= $#names; $i++) {
-+ my @octets = ();
-+
-+ my @components = split(/[.]/, $oids[$i]);
-+
-+ push @octets, $components[0] * 40 + $components[1];
-+
-+ for (my $loop = 2; $loop <= $#components; $loop++) {
-+ my $c = $components[$loop];
-+
-+ # Base128 encode the number
-+ my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
-+ $tmp = int($tmp / 7);
-+
-+ for (; $tmp > 0; $tmp--) {
-+ push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
-+ }
-+ push @octets, $c & 0x7f;
-+ }
-+
-+ push @encoded_oids, \@octets;
-+}
-+
-+#
-+# Create a hash value for each OID
-+#
-+my @hash_values = ();
-+for (my $i = 0; $i <= $#names; $i++) {
-+ my @octets = @{$encoded_oids[$i]};
-+
-+ my $hash = $#octets;
-+ foreach (@octets) {
-+ $hash += $_ * 33;
-+ }
-+
-+ $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash);
-+
-+ push @hash_values, $hash & 0xff;
-+}
-+
-+#
-+# Emit the OID data
-+#
-+print C_FILE "\n";
-+print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n";
-+for (my $i = 0; $i <= $#names; $i++) {
-+ my @octets = @{$encoded_oids[$i]};
-+ print C_FILE "\t";
-+ print C_FILE $_, ", " foreach (@octets);
-+ print C_FILE "\t// ", $names[$i];
-+ print C_FILE "\n";
-+}
-+print C_FILE "};\n";
-+
-+#
-+# Build the search index table (ordered by length then hash then content)
-+#
-+my @index_table = ( 0 .. $#names );
-+
-+@index_table = sort {
-+ my @octets_a = @{$encoded_oids[$a]};
-+ my @octets_b = @{$encoded_oids[$b]};
-+
-+ return $hash_values[$a] <=> $hash_values[$b]
-+ if ($hash_values[$a] != $hash_values[$b]);
-+ return $#octets_a <=> $#octets_b
-+ if ($#octets_a != $#octets_b);
-+ for (my $i = $#octets_a; $i >= 0; $i--) {
-+ return $octets_a[$i] <=> $octets_b[$i]
-+ if ($octets_a[$i] != $octets_b[$i]);
-+ }
-+ return 0;
-+
-+} @index_table;
-+
-+#
-+# Emit the search index and hash value table
-+#
-+print C_FILE "\n";
-+print C_FILE "static const struct {\n";
-+print C_FILE "\tunsigned char hash;\n";
-+if ($#names <= 255) {
-+ print C_FILE "\tenum OID oid : 8;\n";
-+} else {
-+ print C_FILE "\tenum OID oid : 16;\n";
-+}
-+print C_FILE "} oid_search_table[OID__NR] = {\n";
-+for (my $i = 0; $i <= $#names; $i++) {
-+ my @octets = @{$encoded_oids[$index_table[$i]]};
-+ printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ",
-+ $i,
-+ $hash_values[$index_table[$i]],
-+ $names[$index_table[$i]]);
-+ printf C_FILE "%02x", $_ foreach (@octets);
-+ print C_FILE "\n";
-+}
-+print C_FILE "};\n";
-+
-+#
-+# Emit the OID debugging name table
-+#
-+#print C_FILE "\n";
-+#print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n";
-+#
-+#for (my $i = 0; $i <= $#names; $i++) {
-+# print C_FILE "\t\"", $names[$i], "\",\n"
-+#}
-+#print C_FILE "\t\"Unknown-OID\"\n";
-+#print C_FILE "};\n";
-+
-+#
-+# Polish off
-+#
-+close C_FILE or die;
-diff --git a/lib/oid_registry.c b/lib/oid_registry.c
-new file mode 100644
-index 0000000..33cfd17
---- /dev/null
-+++ b/lib/oid_registry.c
-@@ -0,0 +1,89 @@
-+/* ASN.1 Object identifier (OID) registry
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <linux/export.h>
-+#include <linux/oid_registry.h>
-+#include "oid_registry_data.c"
-+
-+/**
-+ * look_up_OID - Find an OID registration for the specified data
-+ * @data: Binary representation of the OID
-+ * @datasize: Size of the binary representation
-+ */
-+enum OID look_up_OID(const void *data, size_t datasize)
-+{
-+ const unsigned char *octets = data;
-+ enum OID oid;
-+ unsigned char xhash;
-+ unsigned i, j, k, hash;
-+ size_t len;
-+
-+ /* Hash the OID data */
-+ hash = datasize - 1;
-+
-+ for (i = 0; i < datasize; i++)
-+ hash += octets[i] * 33;
-+ hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
-+ hash &= 0xff;
-+
-+ /* Binary search the OID registry. OIDs are stored in ascending order
-+ * of hash value then ascending order of size and then in ascending
-+ * order of reverse value.
-+ */
-+ i = 0;
-+ k = OID__NR;
-+ while (i < k) {
-+ j = (i + k) / 2;
-+
-+ xhash = oid_search_table[j].hash;
-+ if (xhash > hash) {
-+ k = j;
-+ continue;
-+ }
-+ if (xhash < hash) {
-+ i = j + 1;
-+ continue;
-+ }
-+
-+ oid = oid_search_table[j].oid;
-+ len = oid_index[oid + 1] - oid_index[oid];
-+ if (len > datasize) {
-+ k = j;
-+ continue;
-+ }
-+ if (len < datasize) {
-+ i = j + 1;
-+ continue;
-+ }
-+
-+ /* Variation is most likely to be at the tail end of the
-+ * OID, so do the comparison in reverse.
-+ */
-+ while (len > 0) {
-+ unsigned char a = oid_data[oid_index[oid] + --len];
-+ unsigned char b = octets[len];
-+ if (a > b) {
-+ k = j;
-+ goto next;
-+ }
-+ if (a < b) {
-+ i = j + 1;
-+ goto next;
-+ }
-+ }
-+ return oid;
-+ next:
-+ ;
-+ }
-+
-+ return OID__NR;
-+}
-+EXPORT_SYMBOL_GPL(look_up_OID);
---
-1.7.12.1
-
-
-From 3e1b30d7c67fd5419d4f6eb5d10b557dda4bc4fd Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:30:51 +0100
-Subject: [PATCH 13/37] X.509: Add utility functions to render OIDs as strings
-
-Add a pair of utility functions to render OIDs as strings. The first takes an
-encoded OID and turns it into a "a.b.c.d" form string:
-
- int sprint_oid(const void *data, size_t datasize,
- char *buffer, size_t bufsize);
-
-The second takes an OID enum index and calls the first on the data held
-therein:
-
- int sprint_OID(enum OID oid, char *buffer, size_t bufsize);
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/linux/oid_registry.h | 2 ++
- lib/oid_registry.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 83 insertions(+)
-
-diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
-index 5928546..6926db7 100644
---- a/include/linux/oid_registry.h
-+++ b/include/linux/oid_registry.h
-@@ -86,5 +86,7 @@ enum OID {
- };
-
- extern enum OID look_up_OID(const void *data, size_t datasize);
-+extern int sprint_oid(const void *, size_t, char *, size_t);
-+extern int sprint_OID(enum OID, char *, size_t);
-
- #endif /* _LINUX_OID_REGISTRY_H */
-diff --git a/lib/oid_registry.c b/lib/oid_registry.c
-index 33cfd17..d8de11f 100644
---- a/lib/oid_registry.c
-+++ b/lib/oid_registry.c
-@@ -11,6 +11,9 @@
-
- #include <linux/export.h>
- #include <linux/oid_registry.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/bug.h>
- #include "oid_registry_data.c"
-
- /**
-@@ -87,3 +90,81 @@ enum OID look_up_OID(const void *data, size_t datasize)
- return OID__NR;
- }
- EXPORT_SYMBOL_GPL(look_up_OID);
-+
-+/*
-+ * sprint_OID - Print an Object Identifier into a buffer
-+ * @data: The encoded OID to print
-+ * @datasize: The size of the encoded OID
-+ * @buffer: The buffer to render into
-+ * @bufsize: The size of the buffer
-+ *
-+ * The OID is rendered into the buffer in "a.b.c.d" format and the number of
-+ * bytes is returned. -EBADMSG is returned if the data could not be intepreted
-+ * and -ENOBUFS if the buffer was too small.
-+ */
-+int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
-+{
-+ const unsigned char *v = data, *end = v + datasize;
-+ unsigned long num;
-+ unsigned char n;
-+ size_t ret;
-+ int count;
-+
-+ if (v >= end)
-+ return -EBADMSG;
-+
-+ n = *v++;
-+ ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
-+ buffer += count;
-+ bufsize -= count;
-+ if (bufsize == 0)
-+ return -ENOBUFS;
-+
-+ while (v < end) {
-+ num = 0;
-+ n = *v++;
-+ if (!(n & 0x80)) {
-+ num = n;
-+ } else {
-+ num = n & 0x7f;
-+ do {
-+ if (v >= end)
-+ return -EBADMSG;
-+ n = *v++;
-+ num <<= 7;
-+ num |= n & 0x7f;
-+ } while (n & 0x80);
-+ }
-+ ret += count = snprintf(buffer, bufsize, ".%lu", num);
-+ buffer += count;
-+ bufsize -= count;
-+ if (bufsize == 0)
-+ return -ENOBUFS;
-+ }
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(sprint_oid);
-+
-+/**
-+ * sprint_OID - Print an Object Identifier into a buffer
-+ * @oid: The OID to print
-+ * @buffer: The buffer to render into
-+ * @bufsize: The size of the buffer
-+ *
-+ * The OID is rendered into the buffer in "a.b.c.d" format and the number of
-+ * bytes is returned.
-+ */
-+int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
-+{
-+ int ret;
-+
-+ BUG_ON(oid >= OID__NR);
-+
-+ ret = sprint_oid(oid_data + oid_index[oid],
-+ oid_index[oid + 1] - oid_index[oid],
-+ buffer, bufsize);
-+ BUG_ON(ret == -EBADMSG);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(sprint_OID);
---
-1.7.12.1
-
-
-From 978cd19071f71ae6a0e622bb2521f88ea633a326 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 21 Sep 2012 23:31:13 +0100
-Subject: [PATCH 14/37] X.509: Add simple ASN.1 grammar compiler
-
-Add a simple ASN.1 grammar compiler. This produces a bytecode output that can
-be fed to a decoder to inform the decoder how to interpret the ASN.1 stream it
-is trying to parse.
-
-Action functions can be specified in the grammar by interpolating:
-
- ({ foo })
-
-after a type, for example:
-
- SubjectPublicKeyInfo ::= SEQUENCE {
- algorithm AlgorithmIdentifier,
- subjectPublicKey BIT STRING ({ do_key_data })
- }
-
-The decoder is expected to call these after matching this type and parsing the
-contents if it is a constructed type.
-
-The grammar compiler does not currently support the SET type (though it does
-support SET OF) as I can't see a good way of tracking which members have been
-encountered yet without using up extra stack space.
-
-Currently, the grammar compiler will fail if more than 256 bytes of bytecode
-would be produced or more than 256 actions have been specified as it uses
-8-bit jump values and action indices to keep space usage down.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/linux/asn1.h | 67 ++
- include/linux/asn1_ber_bytecode.h | 87 +++
- init/Kconfig | 8 +
- scripts/.gitignore | 1 +
- scripts/Makefile | 2 +
- scripts/Makefile.build | 11 +
- scripts/asn1_compiler.c | 1545 +++++++++++++++++++++++++++++++++++++
- 7 files changed, 1721 insertions(+)
- create mode 100644 include/linux/asn1.h
- create mode 100644 include/linux/asn1_ber_bytecode.h
- create mode 100644 scripts/asn1_compiler.c
-
-diff --git a/include/linux/asn1.h b/include/linux/asn1.h
-new file mode 100644
-index 0000000..5c3f4e4
---- /dev/null
-+++ b/include/linux/asn1.h
-@@ -0,0 +1,67 @@
-+/* ASN.1 BER/DER/CER encoding definitions
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_ASN1_H
-+#define _LINUX_ASN1_H
-+
-+/* Class */
-+enum asn1_class {
-+ ASN1_UNIV = 0, /* Universal */
-+ ASN1_APPL = 1, /* Application */
-+ ASN1_CONT = 2, /* Context */
-+ ASN1_PRIV = 3 /* Private */
-+};
-+#define ASN1_CLASS_BITS 0xc0
-+
-+
-+enum asn1_method {
-+ ASN1_PRIM = 0, /* Primitive */
-+ ASN1_CONS = 1 /* Constructed */
-+};
-+#define ASN1_CONS_BIT 0x20
-+
-+/* Tag */
-+enum asn1_tag {
-+ ASN1_EOC = 0, /* End Of Contents or N/A */
-+ ASN1_BOOL = 1, /* Boolean */
-+ ASN1_INT = 2, /* Integer */
-+ ASN1_BTS = 3, /* Bit String */
-+ ASN1_OTS = 4, /* Octet String */
-+ ASN1_NULL = 5, /* Null */
-+ ASN1_OID = 6, /* Object Identifier */
-+ ASN1_ODE = 7, /* Object Description */
-+ ASN1_EXT = 8, /* External */
-+ ASN1_REAL = 9, /* Real float */
-+ ASN1_ENUM = 10, /* Enumerated */
-+ ASN1_EPDV = 11, /* Embedded PDV */
-+ ASN1_UTF8STR = 12, /* UTF8 String */
-+ ASN1_RELOID = 13, /* Relative OID */
-+ /* 14 - Reserved */
-+ /* 15 - Reserved */
-+ ASN1_SEQ = 16, /* Sequence and Sequence of */
-+ ASN1_SET = 17, /* Set and Set of */
-+ ASN1_NUMSTR = 18, /* Numerical String */
-+ ASN1_PRNSTR = 19, /* Printable String */
-+ ASN1_TEXSTR = 20, /* T61 String / Teletext String */
-+ ASN1_VIDSTR = 21, /* Videotex String */
-+ ASN1_IA5STR = 22, /* IA5 String */
-+ ASN1_UNITIM = 23, /* Universal Time */
-+ ASN1_GENTIM = 24, /* General Time */
-+ ASN1_GRASTR = 25, /* Graphic String */
-+ ASN1_VISSTR = 26, /* Visible String */
-+ ASN1_GENSTR = 27, /* General String */
-+ ASN1_UNISTR = 28, /* Universal String */
-+ ASN1_CHRSTR = 29, /* Character String */
-+ ASN1_BMPSTR = 30, /* BMP String */
-+ ASN1_LONG_TAG = 31 /* Long form tag */
-+};
-+
-+#endif /* _LINUX_ASN1_H */
-diff --git a/include/linux/asn1_ber_bytecode.h b/include/linux/asn1_ber_bytecode.h
-new file mode 100644
-index 0000000..945d44a
---- /dev/null
-+++ b/include/linux/asn1_ber_bytecode.h
-@@ -0,0 +1,87 @@
-+/* ASN.1 BER/DER/CER parsing state machine internal definitions
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_ASN1_BER_BYTECODE_H
-+#define _LINUX_ASN1_BER_BYTECODE_H
-+
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#endif
-+#include <linux/asn1.h>
-+
-+typedef int (*asn1_action_t)(void *context,
-+ size_t hdrlen, /* In case of ANY type */
-+ unsigned char tag, /* In case of ANY type */
-+ const void *value, size_t vlen);
-+
-+struct asn1_decoder {
-+ const unsigned char *machine;
-+ size_t machlen;
-+ const asn1_action_t *actions;
-+};
-+
-+enum asn1_opcode {
-+ /* The tag-matching ops come first and the odd-numbered slots
-+ * are for OR_SKIP ops.
-+ */
-+#define ASN1_OP_MATCH__SKIP 0x01
-+#define ASN1_OP_MATCH__ACT 0x02
-+#define ASN1_OP_MATCH__JUMP 0x04
-+#define ASN1_OP_MATCH__ANY 0x08
-+#define ASN1_OP_MATCH__COND 0x10
-+
-+ ASN1_OP_MATCH = 0x00,
-+ ASN1_OP_MATCH_OR_SKIP = 0x01,
-+ ASN1_OP_MATCH_ACT = 0x02,
-+ ASN1_OP_MATCH_ACT_OR_SKIP = 0x03,
-+ ASN1_OP_MATCH_JUMP = 0x04,
-+ ASN1_OP_MATCH_JUMP_OR_SKIP = 0x05,
-+ ASN1_OP_MATCH_ANY = 0x08,
-+ ASN1_OP_MATCH_ANY_ACT = 0x0a,
-+ /* Everything before here matches unconditionally */
-+
-+ ASN1_OP_COND_MATCH_OR_SKIP = 0x11,
-+ ASN1_OP_COND_MATCH_ACT_OR_SKIP = 0x13,
-+ ASN1_OP_COND_MATCH_JUMP_OR_SKIP = 0x15,
-+ ASN1_OP_COND_MATCH_ANY = 0x18,
-+ ASN1_OP_COND_MATCH_ANY_ACT = 0x1a,
-+
-+ /* Everything before here will want a tag from the data */
-+#define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT
-+
-+ /* These are here to help fill up space */
-+ ASN1_OP_COND_FAIL = 0x1b,
-+ ASN1_OP_COMPLETE = 0x1c,
-+ ASN1_OP_ACT = 0x1d,
-+ ASN1_OP_RETURN = 0x1e,
-+
-+ /* The following eight have bit 0 -> SET, 1 -> OF, 2 -> ACT */
-+ ASN1_OP_END_SEQ = 0x20,
-+ ASN1_OP_END_SET = 0x21,
-+ ASN1_OP_END_SEQ_OF = 0x22,
-+ ASN1_OP_END_SET_OF = 0x23,
-+ ASN1_OP_END_SEQ_ACT = 0x24,
-+ ASN1_OP_END_SET_ACT = 0x25,
-+ ASN1_OP_END_SEQ_OF_ACT = 0x26,
-+ ASN1_OP_END_SET_OF_ACT = 0x27,
-+#define ASN1_OP_END__SET 0x01
-+#define ASN1_OP_END__OF 0x02
-+#define ASN1_OP_END__ACT 0x04
-+
-+ ASN1_OP__NR
-+};
-+
-+#define _tag(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | ASN1_##TAG)
-+#define _tagn(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | TAG)
-+#define _jump_target(N) (N)
-+#define _action(N) (N)
-+
-+#endif /* _LINUX_ASN1_BER_BYTECODE_H */
-diff --git a/init/Kconfig b/init/Kconfig
-index 7452e19..fa8ccad 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1626,4 +1626,12 @@ config PADATA
- depends on SMP
- bool
-
-+config ASN1
-+ tristate
-+ help
-+ Build a simple ASN.1 grammar compiler that produces a bytecode output
-+ that can be interpreted by the ASN.1 stream decoder and used to
-+ inform it as to what tags are to be expected in a stream and what
-+ functions to call on what tags.
-+
- source "kernel/Kconfig.locks"
-diff --git a/scripts/.gitignore b/scripts/.gitignore
-index 65f362d..fb070fa 100644
---- a/scripts/.gitignore
-+++ b/scripts/.gitignore
-@@ -10,3 +10,4 @@ ihex2fw
- recordmcount
- docproc
- sortextable
-+asn1_compiler
-diff --git a/scripts/Makefile b/scripts/Makefile
-index a55b006..01e7adb 100644
---- a/scripts/Makefile
-+++ b/scripts/Makefile
-@@ -16,8 +16,10 @@ hostprogs-$(CONFIG_VT) += conmakehash
- hostprogs-$(CONFIG_IKCONFIG) += bin2c
- hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
- hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable
-+hostprogs-$(CONFIG_ASN1) += asn1_compiler
-
- HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
-+HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
-
- always := $(hostprogs-y) $(hostprogs-m)
-
-diff --git a/scripts/Makefile.build b/scripts/Makefile.build
-index ff1720d..0e801c3 100644
---- a/scripts/Makefile.build
-+++ b/scripts/Makefile.build
-@@ -354,6 +354,17 @@ quiet_cmd_cpp_lds_S = LDS $@
- $(obj)/%.lds: $(src)/%.lds.S FORCE
- $(call if_changed_dep,cpp_lds_S)
-
-+# ASN.1 grammar
-+# ---------------------------------------------------------------------------
-+quiet_cmd_asn1_compiler = ASN.1 $@
-+ cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
-+ $(subst .h,.c,$@) $(subst .c,.h,$@)
-+
-+.PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h
-+
-+$(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
-+ $(call cmd,asn1_compiler)
-+
- # Build the compiled-in targets
- # ---------------------------------------------------------------------------
-
-diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c
-new file mode 100644
-index 0000000..db0e5cd
---- /dev/null
-+++ b/scripts/asn1_compiler.c
-@@ -0,0 +1,1545 @@
-+/* Simplified ASN.1 notation parser
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdint.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <sys/stat.h>
-+#include <linux/asn1_ber_bytecode.h>
-+
-+enum token_type {
-+ DIRECTIVE_ABSENT,
-+ DIRECTIVE_ALL,
-+ DIRECTIVE_ANY,
-+ DIRECTIVE_APPLICATION,
-+ DIRECTIVE_AUTOMATIC,
-+ DIRECTIVE_BEGIN,
-+ DIRECTIVE_BIT,
-+ DIRECTIVE_BMPString,
-+ DIRECTIVE_BOOLEAN,
-+ DIRECTIVE_BY,
-+ DIRECTIVE_CHARACTER,
-+ DIRECTIVE_CHOICE,
-+ DIRECTIVE_CLASS,
-+ DIRECTIVE_COMPONENT,
-+ DIRECTIVE_COMPONENTS,
-+ DIRECTIVE_CONSTRAINED,
-+ DIRECTIVE_CONTAINING,
-+ DIRECTIVE_DEFAULT,
-+ DIRECTIVE_DEFINED,
-+ DIRECTIVE_DEFINITIONS,
-+ DIRECTIVE_EMBEDDED,
-+ DIRECTIVE_ENCODED,
-+ DIRECTIVE_ENCODING_CONTROL,
-+ DIRECTIVE_END,
-+ DIRECTIVE_ENUMERATED,
-+ DIRECTIVE_EXCEPT,
-+ DIRECTIVE_EXPLICIT,
-+ DIRECTIVE_EXPORTS,
-+ DIRECTIVE_EXTENSIBILITY,
-+ DIRECTIVE_EXTERNAL,
-+ DIRECTIVE_FALSE,
-+ DIRECTIVE_FROM,
-+ DIRECTIVE_GeneralString,
-+ DIRECTIVE_GeneralizedTime,
-+ DIRECTIVE_GraphicString,
-+ DIRECTIVE_IA5String,
-+ DIRECTIVE_IDENTIFIER,
-+ DIRECTIVE_IMPLICIT,
-+ DIRECTIVE_IMPLIED,
-+ DIRECTIVE_IMPORTS,
-+ DIRECTIVE_INCLUDES,
-+ DIRECTIVE_INSTANCE,
-+ DIRECTIVE_INSTRUCTIONS,
-+ DIRECTIVE_INTEGER,
-+ DIRECTIVE_INTERSECTION,
-+ DIRECTIVE_ISO646String,
-+ DIRECTIVE_MAX,
-+ DIRECTIVE_MIN,
-+ DIRECTIVE_MINUS_INFINITY,
-+ DIRECTIVE_NULL,
-+ DIRECTIVE_NumericString,
-+ DIRECTIVE_OBJECT,
-+ DIRECTIVE_OCTET,
-+ DIRECTIVE_OF,
-+ DIRECTIVE_OPTIONAL,
-+ DIRECTIVE_ObjectDescriptor,
-+ DIRECTIVE_PATTERN,
-+ DIRECTIVE_PDV,
-+ DIRECTIVE_PLUS_INFINITY,
-+ DIRECTIVE_PRESENT,
-+ DIRECTIVE_PRIVATE,
-+ DIRECTIVE_PrintableString,
-+ DIRECTIVE_REAL,
-+ DIRECTIVE_RELATIVE_OID,
-+ DIRECTIVE_SEQUENCE,
-+ DIRECTIVE_SET,
-+ DIRECTIVE_SIZE,
-+ DIRECTIVE_STRING,
-+ DIRECTIVE_SYNTAX,
-+ DIRECTIVE_T61String,
-+ DIRECTIVE_TAGS,
-+ DIRECTIVE_TRUE,
-+ DIRECTIVE_TeletexString,
-+ DIRECTIVE_UNION,
-+ DIRECTIVE_UNIQUE,
-+ DIRECTIVE_UNIVERSAL,
-+ DIRECTIVE_UTCTime,
-+ DIRECTIVE_UTF8String,
-+ DIRECTIVE_UniversalString,
-+ DIRECTIVE_VideotexString,
-+ DIRECTIVE_VisibleString,
-+ DIRECTIVE_WITH,
-+ NR__DIRECTIVES,
-+ TOKEN_ASSIGNMENT = NR__DIRECTIVES,
-+ TOKEN_OPEN_CURLY,
-+ TOKEN_CLOSE_CURLY,
-+ TOKEN_OPEN_SQUARE,
-+ TOKEN_CLOSE_SQUARE,
-+ TOKEN_OPEN_ACTION,
-+ TOKEN_CLOSE_ACTION,
-+ TOKEN_COMMA,
-+ TOKEN_NUMBER,
-+ TOKEN_TYPE_NAME,
-+ TOKEN_ELEMENT_NAME,
-+ NR__TOKENS
-+};
-+
-+static const unsigned char token_to_tag[NR__TOKENS] = {
-+ /* EOC goes first */
-+ [DIRECTIVE_BOOLEAN] = ASN1_BOOL,
-+ [DIRECTIVE_INTEGER] = ASN1_INT,
-+ [DIRECTIVE_BIT] = ASN1_BTS,
-+ [DIRECTIVE_OCTET] = ASN1_OTS,
-+ [DIRECTIVE_NULL] = ASN1_NULL,
-+ [DIRECTIVE_OBJECT] = ASN1_OID,
-+ [DIRECTIVE_ObjectDescriptor] = ASN1_ODE,
-+ [DIRECTIVE_EXTERNAL] = ASN1_EXT,
-+ [DIRECTIVE_REAL] = ASN1_REAL,
-+ [DIRECTIVE_ENUMERATED] = ASN1_ENUM,
-+ [DIRECTIVE_EMBEDDED] = 0,
-+ [DIRECTIVE_UTF8String] = ASN1_UTF8STR,
-+ [DIRECTIVE_RELATIVE_OID] = ASN1_RELOID,
-+ /* 14 */
-+ /* 15 */
-+ [DIRECTIVE_SEQUENCE] = ASN1_SEQ,
-+ [DIRECTIVE_SET] = ASN1_SET,
-+ [DIRECTIVE_NumericString] = ASN1_NUMSTR,
-+ [DIRECTIVE_PrintableString] = ASN1_PRNSTR,
-+ [DIRECTIVE_T61String] = ASN1_TEXSTR,
-+ [DIRECTIVE_TeletexString] = ASN1_TEXSTR,
-+ [DIRECTIVE_VideotexString] = ASN1_VIDSTR,
-+ [DIRECTIVE_IA5String] = ASN1_IA5STR,
-+ [DIRECTIVE_UTCTime] = ASN1_UNITIM,
-+ [DIRECTIVE_GeneralizedTime] = ASN1_GENTIM,
-+ [DIRECTIVE_GraphicString] = ASN1_GRASTR,
-+ [DIRECTIVE_VisibleString] = ASN1_VISSTR,
-+ [DIRECTIVE_GeneralString] = ASN1_GENSTR,
-+ [DIRECTIVE_UniversalString] = ASN1_UNITIM,
-+ [DIRECTIVE_CHARACTER] = ASN1_CHRSTR,
-+ [DIRECTIVE_BMPString] = ASN1_BMPSTR,
-+};
-+
-+static const char asn1_classes[4][5] = {
-+ [ASN1_UNIV] = "UNIV",
-+ [ASN1_APPL] = "APPL",
-+ [ASN1_CONT] = "CONT",
-+ [ASN1_PRIV] = "PRIV"
-+};
-+
-+static const char asn1_methods[2][5] = {
-+ [ASN1_UNIV] = "PRIM",
-+ [ASN1_APPL] = "CONS"
-+};
-+
-+static const char *const asn1_universal_tags[32] = {
-+ "EOC",
-+ "BOOL",
-+ "INT",
-+ "BTS",
-+ "OTS",
-+ "NULL",
-+ "OID",
-+ "ODE",
-+ "EXT",
-+ "REAL",
-+ "ENUM",
-+ "EPDV",
-+ "UTF8STR",
-+ "RELOID",
-+ NULL, /* 14 */
-+ NULL, /* 15 */
-+ "SEQ",
-+ "SET",
-+ "NUMSTR",
-+ "PRNSTR",
-+ "TEXSTR",
-+ "VIDSTR",
-+ "IA5STR",
-+ "UNITIM",
-+ "GENTIM",
-+ "GRASTR",
-+ "VISSTR",
-+ "GENSTR",
-+ "UNISTR",
-+ "CHRSTR",
-+ "BMPSTR",
-+ NULL /* 31 */
-+};
-+
-+static const char *filename;
-+static const char *grammar_name;
-+static const char *outputname;
-+static const char *headername;
-+
-+static const char *const directives[NR__DIRECTIVES] = {
-+#define _(X) [DIRECTIVE_##X] = #X
-+ _(ABSENT),
-+ _(ALL),
-+ _(ANY),
-+ _(APPLICATION),
-+ _(AUTOMATIC),
-+ _(BEGIN),
-+ _(BIT),
-+ _(BMPString),
-+ _(BOOLEAN),
-+ _(BY),
-+ _(CHARACTER),
-+ _(CHOICE),
-+ _(CLASS),
-+ _(COMPONENT),
-+ _(COMPONENTS),
-+ _(CONSTRAINED),
-+ _(CONTAINING),
-+ _(DEFAULT),
-+ _(DEFINED),
-+ _(DEFINITIONS),
-+ _(EMBEDDED),
-+ _(ENCODED),
-+ [DIRECTIVE_ENCODING_CONTROL] = "ENCODING-CONTROL",
-+ _(END),
-+ _(ENUMERATED),
-+ _(EXCEPT),
-+ _(EXPLICIT),
-+ _(EXPORTS),
-+ _(EXTENSIBILITY),
-+ _(EXTERNAL),
-+ _(FALSE),
-+ _(FROM),
-+ _(GeneralString),
-+ _(GeneralizedTime),
-+ _(GraphicString),
-+ _(IA5String),
-+ _(IDENTIFIER),
-+ _(IMPLICIT),
-+ _(IMPLIED),
-+ _(IMPORTS),
-+ _(INCLUDES),
-+ _(INSTANCE),
-+ _(INSTRUCTIONS),
-+ _(INTEGER),
-+ _(INTERSECTION),
-+ _(ISO646String),
-+ _(MAX),
-+ _(MIN),
-+ [DIRECTIVE_MINUS_INFINITY] = "MINUS-INFINITY",
-+ [DIRECTIVE_NULL] = "NULL",
-+ _(NumericString),
-+ _(OBJECT),
-+ _(OCTET),
-+ _(OF),
-+ _(OPTIONAL),
-+ _(ObjectDescriptor),
-+ _(PATTERN),
-+ _(PDV),
-+ [DIRECTIVE_PLUS_INFINITY] = "PLUS-INFINITY",
-+ _(PRESENT),
-+ _(PRIVATE),
-+ _(PrintableString),
-+ _(REAL),
-+ [DIRECTIVE_RELATIVE_OID] = "RELATIVE-OID",
-+ _(SEQUENCE),
-+ _(SET),
-+ _(SIZE),
-+ _(STRING),
-+ _(SYNTAX),
-+ _(T61String),
-+ _(TAGS),
-+ _(TRUE),
-+ _(TeletexString),
-+ _(UNION),
-+ _(UNIQUE),
-+ _(UNIVERSAL),
-+ _(UTCTime),
-+ _(UTF8String),
-+ _(UniversalString),
-+ _(VideotexString),
-+ _(VisibleString),
-+ _(WITH)
-+};
-+
-+struct action {
-+ struct action *next;
-+ unsigned char index;
-+ char name[];
-+};
-+
-+static struct action *action_list;
-+static unsigned nr_actions;
-+
-+struct token {
-+ unsigned short line;
-+ enum token_type token_type : 8;
-+ unsigned char size;
-+ struct action *action;
-+ const char *value;
-+ struct type *type;
-+};
-+
-+static struct token *token_list;
-+static unsigned nr_tokens;
-+
-+static int directive_compare(const void *_key, const void *_pdir)
-+{
-+ const struct token *token = _key;
-+ const char *const *pdir = _pdir, *dir = *pdir;
-+ size_t dlen, clen;
-+ int val;
-+
-+ dlen = strlen(dir);
-+ clen = (dlen < token->size) ? dlen : token->size;
-+
-+ //printf("cmp(%*.*s,%s) = ",
-+ // (int)token->size, (int)token->size, token->value,
-+ // dir);
-+
-+ val = memcmp(token->value, dir, clen);
-+ if (val != 0) {
-+ //printf("%d [cmp]\n", val);
-+ return val;
-+ }
-+
-+ if (dlen == token->size) {
-+ //printf("0\n");
-+ return 0;
-+ }
-+ //printf("%d\n", (int)dlen - (int)token->size);
-+ return dlen - token->size; /* shorter -> negative */
-+}
-+
-+/*
-+ * Tokenise an ASN.1 grammar
-+ */
-+static void tokenise(char *buffer, char *end)
-+{
-+ struct token *tokens;
-+ char *line, *nl, *p, *q;
-+ unsigned tix, lineno;
-+
-+ /* Assume we're going to have half as many tokens as we have
-+ * characters
-+ */
-+ token_list = tokens = calloc((end - buffer) / 2, sizeof(struct token));
-+ if (!tokens) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+ tix = 0;
-+
-+ lineno = 0;
-+ while (buffer < end) {
-+ /* First of all, break out a line */
-+ lineno++;
-+ line = buffer;
-+ nl = memchr(line, '\n', end - buffer);
-+ if (!nl) {
-+ buffer = nl = end;
-+ } else {
-+ buffer = nl + 1;
-+ *nl = '\0';
-+ }
-+
-+ /* Remove "--" comments */
-+ p = line;
-+ next_comment:
-+ while ((p = memchr(p, '-', nl - p))) {
-+ if (p[1] == '-') {
-+ /* Found a comment; see if there's a terminator */
-+ q = p + 2;
-+ while ((q = memchr(q, '-', nl - q))) {
-+ if (q[1] == '-') {
-+ /* There is - excise the comment */
-+ q += 2;
-+ memmove(p, q, nl - q);
-+ goto next_comment;
-+ }
-+ q++;
-+ }
-+ *p = '\0';
-+ nl = p;
-+ break;
-+ } else {
-+ p++;
-+ }
-+ }
-+
-+ p = line;
-+ while (p < nl) {
-+ /* Skip white space */
-+ while (p < nl && isspace(*p))
-+ *(p++) = 0;
-+ if (p >= nl)
-+ break;
-+
-+ tokens[tix].line = lineno;
-+ tokens[tix].value = p;
-+
-+ /* Handle string tokens */
-+ if (isalpha(*p)) {
-+ const char **dir;
-+
-+ /* Can be a directive, type name or element
-+ * name. Find the end of the name.
-+ */
-+ q = p + 1;
-+ while (q < nl && (isalnum(*q) || *q == '-' || *q == '_'))
-+ q++;
-+ tokens[tix].size = q - p;
-+ p = q;
-+
-+ /* If it begins with a lowercase letter then
-+ * it's an element name
-+ */
-+ if (islower(tokens[tix].value[0])) {
-+ tokens[tix++].token_type = TOKEN_ELEMENT_NAME;
-+ continue;
-+ }
-+
-+ /* Otherwise we need to search the directive
-+ * table
-+ */
-+ dir = bsearch(&tokens[tix], directives,
-+ sizeof(directives) / sizeof(directives[1]),
-+ sizeof(directives[1]),
-+ directive_compare);
-+ if (dir) {
-+ tokens[tix++].token_type = dir - directives;
-+ continue;
-+ }
-+
-+ tokens[tix++].token_type = TOKEN_TYPE_NAME;
-+ continue;
-+ }
-+
-+ /* Handle numbers */
-+ if (isdigit(*p)) {
-+ /* Find the end of the number */
-+ q = p + 1;
-+ while (q < nl && (isdigit(*q)))
-+ q++;
-+ tokens[tix].size = q - p;
-+ p = q;
-+ tokens[tix++].token_type = TOKEN_NUMBER;
-+ continue;
-+ }
-+
-+ if (nl - p >= 3) {
-+ if (memcmp(p, "::=", 3) == 0) {
-+ p += 3;
-+ tokens[tix].size = 3;
-+ tokens[tix++].token_type = TOKEN_ASSIGNMENT;
-+ continue;
-+ }
-+ }
-+
-+ if (nl - p >= 2) {
-+ if (memcmp(p, "({", 2) == 0) {
-+ p += 2;
-+ tokens[tix].size = 2;
-+ tokens[tix++].token_type = TOKEN_OPEN_ACTION;
-+ continue;
-+ }
-+ if (memcmp(p, "})", 2) == 0) {
-+ p += 2;
-+ tokens[tix].size = 2;
-+ tokens[tix++].token_type = TOKEN_CLOSE_ACTION;
-+ continue;
-+ }
-+ }
-+
-+ if (nl - p >= 1) {
-+ tokens[tix].size = 1;
-+ switch (*p) {
-+ case '{':
-+ p += 1;
-+ tokens[tix++].token_type = TOKEN_OPEN_CURLY;
-+ continue;
-+ case '}':
-+ p += 1;
-+ tokens[tix++].token_type = TOKEN_CLOSE_CURLY;
-+ continue;
-+ case '[':
-+ p += 1;
-+ tokens[tix++].token_type = TOKEN_OPEN_SQUARE;
-+ continue;
-+ case ']':
-+ p += 1;
-+ tokens[tix++].token_type = TOKEN_CLOSE_SQUARE;
-+ continue;
-+ case ',':
-+ p += 1;
-+ tokens[tix++].token_type = TOKEN_COMMA;
-+ continue;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ fprintf(stderr, "%s:%u: Unknown character in grammar: '%c'\n",
-+ filename, lineno, *p);
-+ exit(1);
-+ }
-+ }
-+
-+ nr_tokens = tix;
-+ printf("Extracted %u tokens\n", nr_tokens);
-+
-+#if 0
-+ {
-+ int n;
-+ for (n = 0; n < nr_tokens; n++)
-+ printf("Token %3u: '%*.*s'\n",
-+ n,
-+ (int)token_list[n].size, (int)token_list[n].size,
-+ token_list[n].value);
-+ }
-+#endif
-+}
-+
-+static void build_type_list(void);
-+static void parse(void);
-+static void render(FILE *out, FILE *hdr);
-+
-+/*
-+ *
-+ */
-+int main(int argc, char **argv)
-+{
-+ struct stat st;
-+ ssize_t readlen;
-+ FILE *out, *hdr;
-+ char *buffer, *p;
-+ int fd;
-+
-+ if (argc != 4) {
-+ fprintf(stderr, "Format: %s <grammar-file> <c-file> <hdr-file>\n",
-+ argv[0]);
-+ exit(2);
-+ }
-+
-+ filename = argv[1];
-+ outputname = argv[2];
-+ headername = argv[3];
-+
-+ fd = open(filename, O_RDONLY);
-+ if (fd < 0) {
-+ perror(filename);
-+ exit(1);
-+ }
-+
-+ if (fstat(fd, &st) < 0) {
-+ perror(filename);
-+ exit(1);
-+ }
-+
-+ if (!(buffer = malloc(st.st_size + 1))) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+
-+ if ((readlen = read(fd, buffer, st.st_size)) < 0) {
-+ perror(filename);
-+ exit(1);
-+ }
-+
-+ if (close(fd) < 0) {
-+ perror(filename);
-+ exit(1);
-+ }
-+
-+ if (readlen != st.st_size) {
-+ fprintf(stderr, "%s: Short read\n", filename);
-+ exit(1);
-+ }
-+
-+ p = strrchr(argv[1], '/');
-+ p = p ? p + 1 : argv[1];
-+ grammar_name = strdup(p);
-+ if (!p) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+ p = strchr(grammar_name, '.');
-+ if (p)
-+ *p = '\0';
-+
-+ buffer[readlen] = 0;
-+ tokenise(buffer, buffer + readlen);
-+ build_type_list();
-+ parse();
-+
-+ out = fopen(outputname, "w");
-+ if (!out) {
-+ perror(outputname);
-+ exit(1);
-+ }
-+
-+ hdr = fopen(headername, "w");
-+ if (!out) {
-+ perror(headername);
-+ exit(1);
-+ }
-+
-+ render(out, hdr);
-+
-+ if (fclose(out) < 0) {
-+ perror(outputname);
-+ exit(1);
-+ }
-+
-+ if (fclose(hdr) < 0) {
-+ perror(headername);
-+ exit(1);
-+ }
-+
-+ return 0;
-+}
-+
-+enum compound {
-+ NOT_COMPOUND,
-+ SET,
-+ SET_OF,
-+ SEQUENCE,
-+ SEQUENCE_OF,
-+ CHOICE,
-+ ANY,
-+ TYPE_REF,
-+ TAG_OVERRIDE
-+};
-+
-+struct element {
-+ struct type *type_def;
-+ struct token *name;
-+ struct token *type;
-+ struct action *action;
-+ struct element *children;
-+ struct element *next;
-+ struct element *render_next;
-+ struct element *list_next;
-+ uint8_t n_elements;
-+ enum compound compound : 8;
-+ enum asn1_class class : 8;
-+ enum asn1_method method : 8;
-+ uint8_t tag;
-+ unsigned entry_index;
-+ unsigned flags;
-+#define ELEMENT_IMPLICIT 0x0001
-+#define ELEMENT_EXPLICIT 0x0002
-+#define ELEMENT_MARKED 0x0004
-+#define ELEMENT_RENDERED 0x0008
-+#define ELEMENT_SKIPPABLE 0x0010
-+#define ELEMENT_CONDITIONAL 0x0020
-+};
-+
-+struct type {
-+ struct token *name;
-+ struct token *def;
-+ struct element *element;
-+ unsigned ref_count;
-+ unsigned flags;
-+#define TYPE_STOP_MARKER 0x0001
-+#define TYPE_BEGIN 0x0002
-+};
-+
-+static struct type *type_list;
-+static struct type **type_index;
-+static unsigned nr_types;
-+
-+static int type_index_compare(const void *_a, const void *_b)
-+{
-+ const struct type *const *a = _a, *const *b = _b;
-+
-+ if ((*a)->name->size != (*b)->name->size)
-+ return (*a)->name->size - (*b)->name->size;
-+ else
-+ return memcmp((*a)->name->value, (*b)->name->value,
-+ (*a)->name->size);
-+}
-+
-+static int type_finder(const void *_key, const void *_ti)
-+{
-+ const struct token *token = _key;
-+ const struct type *const *ti = _ti;
-+ const struct type *type = *ti;
-+
-+ if (token->size != type->name->size)
-+ return token->size - type->name->size;
-+ else
-+ return memcmp(token->value, type->name->value,
-+ token->size);
-+}
-+
-+/*
-+ * Build up a list of types and a sorted index to that list.
-+ */
-+static void build_type_list(void)
-+{
-+ struct type *types;
-+ unsigned nr, t, n;
-+
-+ nr = 0;
-+ for (n = 0; n < nr_tokens - 1; n++)
-+ if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
-+ token_list[n + 1].token_type == TOKEN_ASSIGNMENT)
-+ nr++;
-+
-+ if (nr == 0) {
-+ fprintf(stderr, "%s: No defined types\n", filename);
-+ exit(1);
-+ }
-+
-+ nr_types = nr;
-+ types = type_list = calloc(nr + 1, sizeof(type_list[0]));
-+ if (!type_list) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+ type_index = calloc(nr, sizeof(type_index[0]));
-+ if (!type_index) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+
-+ t = 0;
-+ types[t].flags |= TYPE_BEGIN;
-+ for (n = 0; n < nr_tokens - 1; n++) {
-+ if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
-+ token_list[n + 1].token_type == TOKEN_ASSIGNMENT) {
-+ types[t].name = &token_list[n];
-+ type_index[t] = &types[t];
-+ t++;
-+ }
-+ }
-+ types[t].name = &token_list[n + 1];
-+ types[t].flags |= TYPE_STOP_MARKER;
-+
-+ qsort(type_index, nr, sizeof(type_index[0]), type_index_compare);
-+
-+ printf("Extracted %u types\n", nr_types);
-+#if 0
-+ for (n = 0; n < nr_types; n++) {
-+ struct type *type = type_index[n];
-+ printf("- %*.*s\n",
-+ (int)type->name->size,
-+ (int)type->name->size,
-+ type->name->value);
-+ }
-+#endif
-+}
-+
-+static struct element *parse_type(struct token **_cursor, struct token *stop,
-+ struct token *name);
-+
-+/*
-+ * Parse the token stream
-+ */
-+static void parse(void)
-+{
-+ struct token *cursor;
-+ struct type *type;
-+
-+ /* Parse one type definition statement at a time */
-+ type = type_list;
-+ do {
-+ cursor = type->name;
-+
-+ if (cursor[0].token_type != TOKEN_TYPE_NAME ||
-+ cursor[1].token_type != TOKEN_ASSIGNMENT)
-+ abort();
-+ cursor += 2;
-+
-+ type->element = parse_type(&cursor, type[1].name, NULL);
-+ type->element->type_def = type;
-+
-+ if (cursor != type[1].name) {
-+ fprintf(stderr, "%s:%d: Parse error at token '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+
-+ } while (type++, !(type->flags & TYPE_STOP_MARKER));
-+
-+ printf("Extracted %u actions\n", nr_actions);
-+}
-+
-+static struct element *element_list;
-+
-+static struct element *alloc_elem(struct token *type)
-+{
-+ struct element *e = calloc(1, sizeof(*e));
-+ if (!e) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+ e->list_next = element_list;
-+ element_list = e;
-+ return e;
-+}
-+
-+static struct element *parse_compound(struct token **_cursor, struct token *end,
-+ int alternates);
-+
-+/*
-+ * Parse one type definition statement
-+ */
-+static struct element *parse_type(struct token **_cursor, struct token *end,
-+ struct token *name)
-+{
-+ struct element *top, *element;
-+ struct action *action, **ppaction;
-+ struct token *cursor = *_cursor;
-+ struct type **ref;
-+ char *p;
-+ int labelled = 0, implicit = 0;
-+
-+ top = element = alloc_elem(cursor);
-+ element->class = ASN1_UNIV;
-+ element->method = ASN1_PRIM;
-+ element->tag = token_to_tag[cursor->token_type];
-+ element->name = name;
-+
-+ /* Extract the tag value if one given */
-+ if (cursor->token_type == TOKEN_OPEN_SQUARE) {
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ switch (cursor->token_type) {
-+ case DIRECTIVE_UNIVERSAL:
-+ element->class = ASN1_UNIV;
-+ cursor++;
-+ break;
-+ case DIRECTIVE_APPLICATION:
-+ element->class = ASN1_APPL;
-+ cursor++;
-+ break;
-+ case TOKEN_NUMBER:
-+ element->class = ASN1_CONT;
-+ break;
-+ case DIRECTIVE_PRIVATE:
-+ element->class = ASN1_PRIV;
-+ cursor++;
-+ break;
-+ default:
-+ fprintf(stderr, "%s:%d: Unrecognised tag class token '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != TOKEN_NUMBER) {
-+ fprintf(stderr, "%s:%d: Missing tag number '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+
-+ element->tag &= ~0x1f;
-+ element->tag |= strtoul(cursor->value, &p, 10);
-+ if (p - cursor->value != cursor->size)
-+ abort();
-+ cursor++;
-+
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != TOKEN_CLOSE_SQUARE) {
-+ fprintf(stderr, "%s:%d: Missing closing square bracket '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ labelled = 1;
-+ }
-+
-+ /* Handle implicit and explicit markers */
-+ if (cursor->token_type == DIRECTIVE_IMPLICIT) {
-+ element->flags |= ELEMENT_IMPLICIT;
-+ implicit = 1;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ } else if (cursor->token_type == DIRECTIVE_EXPLICIT) {
-+ element->flags |= ELEMENT_EXPLICIT;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ }
-+
-+ if (labelled) {
-+ if (!implicit)
-+ element->method |= ASN1_CONS;
-+ element->compound = implicit ? TAG_OVERRIDE : SEQUENCE;
-+ element->children = alloc_elem(cursor);
-+ element = element->children;
-+ element->class = ASN1_UNIV;
-+ element->method = ASN1_PRIM;
-+ element->tag = token_to_tag[cursor->token_type];
-+ element->name = name;
-+ }
-+
-+ /* Extract the type we're expecting here */
-+ element->type = cursor;
-+ switch (cursor->token_type) {
-+ case DIRECTIVE_ANY:
-+ element->compound = ANY;
-+ cursor++;
-+ break;
-+
-+ case DIRECTIVE_NULL:
-+ case DIRECTIVE_BOOLEAN:
-+ case DIRECTIVE_ENUMERATED:
-+ case DIRECTIVE_INTEGER:
-+ element->compound = NOT_COMPOUND;
-+ cursor++;
-+ break;
-+
-+ case DIRECTIVE_EXTERNAL:
-+ element->method = ASN1_CONS;
-+
-+ case DIRECTIVE_BMPString:
-+ case DIRECTIVE_GeneralString:
-+ case DIRECTIVE_GraphicString:
-+ case DIRECTIVE_IA5String:
-+ case DIRECTIVE_ISO646String:
-+ case DIRECTIVE_NumericString:
-+ case DIRECTIVE_PrintableString:
-+ case DIRECTIVE_T61String:
-+ case DIRECTIVE_TeletexString:
-+ case DIRECTIVE_UniversalString:
-+ case DIRECTIVE_UTF8String:
-+ case DIRECTIVE_VideotexString:
-+ case DIRECTIVE_VisibleString:
-+ case DIRECTIVE_ObjectDescriptor:
-+ case DIRECTIVE_GeneralizedTime:
-+ case DIRECTIVE_UTCTime:
-+ element->compound = NOT_COMPOUND;
-+ cursor++;
-+ break;
-+
-+ case DIRECTIVE_BIT:
-+ case DIRECTIVE_OCTET:
-+ element->compound = NOT_COMPOUND;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != DIRECTIVE_STRING)
-+ goto parse_error;
-+ cursor++;
-+ break;
-+
-+ case DIRECTIVE_OBJECT:
-+ element->compound = NOT_COMPOUND;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != DIRECTIVE_IDENTIFIER)
-+ goto parse_error;
-+ cursor++;
-+ break;
-+
-+ case TOKEN_TYPE_NAME:
-+ element->compound = TYPE_REF;
-+ ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]),
-+ type_finder);
-+ if (!ref) {
-+ fprintf(stderr, "%s:%d: Type '%*.*s' undefined\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+ cursor->type = *ref;
-+ (*ref)->ref_count++;
-+ cursor++;
-+ break;
-+
-+ case DIRECTIVE_CHOICE:
-+ element->compound = CHOICE;
-+ cursor++;
-+ element->children = parse_compound(&cursor, end, 1);
-+ break;
-+
-+ case DIRECTIVE_SEQUENCE:
-+ element->compound = SEQUENCE;
-+ element->method = ASN1_CONS;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type == DIRECTIVE_OF) {
-+ element->compound = SEQUENCE_OF;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ element->children = parse_type(&cursor, end, NULL);
-+ } else {
-+ element->children = parse_compound(&cursor, end, 0);
-+ }
-+ break;
-+
-+ case DIRECTIVE_SET:
-+ element->compound = SET;
-+ element->method = ASN1_CONS;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type == DIRECTIVE_OF) {
-+ element->compound = SET_OF;
-+ cursor++;
-+ if (cursor >= end)
-+ goto parse_error;
-+ element->children = parse_type(&cursor, end, NULL);
-+ } else {
-+ element->children = parse_compound(&cursor, end, 1);
-+ }
-+ break;
-+
-+ default:
-+ fprintf(stderr, "%s:%d: Token '%*.*s' does not introduce a type\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+
-+ /* Handle elements that are optional */
-+ if (cursor < end && (cursor->token_type == DIRECTIVE_OPTIONAL ||
-+ cursor->token_type == DIRECTIVE_DEFAULT)
-+ ) {
-+ cursor++;
-+ top->flags |= ELEMENT_SKIPPABLE;
-+ }
-+
-+ if (cursor < end && cursor->token_type == TOKEN_OPEN_ACTION) {
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != TOKEN_ELEMENT_NAME) {
-+ fprintf(stderr, "%s:%d: Token '%*.*s' is not an action function name\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+
-+ action = malloc(sizeof(struct action) + cursor->size + 1);
-+ if (!action) {
-+ perror(NULL);
-+ exit(1);
-+ }
-+ action->index = 0;
-+ memcpy(action->name, cursor->value, cursor->size);
-+ action->name[cursor->size] = 0;
-+
-+ for (ppaction = &action_list;
-+ *ppaction;
-+ ppaction = &(*ppaction)->next
-+ ) {
-+ int cmp = strcmp(action->name, (*ppaction)->name);
-+ if (cmp == 0) {
-+ free(action);
-+ action = *ppaction;
-+ goto found;
-+ }
-+ if (cmp < 0) {
-+ action->next = *ppaction;
-+ *ppaction = action;
-+ nr_actions++;
-+ goto found;
-+ }
-+ }
-+ action->next = NULL;
-+ *ppaction = action;
-+ nr_actions++;
-+ found:
-+
-+ element->action = action;
-+ cursor->action = action;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != TOKEN_CLOSE_ACTION) {
-+ fprintf(stderr, "%s:%d: Missing close action, got '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+ cursor++;
-+ }
-+
-+ *_cursor = cursor;
-+ return top;
-+
-+parse_error:
-+ fprintf(stderr, "%s:%d: Unexpected token '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+
-+overrun_error:
-+ fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
-+ exit(1);
-+}
-+
-+/*
-+ * Parse a compound type list
-+ */
-+static struct element *parse_compound(struct token **_cursor, struct token *end,
-+ int alternates)
-+{
-+ struct element *children, **child_p = &children, *element;
-+ struct token *cursor = *_cursor, *name;
-+
-+ if (cursor->token_type != TOKEN_OPEN_CURLY) {
-+ fprintf(stderr, "%s:%d: Expected compound to start with brace not '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+
-+ if (cursor->token_type == TOKEN_OPEN_CURLY) {
-+ fprintf(stderr, "%s:%d: Empty compound\n",
-+ filename, cursor->line);
-+ exit(1);
-+ }
-+
-+ for (;;) {
-+ name = NULL;
-+ if (cursor->token_type == TOKEN_ELEMENT_NAME) {
-+ name = cursor;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ }
-+
-+ element = parse_type(&cursor, end, name);
-+ if (alternates)
-+ element->flags |= ELEMENT_SKIPPABLE | ELEMENT_CONDITIONAL;
-+
-+ *child_p = element;
-+ child_p = &element->next;
-+
-+ if (cursor >= end)
-+ goto overrun_error;
-+ if (cursor->token_type != TOKEN_COMMA)
-+ break;
-+ cursor++;
-+ if (cursor >= end)
-+ goto overrun_error;
-+ }
-+
-+ children->flags &= ~ELEMENT_CONDITIONAL;
-+
-+ if (cursor->token_type != TOKEN_CLOSE_CURLY) {
-+ fprintf(stderr, "%s:%d: Expected compound closure, got '%*.*s'\n",
-+ filename, cursor->line,
-+ (int)cursor->size, (int)cursor->size, cursor->value);
-+ exit(1);
-+ }
-+ cursor++;
-+
-+ *_cursor = cursor;
-+ return children;
-+
-+overrun_error:
-+ fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
-+ exit(1);
-+}
-+
-+static void render_element(FILE *out, struct element *e, struct element *tag);
-+static void render_out_of_line_list(FILE *out);
-+
-+static int nr_entries;
-+static int render_depth = 1;
-+static struct element *render_list, **render_list_p = &render_list;
-+
-+__attribute__((format(printf, 2, 3)))
-+static void render_opcode(FILE *out, const char *fmt, ...)
-+{
-+ va_list va;
-+
-+ if (out) {
-+ fprintf(out, "\t[%4d] =%*s", nr_entries, render_depth, "");
-+ va_start(va, fmt);
-+ vfprintf(out, fmt, va);
-+ va_end(va);
-+ }
-+ nr_entries++;
-+}
-+
-+__attribute__((format(printf, 2, 3)))
-+static void render_more(FILE *out, const char *fmt, ...)
-+{
-+ va_list va;
-+
-+ if (out) {
-+ va_start(va, fmt);
-+ vfprintf(out, fmt, va);
-+ va_end(va);
-+ }
-+}
-+
-+/*
-+ * Render the grammar into a state machine definition.
-+ */
-+static void render(FILE *out, FILE *hdr)
-+{
-+ struct element *e;
-+ struct action *action;
-+ struct type *root;
-+ int index;
-+
-+ fprintf(hdr, "/*\n");
-+ fprintf(hdr, " * Automatically generated by asn1_compiler. Do not edit\n");
-+ fprintf(hdr, " *\n");
-+ fprintf(hdr, " * ASN.1 parser for %s\n", grammar_name);
-+ fprintf(hdr, " */\n");
-+ fprintf(hdr, "#include <linux/asn1_decoder.h>\n");
-+ fprintf(hdr, "\n");
-+ fprintf(hdr, "extern const struct asn1_decoder %s_decoder;\n", grammar_name);
-+ if (ferror(hdr)) {
-+ perror(headername);
-+ exit(1);
-+ }
-+
-+ fprintf(out, "/*\n");
-+ fprintf(out, " * Automatically generated by asn1_compiler. Do not edit\n");
-+ fprintf(out, " *\n");
-+ fprintf(out, " * ASN.1 parser for %s\n", grammar_name);
-+ fprintf(out, " */\n");
-+ fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n");
-+ fprintf(out, "#include \"%s-asn1.h\"\n", grammar_name);
-+ fprintf(out, "\n");
-+ if (ferror(out)) {
-+ perror(outputname);
-+ exit(1);
-+ }
-+
-+ /* Tabulate the action functions we might have to call */
-+ fprintf(hdr, "\n");
-+ index = 0;
-+ for (action = action_list; action; action = action->next) {
-+ action->index = index++;
-+ fprintf(hdr,
-+ "extern int %s(void *, size_t, unsigned char,"
-+ " const void *, size_t);\n",
-+ action->name);
-+ }
-+ fprintf(hdr, "\n");
-+
-+ fprintf(out, "enum %s_actions {\n", grammar_name);
-+ for (action = action_list; action; action = action->next)
-+ fprintf(out, "\tACT_%s = %u,\n",
-+ action->name, action->index);
-+ fprintf(out, "\tNR__%s_actions = %u\n", grammar_name, nr_actions);
-+ fprintf(out, "};\n");
-+
-+ fprintf(out, "\n");
-+ fprintf(out, "static const asn1_action_t %s_action_table[NR__%s_actions] = {\n",
-+ grammar_name, grammar_name);
-+ for (action = action_list; action; action = action->next)
-+ fprintf(out, "\t[%4u] = %s,\n", action->index, action->name);
-+ fprintf(out, "};\n");
-+
-+ if (ferror(out)) {
-+ perror(outputname);
-+ exit(1);
-+ }
-+
-+ /* We do two passes - the first one calculates all the offsets */
-+ printf("Pass 1\n");
-+ nr_entries = 0;
-+ root = &type_list[0];
-+ render_element(NULL, root->element, NULL);
-+ render_opcode(NULL, "ASN1_OP_COMPLETE,\n");
-+ render_out_of_line_list(NULL);
-+
-+ for (e = element_list; e; e = e->list_next)
-+ e->flags &= ~ELEMENT_RENDERED;
-+
-+ /* And then we actually render */
-+ printf("Pass 2\n");
-+ fprintf(out, "\n");
-+ fprintf(out, "static const unsigned char %s_machine[] = {\n",
-+ grammar_name);
-+
-+ nr_entries = 0;
-+ root = &type_list[0];
-+ render_element(out, root->element, NULL);
-+ render_opcode(out, "ASN1_OP_COMPLETE,\n");
-+ render_out_of_line_list(out);
-+
-+ fprintf(out, "};\n");
-+
-+ fprintf(out, "\n");
-+ fprintf(out, "const struct asn1_decoder %s_decoder = {\n", grammar_name);
-+ fprintf(out, "\t.machine = %s_machine,\n", grammar_name);
-+ fprintf(out, "\t.machlen = sizeof(%s_machine),\n", grammar_name);
-+ fprintf(out, "\t.actions = %s_action_table,\n", grammar_name);
-+ fprintf(out, "};\n");
-+}
-+
-+/*
-+ * Render the out-of-line elements
-+ */
-+static void render_out_of_line_list(FILE *out)
-+{
-+ struct element *e, *ce;
-+ const char *act;
-+ int entry;
-+
-+ while ((e = render_list)) {
-+ render_list = e->render_next;
-+ if (!render_list)
-+ render_list_p = &render_list;
-+
-+ render_more(out, "\n");
-+ e->entry_index = entry = nr_entries;
-+ render_depth++;
-+ for (ce = e->children; ce; ce = ce->next)
-+ render_element(out, ce, NULL);
-+ render_depth--;
-+
-+ act = e->action ? "_ACT" : "";
-+ switch (e->compound) {
-+ case SEQUENCE:
-+ render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
-+ break;
-+ case SEQUENCE_OF:
-+ render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
-+ render_opcode(out, "_jump_target(%u),\n", entry);
-+ break;
-+ case SET:
-+ render_opcode(out, "ASN1_OP_END_SET%s,\n", act);
-+ break;
-+ case SET_OF:
-+ render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
-+ render_opcode(out, "_jump_target(%u),\n", entry);
-+ break;
-+ }
-+ if (e->action)
-+ render_opcode(out, "_action(ACT_%s),\n",
-+ e->action->name);
-+ render_opcode(out, "ASN1_OP_RETURN,\n");
-+ }
-+}
-+
-+/*
-+ * Render an element.
-+ */
-+static void render_element(FILE *out, struct element *e, struct element *tag)
-+{
-+ struct element *ec;
-+ const char *cond, *act;
-+ int entry, skippable = 0, outofline = 0;
-+
-+ if (e->flags & ELEMENT_SKIPPABLE ||
-+ (tag && tag->flags & ELEMENT_SKIPPABLE))
-+ skippable = 1;
-+
-+ if ((e->type_def && e->type_def->ref_count > 1) ||
-+ skippable)
-+ outofline = 1;
-+
-+ if (e->type_def && out) {
-+ render_more(out, "\t// %*.*s\n",
-+ (int)e->type_def->name->size, (int)e->type_def->name->size,
-+ e->type_def->name->value);
-+ }
-+
-+ /* Render the operation */
-+ cond = (e->flags & ELEMENT_CONDITIONAL ||
-+ (tag && tag->flags & ELEMENT_CONDITIONAL)) ? "COND_" : "";
-+ act = e->action ? "_ACT" : "";
-+ switch (e->compound) {
-+ case ANY:
-+ render_opcode(out, "ASN1_OP_%sMATCH_ANY%s,", cond, act);
-+ if (e->name)
-+ render_more(out, "\t\t// %*.*s",
-+ (int)e->name->size, (int)e->name->size,
-+ e->name->value);
-+ render_more(out, "\n");
-+ goto dont_render_tag;
-+
-+ case TAG_OVERRIDE:
-+ render_element(out, e->children, e);
-+ return;
-+
-+ case SEQUENCE:
-+ case SEQUENCE_OF:
-+ case SET:
-+ case SET_OF:
-+ render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
-+ cond,
-+ outofline ? "_JUMP" : "",
-+ skippable ? "_OR_SKIP" : "");
-+ break;
-+
-+ case CHOICE:
-+ goto dont_render_tag;
-+
-+ case TYPE_REF:
-+ if (e->class == ASN1_UNIV && e->method == ASN1_PRIM && e->tag == 0)
-+ goto dont_render_tag;
-+ default:
-+ render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
-+ cond, act,
-+ skippable ? "_OR_SKIP" : "");
-+ break;
-+ }
-+
-+ if (e->name)
-+ render_more(out, "\t\t// %*.*s",
-+ (int)e->name->size, (int)e->name->size,
-+ e->name->value);
-+ render_more(out, "\n");
-+
-+ /* Render the tag */
-+ if (!tag)
-+ tag = e;
-+ if (tag->class == ASN1_UNIV &&
-+ tag->tag != 14 &&
-+ tag->tag != 15 &&
-+ tag->tag != 31)
-+ render_opcode(out, "_tag(%s, %s, %s),\n",
-+ asn1_classes[tag->class],
-+ asn1_methods[tag->method | e->method],
-+ asn1_universal_tags[tag->tag]);
-+ else
-+ render_opcode(out, "_tagn(%s, %s, %2u),\n",
-+ asn1_classes[tag->class],
-+ asn1_methods[tag->method | e->method],
-+ tag->tag);
-+ tag = NULL;
-+dont_render_tag:
-+
-+ /* Deal with compound types */
-+ switch (e->compound) {
-+ case TYPE_REF:
-+ render_element(out, e->type->type->element, tag);
-+ if (e->action)
-+ render_opcode(out, "ASN1_OP_ACT,\n");
-+ break;
-+
-+ case SEQUENCE:
-+ if (outofline) {
-+ /* Render out-of-line for multiple use or
-+ * skipability */
-+ render_opcode(out, "_jump_target(%u),", e->entry_index);
-+ if (e->type_def && e->type_def->name)
-+ render_more(out, "\t\t// --> %*.*s",
-+ (int)e->type_def->name->size,
-+ (int)e->type_def->name->size,
-+ e->type_def->name->value);
-+ render_more(out, "\n");
-+ if (!(e->flags & ELEMENT_RENDERED)) {
-+ e->flags |= ELEMENT_RENDERED;
-+ *render_list_p = e;
-+ render_list_p = &e->render_next;
-+ }
-+ return;
-+ } else {
-+ /* Render inline for single use */
-+ render_depth++;
-+ for (ec = e->children; ec; ec = ec->next)
-+ render_element(out, ec, NULL);
-+ render_depth--;
-+ render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
-+ }
-+ break;
-+
-+ case SEQUENCE_OF:
-+ case SET_OF:
-+ if (outofline) {
-+ /* Render out-of-line for multiple use or
-+ * skipability */
-+ render_opcode(out, "_jump_target(%u),", e->entry_index);
-+ if (e->type_def && e->type_def->name)
-+ render_more(out, "\t\t// --> %*.*s",
-+ (int)e->type_def->name->size,
-+ (int)e->type_def->name->size,
-+ e->type_def->name->value);
-+ render_more(out, "\n");
-+ if (!(e->flags & ELEMENT_RENDERED)) {
-+ e->flags |= ELEMENT_RENDERED;
-+ *render_list_p = e;
-+ render_list_p = &e->render_next;
-+ }
-+ return;
-+ } else {
-+ /* Render inline for single use */
-+ entry = nr_entries;
-+ render_depth++;
-+ render_element(out, e->children, NULL);
-+ render_depth--;
-+ if (e->compound == SEQUENCE_OF)
-+ render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
-+ else
-+ render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
-+ render_opcode(out, "_jump_target(%u),\n", entry);
-+ }
-+ break;
-+
-+ case SET:
-+ /* I can't think of a nice way to do SET support without having
-+ * a stack of bitmasks to make sure no element is repeated.
-+ * The bitmask has also to be checked that no non-optional
-+ * elements are left out whilst not preventing optional
-+ * elements from being left out.
-+ */
-+ fprintf(stderr, "The ASN.1 SET type is not currently supported.\n");
-+ exit(1);
-+
-+ case CHOICE:
-+ for (ec = e->children; ec; ec = ec->next)
-+ render_element(out, ec, NULL);
-+ if (!skippable)
-+ render_opcode(out, "ASN1_OP_COND_FAIL,\n");
-+ if (e->action)
-+ render_opcode(out, "ASN1_OP_ACT,\n");
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (e->action)
-+ render_opcode(out, "_action(ACT_%s),\n", e->action->name);
-+}
---
-1.7.12.1
-
-
-From 650c728e4b8d58d72b19973e97c3c765178e81b8 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Mon, 24 Sep 2012 17:11:16 +0100
-Subject: [PATCH 15/37] X.509: Add an ASN.1 decoder
-
-Add an ASN.1 BER/DER/CER decoder. This uses the bytecode from the ASN.1
-compiler in the previous patch to inform it as to what to expect to find in the
-encoded byte stream. The output from the compiler also tells it what functions
-to call on what tags, thus allowing the caller to retrieve information.
-
-The decoder is called as follows:
-
- int asn1_decoder(const struct asn1_decoder *decoder,
- void *context,
- const unsigned char *data,
- size_t datalen);
-
-The decoder argument points to the bytecode from the ASN.1 compiler. context
-is the caller's context and is passed to the action functions. data and
-datalen define the byte stream to be decoded.
-
-Note that the decoder is currently limited to datalen being less than 64K.
-This reduces the amount of stack space used by the decoder because ASN.1 is a
-nested construct. Similarly, the decoder is limited to a maximum of 10 levels
-of constructed data outside of a leaf node also in an effort to keep stack
-usage down.
-
-These restrictions can be raised if necessary.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/linux/asn1_decoder.h | 24 +++
- lib/Makefile | 2 +
- lib/asn1_decoder.c | 477 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 503 insertions(+)
- create mode 100644 include/linux/asn1_decoder.h
- create mode 100644 lib/asn1_decoder.c
-
-diff --git a/include/linux/asn1_decoder.h b/include/linux/asn1_decoder.h
-new file mode 100644
-index 0000000..fa2ff5b
---- /dev/null
-+++ b/include/linux/asn1_decoder.h
-@@ -0,0 +1,24 @@
-+/* ASN.1 decoder
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_ASN1_DECODER_H
-+#define _LINUX_ASN1_DECODER_H
-+
-+#include <linux/asn1.h>
-+
-+struct asn1_decoder;
-+
-+extern int asn1_ber_decoder(const struct asn1_decoder *decoder,
-+ void *context,
-+ const unsigned char *data,
-+ size_t datalen);
-+
-+#endif /* _LINUX_ASN1_DECODER_H */
-diff --git a/lib/Makefile b/lib/Makefile
-index b042896..ca856b6 100644
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -140,6 +140,8 @@ $(foreach file, $(libfdt_files), \
- $(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
- lib-$(CONFIG_LIBFDT) += $(libfdt_files)
-
-+obj-$(CONFIG_ASN1) += asn1_decoder.o
-+
- hostprogs-y := gen_crc32table
- clean-files := crc32table.h
-
-diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
-new file mode 100644
-index 0000000..2e4196d
---- /dev/null
-+++ b/lib/asn1_decoder.c
-@@ -0,0 +1,477 @@
-+/* Decoder for ASN.1 BER/DER/CER encoded bytestream
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <linux/export.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/asn1_decoder.h>
-+#include <linux/asn1_ber_bytecode.h>
-+
-+static const unsigned char asn1_op_lengths[ASN1_OP__NR] = {
-+ /* OPC TAG JMP ACT */
-+ [ASN1_OP_MATCH] = 1 + 1,
-+ [ASN1_OP_MATCH_OR_SKIP] = 1 + 1,
-+ [ASN1_OP_MATCH_ACT] = 1 + 1 + 1,
-+ [ASN1_OP_MATCH_ACT_OR_SKIP] = 1 + 1 + 1,
-+ [ASN1_OP_MATCH_JUMP] = 1 + 1 + 1,
-+ [ASN1_OP_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
-+ [ASN1_OP_MATCH_ANY] = 1,
-+ [ASN1_OP_MATCH_ANY_ACT] = 1 + 1,
-+ [ASN1_OP_COND_MATCH_OR_SKIP] = 1 + 1,
-+ [ASN1_OP_COND_MATCH_ACT_OR_SKIP] = 1 + 1 + 1,
-+ [ASN1_OP_COND_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
-+ [ASN1_OP_COND_MATCH_ANY] = 1,
-+ [ASN1_OP_COND_MATCH_ANY_ACT] = 1 + 1,
-+ [ASN1_OP_COND_FAIL] = 1,
-+ [ASN1_OP_COMPLETE] = 1,
-+ [ASN1_OP_ACT] = 1 + 1,
-+ [ASN1_OP_RETURN] = 1,
-+ [ASN1_OP_END_SEQ] = 1,
-+ [ASN1_OP_END_SEQ_OF] = 1 + 1,
-+ [ASN1_OP_END_SET] = 1,
-+ [ASN1_OP_END_SET_OF] = 1 + 1,
-+ [ASN1_OP_END_SEQ_ACT] = 1 + 1,
-+ [ASN1_OP_END_SEQ_OF_ACT] = 1 + 1 + 1,
-+ [ASN1_OP_END_SET_ACT] = 1 + 1,
-+ [ASN1_OP_END_SET_OF_ACT] = 1 + 1 + 1,
-+};
-+
-+/*
-+ * Find the length of an indefinite length object
-+ */
-+static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen,
-+ const char **_errmsg, size_t *_err_dp)
-+{
-+ unsigned char tag, tmp;
-+ size_t dp = 0, len, n;
-+ int indef_level = 1;
-+
-+next_tag:
-+ if (unlikely(datalen - dp < 2)) {
-+ if (datalen == dp)
-+ goto missing_eoc;
-+ goto data_overrun_error;
-+ }
-+
-+ /* Extract a tag from the data */
-+ tag = data[dp++];
-+ if (tag == 0) {
-+ /* It appears to be an EOC. */
-+ if (data[dp++] != 0)
-+ goto invalid_eoc;
-+ if (--indef_level <= 0)
-+ return dp;
-+ goto next_tag;
-+ }
-+
-+ if (unlikely((tag & 0x1f) == 0x1f)) {
-+ do {
-+ if (unlikely(datalen - dp < 2))
-+ goto data_overrun_error;
-+ tmp = data[dp++];
-+ } while (tmp & 0x80);
-+ }
-+
-+ /* Extract the length */
-+ len = data[dp++];
-+ if (len < 0x7f) {
-+ dp += len;
-+ goto next_tag;
-+ }
-+
-+ if (unlikely(len == 0x80)) {
-+ /* Indefinite length */
-+ if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5))
-+ goto indefinite_len_primitive;
-+ indef_level++;
-+ goto next_tag;
-+ }
-+
-+ n = len - 0x80;
-+ if (unlikely(n > sizeof(size_t) - 1))
-+ goto length_too_long;
-+ if (unlikely(n > datalen - dp))
-+ goto data_overrun_error;
-+ for (len = 0; n > 0; n--) {
-+ len <<= 8;
-+ len |= data[dp++];
-+ }
-+ dp += len;
-+ goto next_tag;
-+
-+length_too_long:
-+ *_errmsg = "Unsupported length";
-+ goto error;
-+indefinite_len_primitive:
-+ *_errmsg = "Indefinite len primitive not permitted";
-+ goto error;
-+invalid_eoc:
-+ *_errmsg = "Invalid length EOC";
-+ goto error;
-+data_overrun_error:
-+ *_errmsg = "Data overrun error";
-+ goto error;
-+missing_eoc:
-+ *_errmsg = "Missing EOC in indefinite len cons";
-+error:
-+ *_err_dp = dp;
-+ return -1;
-+}
-+
-+/**
-+ * asn1_ber_decoder - Decoder BER/DER/CER ASN.1 according to pattern
-+ * @decoder: The decoder definition (produced by asn1_compiler)
-+ * @context: The caller's context (to be passed to the action functions)
-+ * @data: The encoded data
-+ * @datasize: The size of the encoded data
-+ *
-+ * Decode BER/DER/CER encoded ASN.1 data according to a bytecode pattern
-+ * produced by asn1_compiler. Action functions are called on marked tags to
-+ * allow the caller to retrieve significant data.
-+ *
-+ * LIMITATIONS:
-+ *
-+ * To keep down the amount of stack used by this function, the following limits
-+ * have been imposed:
-+ *
-+ * (1) This won't handle datalen > 65535 without increasing the size of the
-+ * cons stack elements and length_too_long checking.
-+ *
-+ * (2) The stack of constructed types is 10 deep. If the depth of non-leaf
-+ * constructed types exceeds this, the decode will fail.
-+ *
-+ * (3) The SET type (not the SET OF type) isn't really supported as tracking
-+ * what members of the set have been seen is a pain.
-+ */
-+int asn1_ber_decoder(const struct asn1_decoder *decoder,
-+ void *context,
-+ const unsigned char *data,
-+ size_t datalen)
-+{
-+ const unsigned char *machine = decoder->machine;
-+ const asn1_action_t *actions = decoder->actions;
-+ size_t machlen = decoder->machlen;
-+ enum asn1_opcode op;
-+ unsigned char tag = 0, csp = 0, jsp = 0, optag = 0, hdr = 0;
-+ const char *errmsg;
-+ size_t pc = 0, dp = 0, tdp = 0, len = 0;
-+ int ret;
-+
-+ unsigned char flags = 0;
-+#define FLAG_INDEFINITE_LENGTH 0x01
-+#define FLAG_MATCHED 0x02
-+#define FLAG_CONS 0x20 /* Corresponds to CONS bit in the opcode tag
-+ * - ie. whether or not we are going to parse
-+ * a compound type.
-+ */
-+
-+#define NR_CONS_STACK 10
-+ unsigned short cons_dp_stack[NR_CONS_STACK];
-+ unsigned short cons_datalen_stack[NR_CONS_STACK];
-+ unsigned char cons_hdrlen_stack[NR_CONS_STACK];
-+#define NR_JUMP_STACK 10
-+ unsigned char jump_stack[NR_JUMP_STACK];
-+
-+ if (datalen > 65535)
-+ return -EMSGSIZE;
-+
-+next_op:
-+ pr_debug("next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d J=%d\n",
-+ pc, machlen, dp, datalen, csp, jsp);
-+ if (unlikely(pc >= machlen))
-+ goto machine_overrun_error;
-+ op = machine[pc];
-+ if (unlikely(pc + asn1_op_lengths[op] > machlen))
-+ goto machine_overrun_error;
-+
-+ /* If this command is meant to match a tag, then do that before
-+ * evaluating the command.
-+ */
-+ if (op <= ASN1_OP__MATCHES_TAG) {
-+ unsigned char tmp;
-+
-+ /* Skip conditional matches if possible */
-+ if ((op & ASN1_OP_MATCH__COND &&
-+ flags & FLAG_MATCHED) ||
-+ dp == datalen) {
-+ pc += asn1_op_lengths[op];
-+ goto next_op;
-+ }
-+
-+ flags = 0;
-+ hdr = 2;
-+
-+ /* Extract a tag from the data */
-+ if (unlikely(dp >= datalen - 1))
-+ goto data_overrun_error;
-+ tag = data[dp++];
-+ if (unlikely((tag & 0x1f) == 0x1f))
-+ goto long_tag_not_supported;
-+
-+ if (op & ASN1_OP_MATCH__ANY) {
-+ pr_debug("- any %02x\n", tag);
-+ } else {
-+ /* Extract the tag from the machine
-+ * - Either CONS or PRIM are permitted in the data if
-+ * CONS is not set in the op stream, otherwise CONS
-+ * is mandatory.
-+ */
-+ optag = machine[pc + 1];
-+ flags |= optag & FLAG_CONS;
-+
-+ /* Determine whether the tag matched */
-+ tmp = optag ^ tag;
-+ tmp &= ~(optag & ASN1_CONS_BIT);
-+ pr_debug("- match? %02x %02x %02x\n", tag, optag, tmp);
-+ if (tmp != 0) {
-+ /* All odd-numbered tags are MATCH_OR_SKIP. */
-+ if (op & ASN1_OP_MATCH__SKIP) {
-+ pc += asn1_op_lengths[op];
-+ dp--;
-+ goto next_op;
-+ }
-+ goto tag_mismatch;
-+ }
-+ }
-+ flags |= FLAG_MATCHED;
-+
-+ len = data[dp++];
-+ if (len > 0x7f) {
-+ if (unlikely(len == 0x80)) {
-+ /* Indefinite length */
-+ if (unlikely(!(tag & ASN1_CONS_BIT)))
-+ goto indefinite_len_primitive;
-+ flags |= FLAG_INDEFINITE_LENGTH;
-+ if (unlikely(2 > datalen - dp))
-+ goto data_overrun_error;
-+ } else {
-+ int n = len - 0x80;
-+ if (unlikely(n > 2))
-+ goto length_too_long;
-+ if (unlikely(dp >= datalen - n))
-+ goto data_overrun_error;
-+ hdr += n;
-+ for (len = 0; n > 0; n--) {
-+ len <<= 8;
-+ len |= data[dp++];
-+ }
-+ if (unlikely(len > datalen - dp))
-+ goto data_overrun_error;
-+ }
-+ }
-+
-+ if (flags & FLAG_CONS) {
-+ /* For expected compound forms, we stack the positions
-+ * of the start and end of the data.
-+ */
-+ if (unlikely(csp >= NR_CONS_STACK))
-+ goto cons_stack_overflow;
-+ cons_dp_stack[csp] = dp;
-+ cons_hdrlen_stack[csp] = hdr;
-+ if (!(flags & FLAG_INDEFINITE_LENGTH)) {
-+ cons_datalen_stack[csp] = datalen;
-+ datalen = dp + len;
-+ } else {
-+ cons_datalen_stack[csp] = 0;
-+ }
-+ csp++;
-+ }
-+
-+ pr_debug("- TAG: %02x %zu%s\n",
-+ tag, len, flags & FLAG_CONS ? " CONS" : "");
-+ tdp = dp;
-+ }
-+
-+ /* Decide how to handle the operation */
-+ switch (op) {
-+ case ASN1_OP_MATCH_ANY_ACT:
-+ case ASN1_OP_COND_MATCH_ANY_ACT:
-+ ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
-+ if (ret < 0)
-+ return ret;
-+ goto skip_data;
-+
-+ case ASN1_OP_MATCH_ACT:
-+ case ASN1_OP_MATCH_ACT_OR_SKIP:
-+ case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
-+ ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
-+ if (ret < 0)
-+ return ret;
-+ goto skip_data;
-+
-+ case ASN1_OP_MATCH:
-+ case ASN1_OP_MATCH_OR_SKIP:
-+ case ASN1_OP_MATCH_ANY:
-+ case ASN1_OP_COND_MATCH_OR_SKIP:
-+ case ASN1_OP_COND_MATCH_ANY:
-+ skip_data:
-+ if (!(flags & FLAG_CONS)) {
-+ if (flags & FLAG_INDEFINITE_LENGTH) {
-+ len = asn1_find_indefinite_length(
-+ data + dp, datalen - dp, &errmsg, &dp);
-+ if (len < 0)
-+ goto error;
-+ }
-+ pr_debug("- LEAF: %zu\n", len);
-+ dp += len;
-+ }
-+ pc += asn1_op_lengths[op];
-+ goto next_op;
-+
-+ case ASN1_OP_MATCH_JUMP:
-+ case ASN1_OP_MATCH_JUMP_OR_SKIP:
-+ case ASN1_OP_COND_MATCH_JUMP_OR_SKIP:
-+ pr_debug("- MATCH_JUMP\n");
-+ if (unlikely(jsp == NR_JUMP_STACK))
-+ goto jump_stack_overflow;
-+ jump_stack[jsp++] = pc + asn1_op_lengths[op];
-+ pc = machine[pc + 2];
-+ goto next_op;
-+
-+ case ASN1_OP_COND_FAIL:
-+ if (unlikely(!(flags & FLAG_MATCHED)))
-+ goto tag_mismatch;
-+ pc += asn1_op_lengths[op];
-+ goto next_op;
-+
-+ case ASN1_OP_COMPLETE:
-+ if (unlikely(jsp != 0 || csp != 0)) {
-+ pr_err("ASN.1 decoder error: Stacks not empty at completion (%u, %u)\n",
-+ jsp, csp);
-+ return -EBADMSG;
-+ }
-+ return 0;
-+
-+ case ASN1_OP_END_SET:
-+ case ASN1_OP_END_SET_ACT:
-+ if (unlikely(!(flags & FLAG_MATCHED)))
-+ goto tag_mismatch;
-+ case ASN1_OP_END_SEQ:
-+ case ASN1_OP_END_SET_OF:
-+ case ASN1_OP_END_SEQ_OF:
-+ case ASN1_OP_END_SEQ_ACT:
-+ case ASN1_OP_END_SET_OF_ACT:
-+ case ASN1_OP_END_SEQ_OF_ACT:
-+ if (unlikely(csp <= 0))
-+ goto cons_stack_underflow;
-+ csp--;
-+ tdp = cons_dp_stack[csp];
-+ hdr = cons_hdrlen_stack[csp];
-+ len = datalen;
-+ datalen = cons_datalen_stack[csp];
-+ pr_debug("- end cons t=%zu dp=%zu l=%zu/%zu\n",
-+ tdp, dp, len, datalen);
-+ if (datalen == 0) {
-+ /* Indefinite length - check for the EOC. */
-+ datalen = len;
-+ if (unlikely(datalen - dp < 2))
-+ goto data_overrun_error;
-+ if (data[dp++] != 0) {
-+ if (op & ASN1_OP_END__OF) {
-+ dp--;
-+ csp++;
-+ pc = machine[pc + 1];
-+ pr_debug("- continue\n");
-+ goto next_op;
-+ }
-+ goto missing_eoc;
-+ }
-+ if (data[dp++] != 0)
-+ goto invalid_eoc;
-+ len = dp - tdp - 2;
-+ } else {
-+ if (dp < len && (op & ASN1_OP_END__OF)) {
-+ datalen = len;
-+ csp++;
-+ pc = machine[pc + 1];
-+ pr_debug("- continue\n");
-+ goto next_op;
-+ }
-+ if (dp != len)
-+ goto cons_length_error;
-+ len -= tdp;
-+ pr_debug("- cons len l=%zu d=%zu\n", len, dp - tdp);
-+ }
-+
-+ if (op & ASN1_OP_END__ACT) {
-+ unsigned char act;
-+ if (op & ASN1_OP_END__OF)
-+ act = machine[pc + 2];
-+ else
-+ act = machine[pc + 1];
-+ ret = actions[act](context, hdr, 0, data + tdp, len);
-+ }
-+ pc += asn1_op_lengths[op];
-+ goto next_op;
-+
-+ case ASN1_OP_ACT:
-+ ret = actions[machine[pc + 1]](context, hdr, tag, data + tdp, len);
-+ pc += asn1_op_lengths[op];
-+ goto next_op;
-+
-+ case ASN1_OP_RETURN:
-+ if (unlikely(jsp <= 0))
-+ goto jump_stack_underflow;
-+ pc = jump_stack[--jsp];
-+ goto next_op;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Shouldn't reach here */
-+ pr_err("ASN.1 decoder error: Found reserved opcode (%u)\n", op);
-+ return -EBADMSG;
-+
-+data_overrun_error:
-+ errmsg = "Data overrun error";
-+ goto error;
-+machine_overrun_error:
-+ errmsg = "Machine overrun error";
-+ goto error;
-+jump_stack_underflow:
-+ errmsg = "Jump stack underflow";
-+ goto error;
-+jump_stack_overflow:
-+ errmsg = "Jump stack overflow";
-+ goto error;
-+cons_stack_underflow:
-+ errmsg = "Cons stack underflow";
-+ goto error;
-+cons_stack_overflow:
-+ errmsg = "Cons stack overflow";
-+ goto error;
-+cons_length_error:
-+ errmsg = "Cons length error";
-+ goto error;
-+missing_eoc:
-+ errmsg = "Missing EOC in indefinite len cons";
-+ goto error;
-+invalid_eoc:
-+ errmsg = "Invalid length EOC";
-+ goto error;
-+length_too_long:
-+ errmsg = "Unsupported length";
-+ goto error;
-+indefinite_len_primitive:
-+ errmsg = "Indefinite len primitive not permitted";
-+ goto error;
-+tag_mismatch:
-+ errmsg = "Unexpected tag";
-+ goto error;
-+long_tag_not_supported:
-+ errmsg = "Long tag not supported";
-+error:
-+ pr_debug("\nASN1: %s [m=%zu d=%zu ot=%02x t=%02x l=%zu]\n",
-+ errmsg, pc, dp, optag, tag, len);
-+ return -EBADMSG;
-+}
-+EXPORT_SYMBOL_GPL(asn1_ber_decoder);
---
-1.7.12.1
-
-
-From 686b0b5e3549b711c0bcc405d833697ff5e2344d Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Mon, 24 Sep 2012 17:11:27 +0100
-Subject: [PATCH 16/37] MPILIB: Provide a function to read raw data into an
- MPI
-
-Provide a function to read raw data of a predetermined size into an MPI rather
-than expecting the size to be encoded within the data. The data is assumed to
-represent an unsigned integer, and the resulting MPI will be positive.
-
-The function looks like this:
-
- MPI mpi_read_raw_data(const void *, size_t);
-
-This is useful for reading ASN.1 integer primitives where the length is encoded
-in the ASN.1 metadata.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- include/linux/mpi.h | 1 +
- lib/mpi/mpicoder.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 56 insertions(+)
-
-diff --git a/include/linux/mpi.h b/include/linux/mpi.h
-index d02cca6..5af1b81 100644
---- a/include/linux/mpi.h
-+++ b/include/linux/mpi.h
-@@ -76,6 +76,7 @@ void mpi_swap(MPI a, MPI b);
-
- /*-- mpicoder.c --*/
- MPI do_encode_md(const void *sha_buffer, unsigned nbits);
-+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
- MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
- int mpi_fromstr(MPI val, const char *str);
- u32 mpi_get_keyid(MPI a, u32 *keyid);
-diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
-index f0fa659..3962b7f 100644
---- a/lib/mpi/mpicoder.c
-+++ b/lib/mpi/mpicoder.c
-@@ -18,10 +18,65 @@
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-+#include <linux/bitops.h>
-+#include <asm-generic/bitops/count_zeros.h>
- #include "mpi-internal.h"
-
- #define MAX_EXTERN_MPI_BITS 16384
-
-+/**
-+ * mpi_read_raw_data - Read a raw byte stream as a positive integer
-+ * @xbuffer: The data to read
-+ * @nbytes: The amount of data to read
-+ */
-+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
-+{
-+ const uint8_t *buffer = xbuffer;
-+ int i, j;
-+ unsigned nbits, nlimbs;
-+ mpi_limb_t a;
-+ MPI val = NULL;
-+
-+ while (nbytes >= 0 && buffer[0] == 0) {
-+ buffer++;
-+ nbytes--;
-+ }
-+
-+ nbits = nbytes * 8;
-+ if (nbits > MAX_EXTERN_MPI_BITS) {
-+ pr_info("MPI: mpi too large (%u bits)\n", nbits);
-+ return NULL;
-+ }
-+ if (nbytes > 0)
-+ nbits -= count_leading_zeros(buffer[0]);
-+ else
-+ nbits = 0;
-+
-+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
-+ val = mpi_alloc(nlimbs);
-+ if (!val)
-+ return NULL;
-+ val->nbits = nbits;
-+ val->sign = 0;
-+ val->nlimbs = nlimbs;
-+
-+ if (nbytes > 0) {
-+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
-+ i %= BYTES_PER_MPI_LIMB;
-+ for (j = nlimbs; j > 0; j--) {
-+ a = 0;
-+ for (; i < BYTES_PER_MPI_LIMB; i++) {
-+ a <<= 8;
-+ a |= *buffer++;
-+ }
-+ i = 0;
-+ val->d[j - 1] = a;
-+ }
-+ }
-+ return val;
-+}
-+EXPORT_SYMBOL_GPL(mpi_read_raw_data);
-+
- MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
- {
- const uint8_t *buffer = xbuffer;
---
-1.7.12.1
-
-
-From c6ca1b7770b65d0639fb84a7afead457ff22c8d4 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Mon, 24 Sep 2012 17:11:48 +0100
-Subject: [PATCH 17/37] X.509: Add a crypto key parser for binary (DER) X.509
- certificates
-
-Add a crypto key parser for binary (DER) encoded X.509 certificates. The
-certificate is parsed and, if possible, the signature is verified.
-
-An X.509 key can be added like this:
-
- # keyctl padd crypto bar @s </tmp/x509.cert
- 15768135
-
-and displayed like this:
-
- # cat /proc/keys
- 00f09a47 I--Q--- 1 perm 39390000 0 0 asymmetri bar: X509.RSA e9fd6d08 []
-
-Note that this only works with binary certificates. PEM encoded certificates
-are ignored by the parser.
-
-Note also that the X.509 key ID is not congruent with the PGP key ID, but for
-the moment, they will match.
-
-If a NULL or "" name is given to add_key(), then the parser will generate a key
-description from the CertificateSerialNumber and Name fields of the
-TBSCertificate:
-
- 00aefc4e I--Q--- 1 perm 39390000 0 0 asymmetri bfbc0cd76d050ea4:/C=GB/L=Cambridge/O=Red Hat/CN=kernel key: X509.RSA 0c688c7b []
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/.gitignore | 1 +
- crypto/asymmetric_keys/Kconfig | 10 +
- crypto/asymmetric_keys/Makefile | 17 +
- crypto/asymmetric_keys/x509.asn1 | 60 ++++
- crypto/asymmetric_keys/x509_cert_parser.c | 497 ++++++++++++++++++++++++++++++
- crypto/asymmetric_keys/x509_parser.h | 36 +++
- crypto/asymmetric_keys/x509_public_key.c | 207 +++++++++++++
- crypto/asymmetric_keys/x509_rsakey.asn1 | 4 +
- 8 files changed, 832 insertions(+)
- create mode 100644 crypto/asymmetric_keys/.gitignore
- create mode 100644 crypto/asymmetric_keys/x509.asn1
- create mode 100644 crypto/asymmetric_keys/x509_cert_parser.c
- create mode 100644 crypto/asymmetric_keys/x509_parser.h
- create mode 100644 crypto/asymmetric_keys/x509_public_key.c
- create mode 100644 crypto/asymmetric_keys/x509_rsakey.asn1
-
-diff --git a/crypto/asymmetric_keys/.gitignore b/crypto/asymmetric_keys/.gitignore
-new file mode 100644
-index 0000000..ee32837
---- /dev/null
-+++ b/crypto/asymmetric_keys/.gitignore
-@@ -0,0 +1 @@
-+*-asn1.[ch]
-diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
-index 561759d..6d2c2ea 100644
---- a/crypto/asymmetric_keys/Kconfig
-+++ b/crypto/asymmetric_keys/Kconfig
-@@ -25,4 +25,14 @@ config PUBLIC_KEY_ALGO_RSA
- help
- This option enables support for the RSA algorithm (PKCS#1, RFC3447).
-
-+config X509_CERTIFICATE_PARSER
-+ tristate "X.509 certificate parser"
-+ depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
-+ select ASN1
-+ select OID_REGISTRY
-+ help
-+ This option procides support for parsing X.509 format blobs for key
-+ data and provides the ability to instantiate a crypto key from a
-+ public key packet found inside the certificate.
-+
- endif # ASYMMETRIC_KEY_TYPE
-diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
-index 7c92691..0727204 100644
---- a/crypto/asymmetric_keys/Makefile
-+++ b/crypto/asymmetric_keys/Makefile
-@@ -8,3 +8,20 @@ asymmetric_keys-y := asymmetric_type.o signature.o
-
- obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
- obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
-+
-+#
-+# X.509 Certificate handling
-+#
-+obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
-+x509_key_parser-y := \
-+ x509-asn1.o \
-+ x509_rsakey-asn1.o \
-+ x509_cert_parser.o \
-+ x509_public_key.o
-+
-+$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h
-+$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
-+$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
-+
-+clean-files += x509-asn1.c x509-asn1.h
-+clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
-diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
-new file mode 100644
-index 0000000..bf32b3d
---- /dev/null
-+++ b/crypto/asymmetric_keys/x509.asn1
-@@ -0,0 +1,60 @@
-+Certificate ::= SEQUENCE {
-+ tbsCertificate TBSCertificate ({ x509_note_tbs_certificate }),
-+ signatureAlgorithm AlgorithmIdentifier,
-+ signature BIT STRING ({ x509_note_signature })
-+ }
-+
-+TBSCertificate ::= SEQUENCE {
-+ version [ 0 ] Version DEFAULT,
-+ serialNumber CertificateSerialNumber,
-+ signature AlgorithmIdentifier ({ x509_note_pkey_algo }),
-+ issuer Name ({ x509_note_issuer }),
-+ validity Validity,
-+ subject Name ({ x509_note_subject }),
-+ subjectPublicKeyInfo SubjectPublicKeyInfo,
-+ issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
-+ subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
-+ extensions [ 3 ] Extensions OPTIONAL
-+ }
-+
-+Version ::= INTEGER
-+CertificateSerialNumber ::= INTEGER
-+
-+AlgorithmIdentifier ::= SEQUENCE {
-+ algorithm OBJECT IDENTIFIER ({ x509_note_OID }),
-+ parameters ANY OPTIONAL
-+}
-+
-+Name ::= SEQUENCE OF RelativeDistinguishedName
-+
-+RelativeDistinguishedName ::= SET OF AttributeValueAssertion
-+
-+AttributeValueAssertion ::= SEQUENCE {
-+ attributeType OBJECT IDENTIFIER ({ x509_note_OID }),
-+ attributeValue ANY ({ x509_extract_name_segment })
-+ }
-+
-+Validity ::= SEQUENCE {
-+ notBefore Time ({ x509_note_not_before }),
-+ notAfter Time ({ x509_note_not_after })
-+ }
-+
-+Time ::= CHOICE {
-+ utcTime UTCTime,
-+ generalTime GeneralizedTime
-+ }
-+
-+SubjectPublicKeyInfo ::= SEQUENCE {
-+ algorithm AlgorithmIdentifier,
-+ subjectPublicKey BIT STRING ({ x509_extract_key_data })
-+ }
-+
-+UniqueIdentifier ::= BIT STRING
-+
-+Extensions ::= SEQUENCE OF Extension
-+
-+Extension ::= SEQUENCE {
-+ extnid OBJECT IDENTIFIER ({ x509_note_OID }),
-+ critical BOOLEAN DEFAULT,
-+ extnValue OCTET STRING ({ x509_process_extension })
-+ }
-diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
-new file mode 100644
-index 0000000..8fcac94
---- /dev/null
-+++ b/crypto/asymmetric_keys/x509_cert_parser.c
-@@ -0,0 +1,497 @@
-+/* X.509 certificate parser
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#define pr_fmt(fmt) "X.509: "fmt
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/err.h>
-+#include <linux/oid_registry.h>
-+#include "public_key.h"
-+#include "x509_parser.h"
-+#include "x509-asn1.h"
-+#include "x509_rsakey-asn1.h"
-+
-+struct x509_parse_context {
-+ struct x509_certificate *cert; /* Certificate being constructed */
-+ unsigned long data; /* Start of data */
-+ const void *cert_start; /* Start of cert content */
-+ const void *key; /* Key data */
-+ size_t key_size; /* Size of key data */
-+ enum OID last_oid; /* Last OID encountered */
-+ enum OID algo_oid; /* Algorithm OID */
-+ unsigned char nr_mpi; /* Number of MPIs stored */
-+ u8 o_size; /* Size of organizationName (O) */
-+ u8 cn_size; /* Size of commonName (CN) */
-+ u8 email_size; /* Size of emailAddress */
-+ u16 o_offset; /* Offset of organizationName (O) */
-+ u16 cn_offset; /* Offset of commonName (CN) */
-+ u16 email_offset; /* Offset of emailAddress */
-+};
-+
-+/*
-+ * Free an X.509 certificate
-+ */
-+void x509_free_certificate(struct x509_certificate *cert)
-+{
-+ if (cert) {
-+ public_key_destroy(cert->pub);
-+ kfree(cert->issuer);
-+ kfree(cert->subject);
-+ kfree(cert->fingerprint);
-+ kfree(cert->authority);
-+ kfree(cert);
-+ }
-+}
-+
-+/*
-+ * Parse an X.509 certificate
-+ */
-+struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
-+{
-+ struct x509_certificate *cert;
-+ struct x509_parse_context *ctx;
-+ long ret;
-+
-+ ret = -ENOMEM;
-+ cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
-+ if (!cert)
-+ goto error_no_cert;
-+ cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
-+ if (!cert->pub)
-+ goto error_no_ctx;
-+ ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
-+ if (!ctx)
-+ goto error_no_ctx;
-+
-+ ctx->cert = cert;
-+ ctx->data = (unsigned long)data;
-+
-+ /* Attempt to decode the certificate */
-+ ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
-+ if (ret < 0)
-+ goto error_decode;
-+
-+ /* Decode the public key */
-+ ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
-+ ctx->key, ctx->key_size);
-+ if (ret < 0)
-+ goto error_decode;
-+
-+ kfree(ctx);
-+ return cert;
-+
-+error_decode:
-+ kfree(ctx);
-+error_no_ctx:
-+ x509_free_certificate(cert);
-+error_no_cert:
-+ return ERR_PTR(ret);
-+}
-+
-+/*
-+ * Note an OID when we find one for later processing when we know how
-+ * to interpret it.
-+ */
-+int x509_note_OID(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ ctx->last_oid = look_up_OID(value, vlen);
-+ if (ctx->last_oid == OID__NR) {
-+ char buffer[50];
-+ sprint_oid(value, vlen, buffer, sizeof(buffer));
-+ pr_debug("Unknown OID: [%zu] %s\n",
-+ (unsigned long)value - ctx->data, buffer);
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Save the position of the TBS data so that we can check the signature over it
-+ * later.
-+ */
-+int x509_note_tbs_certificate(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
-+ hdrlen, tag, (unsigned long)value - ctx->data, vlen);
-+
-+ ctx->cert->tbs = value - hdrlen;
-+ ctx->cert->tbs_size = vlen + hdrlen;
-+ return 0;
-+}
-+
-+/*
-+ * Record the public key algorithm
-+ */
-+int x509_note_pkey_algo(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ pr_debug("PubKey Algo: %u\n", ctx->last_oid);
-+
-+ switch (ctx->last_oid) {
-+ case OID_md2WithRSAEncryption:
-+ case OID_md3WithRSAEncryption:
-+ default:
-+ return -ENOPKG; /* Unsupported combination */
-+
-+ case OID_md4WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_MD5;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+
-+ case OID_sha1WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA1;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+
-+ case OID_sha256WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA256;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+
-+ case OID_sha384WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA384;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+
-+ case OID_sha512WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA512;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+
-+ case OID_sha224WithRSAEncryption:
-+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA224;
-+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
-+ break;
-+ }
-+
-+ ctx->algo_oid = ctx->last_oid;
-+ return 0;
-+}
-+
-+/*
-+ * Note the whereabouts and type of the signature.
-+ */
-+int x509_note_signature(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
-+
-+ if (ctx->last_oid != ctx->algo_oid) {
-+ pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
-+ ctx->algo_oid, ctx->last_oid);
-+ return -EINVAL;
-+ }
-+
-+ ctx->cert->sig = value;
-+ ctx->cert->sig_size = vlen;
-+ return 0;
-+}
-+
-+/*
-+ * Note some of the name segments from which we'll fabricate a name.
-+ */
-+int x509_extract_name_segment(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ switch (ctx->last_oid) {
-+ case OID_commonName:
-+ ctx->cn_size = vlen;
-+ ctx->cn_offset = (unsigned long)value - ctx->data;
-+ break;
-+ case OID_organizationName:
-+ ctx->o_size = vlen;
-+ ctx->o_offset = (unsigned long)value - ctx->data;
-+ break;
-+ case OID_email_address:
-+ ctx->email_size = vlen;
-+ ctx->email_offset = (unsigned long)value - ctx->data;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Fabricate and save the issuer and subject names
-+ */
-+static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
-+ unsigned char tag,
-+ char **_name, size_t vlen)
-+{
-+ const void *name, *data = (const void *)ctx->data;
-+ size_t namesize;
-+ char *buffer;
-+
-+ if (*_name)
-+ return -EINVAL;
-+
-+ /* Empty name string if no material */
-+ if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
-+ buffer = kmalloc(1, GFP_KERNEL);
-+ if (!buffer)
-+ return -ENOMEM;
-+ buffer[0] = 0;
-+ goto done;
-+ }
-+
-+ if (ctx->cn_size && ctx->o_size) {
-+ /* Consider combining O and CN, but use only the CN if it is
-+ * prefixed by the O, or a significant portion thereof.
-+ */
-+ namesize = ctx->cn_size;
-+ name = data + ctx->cn_offset;
-+ if (ctx->cn_size >= ctx->o_size &&
-+ memcmp(data + ctx->cn_offset, data + ctx->o_offset,
-+ ctx->o_size) == 0)
-+ goto single_component;
-+ if (ctx->cn_size >= 7 &&
-+ ctx->o_size >= 7 &&
-+ memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
-+ goto single_component;
-+
-+ buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
-+ GFP_KERNEL);
-+ if (!buffer)
-+ return -ENOMEM;
-+
-+ memcpy(buffer,
-+ data + ctx->o_offset, ctx->o_size);
-+ buffer[ctx->o_size + 0] = ':';
-+ buffer[ctx->o_size + 1] = ' ';
-+ memcpy(buffer + ctx->o_size + 2,
-+ data + ctx->cn_offset, ctx->cn_size);
-+ buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
-+ goto done;
-+
-+ } else if (ctx->cn_size) {
-+ namesize = ctx->cn_size;
-+ name = data + ctx->cn_offset;
-+ } else if (ctx->o_size) {
-+ namesize = ctx->o_size;
-+ name = data + ctx->o_offset;
-+ } else {
-+ namesize = ctx->email_size;
-+ name = data + ctx->email_offset;
-+ }
-+
-+single_component:
-+ buffer = kmalloc(namesize + 1, GFP_KERNEL);
-+ if (!buffer)
-+ return -ENOMEM;
-+ memcpy(buffer, name, namesize);
-+ buffer[namesize] = 0;
-+
-+done:
-+ *_name = buffer;
-+ ctx->cn_size = 0;
-+ ctx->o_size = 0;
-+ ctx->email_size = 0;
-+ return 0;
-+}
-+
-+int x509_note_issuer(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
-+}
-+
-+int x509_note_subject(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
-+}
-+
-+/*
-+ * Extract the data for the public key algorithm
-+ */
-+int x509_extract_key_data(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+
-+ if (ctx->last_oid != OID_rsaEncryption)
-+ return -ENOPKG;
-+
-+ /* There seems to be an extraneous 0 byte on the front of the data */
-+ ctx->cert->pkey_algo = PKEY_ALGO_RSA;
-+ ctx->key = value + 1;
-+ ctx->key_size = vlen - 1;
-+ return 0;
-+}
-+
-+/*
-+ * Extract a RSA public key value
-+ */
-+int rsa_extract_mpi(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ MPI mpi;
-+
-+ if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
-+ pr_err("Too many public key MPIs in certificate\n");
-+ return -EBADMSG;
-+ }
-+
-+ mpi = mpi_read_raw_data(value, vlen);
-+ if (!mpi)
-+ return -ENOMEM;
-+
-+ ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
-+ return 0;
-+}
-+
-+/*
-+ * Process certificate extensions that are used to qualify the certificate.
-+ */
-+int x509_process_extension(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ const unsigned char *v = value;
-+ char *f;
-+ int i;
-+
-+ pr_debug("Extension: %u\n", ctx->last_oid);
-+
-+ if (ctx->last_oid == OID_subjectKeyIdentifier) {
-+ /* Get hold of the key fingerprint */
-+ if (vlen < 3)
-+ return -EBADMSG;
-+ if (v[0] != ASN1_OTS || v[1] != vlen - 2)
-+ return -EBADMSG;
-+ v += 2;
-+ vlen -= 2;
-+
-+ f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
-+ if (!f)
-+ return -ENOMEM;
-+ for (i = 0; i < vlen; i++)
-+ sprintf(f + i * 2, "%02x", v[i]);
-+ pr_debug("fingerprint %s\n", f);
-+ ctx->cert->fingerprint = f;
-+ return 0;
-+ }
-+
-+ if (ctx->last_oid == OID_authorityKeyIdentifier) {
-+ /* Get hold of the CA key fingerprint */
-+ if (vlen < 5)
-+ return -EBADMSG;
-+ if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) ||
-+ v[1] != vlen - 2 ||
-+ v[2] != (ASN1_CONT << 6) ||
-+ v[3] != vlen - 4)
-+ return -EBADMSG;
-+ v += 4;
-+ vlen -= 4;
-+
-+ f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
-+ if (!f)
-+ return -ENOMEM;
-+ for (i = 0; i < vlen; i++)
-+ sprintf(f + i * 2, "%02x", v[i]);
-+ pr_debug("authority %s\n", f);
-+ ctx->cert->authority = f;
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Record a certificate time.
-+ */
-+static int x509_note_time(time_t *_time, size_t hdrlen,
-+ unsigned char tag,
-+ const unsigned char *value, size_t vlen)
-+{
-+ unsigned YY, MM, DD, hh, mm, ss;
-+ const unsigned char *p = value;
-+
-+#define dec2bin(X) ((X) - '0')
-+#define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
-+
-+ if (tag == ASN1_UNITIM) {
-+ /* UTCTime: YYMMDDHHMMSSZ */
-+ if (vlen != 13)
-+ goto unsupported_time;
-+ YY = DD2bin(p);
-+ if (YY > 50)
-+ YY += 1900;
-+ else
-+ YY += 2000;
-+ } else if (tag == ASN1_GENTIM) {
-+ /* GenTime: YYYYMMDDHHMMSSZ */
-+ if (vlen != 15)
-+ goto unsupported_time;
-+ YY = DD2bin(p) * 100 + DD2bin(p);
-+ } else {
-+ goto unsupported_time;
-+ }
-+
-+ MM = DD2bin(p);
-+ DD = DD2bin(p);
-+ hh = DD2bin(p);
-+ mm = DD2bin(p);
-+ ss = DD2bin(p);
-+
-+ if (*p != 'Z')
-+ goto unsupported_time;
-+
-+ *_time = mktime(YY, MM, DD, hh, mm, ss);
-+ return 0;
-+
-+unsupported_time:
-+ pr_debug("Got unsupported time [tag %02x]: '%*.*s'\n",
-+ tag, (int)vlen, (int)vlen, value);
-+ return -EBADMSG;
-+}
-+
-+int x509_note_not_before(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ return x509_note_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
-+}
-+
-+int x509_note_not_after(void *context, size_t hdrlen,
-+ unsigned char tag,
-+ const void *value, size_t vlen)
-+{
-+ struct x509_parse_context *ctx = context;
-+ return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
-+}
-diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
-new file mode 100644
-index 0000000..635053f
---- /dev/null
-+++ b/crypto/asymmetric_keys/x509_parser.h
-@@ -0,0 +1,36 @@
-+/* X.509 certificate parser internal definitions
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <crypto/public_key.h>
-+
-+struct x509_certificate {
-+ struct x509_certificate *next;
-+ struct public_key *pub; /* Public key details */
-+ char *issuer; /* Name of certificate issuer */
-+ char *subject; /* Name of certificate subject */
-+ char *fingerprint; /* Key fingerprint as hex */
-+ char *authority; /* Authority key fingerprint as hex */
-+ time_t valid_from;
-+ time_t valid_to;
-+ enum pkey_algo pkey_algo : 8; /* Public key algorithm */
-+ enum pkey_algo sig_pkey_algo : 8; /* Signature public key algorithm */
-+ enum pkey_hash_algo sig_hash_algo : 8; /* Signature hash algorithm */
-+ const void *tbs; /* Signed data */
-+ size_t tbs_size; /* Size of signed data */
-+ const void *sig; /* Signature data */
-+ size_t sig_size; /* Size of sigature */
-+};
-+
-+/*
-+ * x509_cert_parser.c
-+ */
-+extern void x509_free_certificate(struct x509_certificate *cert);
-+extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
-diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
-new file mode 100644
-index 0000000..716917c
---- /dev/null
-+++ b/crypto/asymmetric_keys/x509_public_key.c
-@@ -0,0 +1,207 @@
-+/* Instantiate a public key crypto key from an X.509 Certificate
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#define pr_fmt(fmt) "X.509: "fmt
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/err.h>
-+#include <linux/mpi.h>
-+#include <linux/asn1_decoder.h>
-+#include <keys/asymmetric-subtype.h>
-+#include <keys/asymmetric-parser.h>
-+#include <crypto/hash.h>
-+#include "asymmetric_keys.h"
-+#include "public_key.h"
-+#include "x509_parser.h"
-+
-+static const
-+struct public_key_algorithm *x509_public_key_algorithms[PKEY_ALGO__LAST] = {
-+ [PKEY_ALGO_DSA] = NULL,
-+#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
-+ defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
-+ [PKEY_ALGO_RSA] = &RSA_public_key_algorithm,
-+#endif
-+};
-+
-+/*
-+ * Check the signature on a certificate using the provided public key
-+ */
-+static int x509_check_signature(const struct public_key *pub,
-+ const struct x509_certificate *cert)
-+{
-+ struct public_key_signature *sig;
-+ struct crypto_shash *tfm;
-+ struct shash_desc *desc;
-+ size_t digest_size, desc_size;
-+ int ret;
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ /* Allocate the hashing algorithm we're going to need and find out how
-+ * big the hash operational data will be.
-+ */
-+ tfm = crypto_alloc_shash(pkey_hash_algo[cert->sig_hash_algo], 0, 0);
-+ if (IS_ERR(tfm))
-+ return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
-+
-+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
-+ digest_size = crypto_shash_digestsize(tfm);
-+
-+ /* We allocate the hash operational data storage on the end of our
-+ * context data.
-+ */
-+ ret = -ENOMEM;
-+ sig = kzalloc(sizeof(*sig) + desc_size + digest_size, GFP_KERNEL);
-+ if (!sig)
-+ goto error_no_sig;
-+
-+ sig->pkey_hash_algo = cert->sig_hash_algo;
-+ sig->digest = (u8 *)sig + sizeof(*sig) + desc_size;
-+ sig->digest_size = digest_size;
-+
-+ desc = (void *)sig + sizeof(*sig);
-+ desc->tfm = tfm;
-+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-+
-+ ret = crypto_shash_init(desc);
-+ if (ret < 0)
-+ goto error;
-+
-+ ret = -ENOMEM;
-+ sig->rsa.s = mpi_read_raw_data(cert->sig, cert->sig_size);
-+ if (!sig->rsa.s)
-+ goto error;
-+
-+ ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
-+ if (ret < 0)
-+ goto error_mpi;
-+
-+ ret = pub->algo->verify_signature(pub, sig);
-+
-+ pr_debug("Cert Verification: %d\n", ret);
-+
-+error_mpi:
-+ mpi_free(sig->rsa.s);
-+error:
-+ kfree(sig);
-+error_no_sig:
-+ crypto_free_shash(tfm);
-+
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ret;
-+}
-+
-+/*
-+ * Attempt to parse a data blob for a key as an X509 certificate.
-+ */
-+static int x509_key_preparse(struct key_preparsed_payload *prep)
-+{
-+ struct x509_certificate *cert;
-+ time_t now;
-+ size_t srlen, sulen;
-+ char *desc = NULL;
-+ int ret;
-+
-+ cert = x509_cert_parse(prep->data, prep->datalen);
-+ if (IS_ERR(cert))
-+ return PTR_ERR(cert);
-+
-+ pr_devel("Cert Issuer: %s\n", cert->issuer);
-+ pr_devel("Cert Subject: %s\n", cert->subject);
-+ pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
-+ pr_devel("Cert Valid: %lu - %lu\n", cert->valid_from, cert->valid_to);
-+ pr_devel("Cert Signature: %s + %s\n",
-+ pkey_algo[cert->sig_pkey_algo],
-+ pkey_hash_algo[cert->sig_hash_algo]);
-+
-+ if (!cert->fingerprint || !cert->authority) {
-+ pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n",
-+ cert->subject);
-+ ret = -EKEYREJECTED;
-+ goto error_free_cert;
-+ }
-+
-+ now = CURRENT_TIME.tv_sec;
-+ if (now < cert->valid_from) {
-+ pr_warn("Cert %s is not yet valid\n", cert->fingerprint);
-+ ret = -EKEYREJECTED;
-+ goto error_free_cert;
-+ }
-+ if (now >= cert->valid_to) {
-+ pr_warn("Cert %s has expired\n", cert->fingerprint);
-+ ret = -EKEYEXPIRED;
-+ goto error_free_cert;
-+ }
-+
-+ cert->pub->algo = x509_public_key_algorithms[cert->pkey_algo];
-+ cert->pub->id_type = PKEY_ID_X509;
-+
-+ /* Check the signature on the key */
-+ if (strcmp(cert->fingerprint, cert->authority) == 0) {
-+ ret = x509_check_signature(cert->pub, cert);
-+ if (ret < 0)
-+ goto error_free_cert;
-+ }
-+
-+ /* Propose a description */
-+ sulen = strlen(cert->subject);
-+ srlen = strlen(cert->fingerprint);
-+ ret = -ENOMEM;
-+ desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL);
-+ if (!desc)
-+ goto error_free_cert;
-+ memcpy(desc, cert->subject, sulen);
-+ desc[sulen] = ':';
-+ desc[sulen + 1] = ' ';
-+ memcpy(desc + sulen + 2, cert->fingerprint, srlen);
-+ desc[sulen + 2 + srlen] = 0;
-+
-+ /* We're pinning the module by being linked against it */
-+ __module_get(public_key_subtype.owner);
-+ prep->type_data[0] = &public_key_subtype;
-+ prep->type_data[1] = cert->fingerprint;
-+ prep->payload = cert->pub;
-+ prep->description = desc;
-+ prep->quotalen = 100;
-+
-+ /* We've finished with the certificate */
-+ cert->pub = NULL;
-+ cert->fingerprint = NULL;
-+ desc = NULL;
-+ ret = 0;
-+
-+error_free_cert:
-+ x509_free_certificate(cert);
-+ return ret;
-+}
-+
-+static struct asymmetric_key_parser x509_key_parser = {
-+ .owner = THIS_MODULE,
-+ .name = "x509",
-+ .parse = x509_key_preparse,
-+};
-+
-+/*
-+ * Module stuff
-+ */
-+static int __init x509_key_init(void)
-+{
-+ return register_asymmetric_key_parser(&x509_key_parser);
-+}
-+
-+static void __exit x509_key_exit(void)
-+{
-+ unregister_asymmetric_key_parser(&x509_key_parser);
-+}
-+
-+module_init(x509_key_init);
-+module_exit(x509_key_exit);
-diff --git a/crypto/asymmetric_keys/x509_rsakey.asn1 b/crypto/asymmetric_keys/x509_rsakey.asn1
-new file mode 100644
-index 0000000..4ec7cc6
---- /dev/null
-+++ b/crypto/asymmetric_keys/x509_rsakey.asn1
-@@ -0,0 +1,4 @@
-+RSAPublicKey ::= SEQUENCE {
-+ modulus INTEGER ({ rsa_extract_mpi }), -- n
-+ publicExponent INTEGER ({ rsa_extract_mpi }) -- e
-+ }
---
-1.7.12.1
-
-
-From a4c3000ab42b11536ffc8eb9c1d03a746b424bda Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:09:50 +0100
-Subject: [PATCH 18/37] MODSIGN: Add FIPS policy
-
-If we're in FIPS mode, we should panic if we fail to verify the signature on a
-module or we're asked to load an unsigned module in signature enforcing mode.
-Possibly FIPS mode should automatically enable enforcing mode.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- kernel/module.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/kernel/module.c b/kernel/module.c
-index 7efb415..3e8b1a7 100644
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -58,6 +58,7 @@
- #include <linux/jump_label.h>
- #include <linux/pfn.h>
- #include <linux/bsearch.h>
-+#include <linux/fips.h>
- #include "module-internal.h"
-
- #define CREATE_TRACE_POINTS
-@@ -2467,6 +2468,9 @@ static int module_sig_check(struct load_info *info,
- }
-
- /* Not having a signature is only an error if we're strict. */
-+ if (err < 0 && fips_enabled)
-+ panic("Module verification failed with error %d in FIPS mode\n",
-+ err);
- if (err == -ENOKEY && !sig_enforce)
- err = 0;
-
---
-1.7.12.1
-
-
-From 86342ab6db2c5b10b08bd9d1064b1779070c2a82 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:09:50 +0100
-Subject: [PATCH 19/37] MODSIGN: Provide gitignore and make clean rules for
- extra files
-
-Provide gitignore and make clean rules for extra files to hide and clean up the
-extra files produced by module signing stuff once it is added. Also add a
-clean up rule for the module content extractor program used to extract the data
-to be signed.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- .gitignore | 14 ++++++++++++++
- Makefile | 1 +
- 2 files changed, 15 insertions(+)
-
-diff --git a/.gitignore b/.gitignore
-index 57af07c..0f2f40f 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -14,6 +14,10 @@
- *.o.*
- *.a
- *.s
-+*.ko.unsigned
-+*.ko.stripped
-+*.ko.stripped.dig
-+*.ko.stripped.sig
- *.ko
- *.so
- *.so.dbg
-@@ -84,3 +88,13 @@ GTAGS
- *.orig
- *~
- \#*#
-+
-+#
-+# Leavings from module signing
-+#
-+extra_certificates
-+signing_key.priv
-+signing_key.x509
-+signing_key.x509.keyid
-+signing_key.x509.signer
-+x509.genkey
-diff --git a/Makefile b/Makefile
-index 6cdadf4..b4f9eb5 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1239,6 +1239,7 @@ clean: $(clean-dirs)
- $(call cmd,rmfiles)
- @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
- \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-+ -o -name '*.ko.*' \
- -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
- -o -name '*.symtypes' -o -name 'modules.order' \
- -o -name modules.builtin -o -name '.tmp_*.o.*' \
---
-1.7.12.1
-
-
-From c631aa86c295b87aa09188d9313cccf41e5db23f Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:09:50 +0100
-Subject: [PATCH 20/37] MODSIGN: Provide Kconfig options
-
-Provide kernel configuration options for module signing.
-
-The following configuration options are added:
-
- CONFIG_MODULE_SIG_SHA1
- CONFIG_MODULE_SIG_SHA224
- CONFIG_MODULE_SIG_SHA256
- CONFIG_MODULE_SIG_SHA384
- CONFIG_MODULE_SIG_SHA512
-
-These select the cryptographic hash used to digest the data prior to signing.
-Additionally, the crypto module selected will be built into the kernel as it
-won't be possible to load it as a module without incurring a circular
-dependency when the kernel tries to check its signature.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- init/Kconfig | 38 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
-diff --git a/init/Kconfig b/init/Kconfig
-index fa8ccad..00d4579 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1593,12 +1593,50 @@ config MODULE_SIG
- is simply appended to the module. For more information see
- Documentation/module-signing.txt.
-
-+ !!!WARNING!!! If you enable this option, you MUST make sure that the
-+ module DOES NOT get stripped after being signed. This includes the
-+ debuginfo strip done by some packagers (such as rpmbuild) and
-+ inclusion into an initramfs that wants the module size reduced.
-+
- config MODULE_SIG_FORCE
- bool "Require modules to be validly signed"
- depends on MODULE_SIG
- help
- Reject unsigned modules or signed modules for which we don't have a
- key. Without this, such modules will simply taint the kernel.
-+
-+choice
-+ prompt "Which hash algorithm should modules be signed with?"
-+ depends on MODULE_SIG
-+ help
-+ This determines which sort of hashing algorithm will be used during
-+ signature generation. This algorithm _must_ be built into the kernel
-+ directly so that signature verification can take place. It is not
-+ possible to load a signed module containing the algorithm to check
-+ the signature on that module.
-+
-+config MODULE_SIG_SHA1
-+ bool "Sign modules with SHA-1"
-+ select CRYPTO_SHA1
-+
-+config MODULE_SIG_SHA224
-+ bool "Sign modules with SHA-224"
-+ select CRYPTO_SHA256
-+
-+config MODULE_SIG_SHA256
-+ bool "Sign modules with SHA-256"
-+ select CRYPTO_SHA256
-+
-+config MODULE_SIG_SHA384
-+ bool "Sign modules with SHA-384"
-+ select CRYPTO_SHA512
-+
-+config MODULE_SIG_SHA512
-+ bool "Sign modules with SHA-512"
-+ select CRYPTO_SHA512
-+
-+endchoice
-+
- endif # MODULES
-
- config INIT_ALL_POSSIBLE
---
-1.7.12.1
-
-
-From 84d1788d1ea47ecfe2d30d0c2081055d7e89441d Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:09:51 +0100
-Subject: [PATCH 21/37] MODSIGN: Automatically generate module signing keys if
- missing
-
-Automatically generate keys for module signing if they're absent so that
-allyesconfig doesn't break. The builder should consider generating their own
-key and certificate, however, so that the keys are appropriately named.
-
-The private key for the module signer should be placed in signing_key.priv
-(unencrypted!) and the public key in an X.509 certificate as signing_key.x509.
-
-If a transient key is desired for signing the modules, a config file for
-'openssl req' can be placed in x509.genkey, looking something like the
-following:
-
- [ req ]
- default_bits = 4096
- distinguished_name = req_distinguished_name
- prompt = no
- x509_extensions = myexts
-
- [ req_distinguished_name ]
- O = Magarathea
- CN = Glacier signing key
- emailAddress = slartibartfast@magrathea.h2g2
-
- [ myexts ]
- basicConstraints=critical,CA:FALSE
- keyUsage=digitalSignature
- subjectKeyIdentifier=hash
- authorityKeyIdentifier=hash
-
-The build process will use this to configure:
-
- openssl req -new -nodes -utf8 -sha1 -days 36500 -batch \
- -x509 -config x509.genkey \
- -outform DER -out signing_key.x509 \
- -keyout signing_key.priv
-
-to generate the key.
-
-Note that it is required that the X.509 certificate have a subjectKeyIdentifier
-and an authorityKeyIdentifier. Without those, the certificate will be
-rejected. These can be used to check the validity of a certificate.
-
-Note that 'make distclean' will remove signing_key.{priv,x509} and x509.genkey,
-whether or not they were generated automatically.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- kernel/Makefile | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 49 insertions(+)
-
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 08ba8a6..58c6f11 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -132,3 +132,52 @@ quiet_cmd_timeconst = TIMEC $@
- targets += timeconst.h
- $(obj)/timeconst.h: $(src)/timeconst.pl FORCE
- $(call if_changed,timeconst)
-+
-+ifeq ($(CONFIG_MODULE_SIG),y)
-+
-+###############################################################################
-+#
-+# If module signing is requested, say by allyesconfig, but a key has not been
-+# supplied, then one will need to be generated to make sure the build does not
-+# fail and that the kernel may be used afterwards.
-+#
-+###############################################################################
-+signing_key.priv signing_key.x509: x509.genkey
-+ @echo "###"
-+ @echo "### Now generating an X.509 key pair to be used for signing modules."
-+ @echo "###"
-+ @echo "### If this takes a long time, you might wish to run rngd in the"
-+ @echo "### background to keep the supply of entropy topped up. It"
-+ @echo "### needs to be run as root, and should use a hardware random"
-+ @echo "### number generator if one is available, eg:"
-+ @echo "###"
-+ @echo "### rngd -r /dev/hwrandom"
-+ @echo "###"
-+ openssl req -new -nodes -utf8 -sha1 -days 36500 -batch \
-+ -x509 -config x509.genkey \
-+ -outform DER -out signing_key.x509 \
-+ -keyout signing_key.priv
-+ @echo "###"
-+ @echo "### Key pair generated."
-+ @echo "###"
-+
-+x509.genkey:
-+ @echo Generating X.509 key generation config
-+ @echo >x509.genkey "[ req ]"
-+ @echo >>x509.genkey "default_bits = 4096"
-+ @echo >>x509.genkey "distinguished_name = req_distinguished_name"
-+ @echo >>x509.genkey "prompt = no"
-+ @echo >>x509.genkey "x509_extensions = myexts"
-+ @echo >>x509.genkey
-+ @echo >>x509.genkey "[ req_distinguished_name ]"
-+ @echo >>x509.genkey "O = Magrathea"
-+ @echo >>x509.genkey "CN = Glacier signing key"
-+ @echo >>x509.genkey "emailAddress = slartibartfast@magrathea.h2g2"
-+ @echo >>x509.genkey
-+ @echo >>x509.genkey "[ myexts ]"
-+ @echo >>x509.genkey "basicConstraints=critical,CA:FALSE"
-+ @echo >>x509.genkey "keyUsage=digitalSignature"
-+ @echo >>x509.genkey "subjectKeyIdentifier=hash"
-+ @echo >>x509.genkey "authorityKeyIdentifier=keyid"
-+endif
-+CLEAN_FILES += signing_key.priv signing_key.x509 x509.genkey
---
-1.7.12.1
-
-
-From 51da59e56f0666efe97c376830dffefdfcecd21f Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:09:51 +0100
-Subject: [PATCH 22/37] MODSIGN: Provide module signing public keys to the
- kernel
-
-Include a PGP keyring containing the public keys required to perform module
-verification in the kernel image during build and create a special keyring
-during boot which is then populated with keys of crypto type holding the public
-keys found in the PGP keyring.
-
-These can be seen by root:
-
-[root@andromeda ~]# cat /proc/keys
-07ad4ee0 I----- 1 perm 3f010000 0 0 crypto modsign.0: RSA 87b9b3bd []
-15c7f8c3 I----- 1 perm 1f030000 0 0 keyring .module_sign: 1/4
-...
-
-It is probably worth permitting root to invalidate these keys, resulting in
-their removal and preventing further modules from being loaded with that key.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- kernel/Makefile | 11 ++++-
- kernel/modsign_pubkey.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++
- kernel/module-internal.h | 2 +
- 3 files changed, 124 insertions(+), 2 deletions(-)
- create mode 100644 kernel/modsign_pubkey.c
-
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 58c6f11..111a845 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -55,7 +55,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
- obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
- obj-$(CONFIG_UID16) += uid16.o
- obj-$(CONFIG_MODULES) += module.o
--obj-$(CONFIG_MODULE_SIG) += module_signing.o
-+obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o
- obj-$(CONFIG_KALLSYMS) += kallsyms.o
- obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
- obj-$(CONFIG_KEXEC) += kexec.o
-@@ -134,6 +134,13 @@ $(obj)/timeconst.h: $(src)/timeconst.pl FORCE
- $(call if_changed,timeconst)
-
- ifeq ($(CONFIG_MODULE_SIG),y)
-+#
-+# Pull the signing certificate and any extra certificates into the kernel
-+#
-+extra_certificates:
-+ touch $@
-+
-+kernel/modsign_pubkey.o: signing_key.x509 extra_certificates
-
- ###############################################################################
- #
-@@ -180,4 +187,4 @@ x509.genkey:
- @echo >>x509.genkey "subjectKeyIdentifier=hash"
- @echo >>x509.genkey "authorityKeyIdentifier=keyid"
- endif
--CLEAN_FILES += signing_key.priv signing_key.x509 x509.genkey
-+CLEAN_FILES += signing_key.priv signing_key.x509 x509.genkey extra_certificates
-diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
-new file mode 100644
-index 0000000..4646eb2
---- /dev/null
-+++ b/kernel/modsign_pubkey.c
-@@ -0,0 +1,113 @@
-+/* Public keys for module signature verification
-+ *
-+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells@redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public Licence
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the Licence, or (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/cred.h>
-+#include <linux/err.h>
-+#include <keys/asymmetric-type.h>
-+#include "module-internal.h"
-+
-+struct key *modsign_keyring;
-+
-+extern __initdata const u8 modsign_certificate_list[];
-+extern __initdata const u8 modsign_certificate_list_end[];
-+asm(".section .init.data,\"aw\"\n"
-+ "modsign_certificate_list:\n"
-+ ".incbin \"signing_key.x509\"\n"
-+ ".incbin \"extra_certificates\"\n"
-+ "modsign_certificate_list_end:"
-+ );
-+
-+/*
-+ * We need to make sure ccache doesn't cache the .o file as it doesn't notice
-+ * if modsign.pub changes.
-+ */
-+static __initdata const char annoy_ccache[] = __TIME__ "foo";
-+
-+/*
-+ * Load the compiled-in keys
-+ */
-+static __init int module_verify_init(void)
-+{
-+ pr_notice("Initialise module verification\n");
-+
-+ modsign_keyring = key_alloc(&key_type_keyring, ".module_sign",
-+ KUIDT_INIT(0), KGIDT_INIT(0),
-+ current_cred(),
-+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
-+ KEY_USR_VIEW | KEY_USR_READ,
-+ KEY_ALLOC_NOT_IN_QUOTA);
-+ if (IS_ERR(modsign_keyring))
-+ panic("Can't allocate module signing keyring\n");
-+
-+ if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0)
-+ panic("Can't instantiate module signing keyring\n");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Must be initialised before we try and load the keys into the keyring.
-+ */
-+device_initcall(module_verify_init);
-+
-+/*
-+ * Load the compiled-in keys
-+ */
-+static __init int load_module_signing_keys(void)
-+{
-+ key_ref_t key;
-+ const u8 *p, *end;
-+ size_t plen;
-+
-+ pr_notice("Loading module verification certificates\n");
-+
-+ end = modsign_certificate_list_end;
-+ p = modsign_certificate_list;
-+ while (p < end) {
-+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
-+ * than 256 bytes in size.
-+ */
-+ if (end - p < 4)
-+ goto dodgy_cert;
-+ if (p[0] != 0x30 &&
-+ p[1] != 0x82)
-+ goto dodgy_cert;
-+ plen = (p[2] << 8) | p[3];
-+ plen += 4;
-+ if (plen > end - p)
-+ goto dodgy_cert;
-+
-+ key = key_create_or_update(make_key_ref(modsign_keyring, 1),
-+ "asymmetric",
-+ NULL,
-+ p,
-+ plen,
-+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
-+ KEY_USR_VIEW,
-+ KEY_ALLOC_NOT_IN_QUOTA);
-+ if (IS_ERR(key))
-+ pr_err("MODSIGN: Problem loading in-kernel X.509 certificate (%ld)\n",
-+ PTR_ERR(key));
-+ else
-+ pr_notice("MODSIGN: Loaded cert '%s'\n",
-+ key_ref_to_ptr(key)->description);
-+ p += plen;
-+ }
-+
-+ return 0;
-+
-+dodgy_cert:
-+ pr_err("MODSIGN: Problem parsing in-kernel X.509 certificate list\n");
-+ return 0;
-+}
-+late_initcall(load_module_signing_keys);
-diff --git a/kernel/module-internal.h b/kernel/module-internal.h
-index 033c17f..6114a13 100644
---- a/kernel/module-internal.h
-+++ b/kernel/module-internal.h
-@@ -9,5 +9,7 @@
- * 2 of the Licence, or (at your option) any later version.
- */
-
-+extern struct key *modsign_keyring;
-+
- extern int mod_verify_sig(const void *mod, unsigned long modlen,
- const void *sig, unsigned long siglen);
---
-1.7.12.1
-
-
-From 81a8def438b252dac4aa9c7eda39ad517bfe51ac Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:11:03 +0100
-Subject: [PATCH 23/37] MODSIGN: Implement module signature checking
-
-Check the signature on the module against the keys compiled into the kernel or
-available in a hardware key store.
-
-Currently, only RSA keys are supported - though that's easy enough to change,
-and the signature is expected to contain raw components (so not a PGP or
-PKCS#7 formatted blob).
-
-The signature blob is expected to consist of the following pieces in order:
-
- (1) The binary identifier for the key. This is expected to match the
- SubjectKeyIdentifier from an X.509 certificate. Only X.509 type
- identifiers are currently supported.
-
- (2) The signature data, consisting of a series of MPIs in which each is in
- the format of a 2-byte BE word sizes followed by the content data.
-
- (3) A 12 byte information block of the form:
-
- struct module_signature {
- enum pkey_algo algo : 8;
- enum pkey_hash_algo hash : 8;
- enum pkey_id_type id_type : 8;
- u8 __pad;
- __be32 id_length;
- __be32 sig_length;
- };
-
- The three enums are defined in crypto/public_key.h.
-
- 'algo' contains the public-key algorithm identifier (0->DSA, 1->RSA).
-
- 'hash' contains the digest algorithm identifier (0->MD4, 1->MD5, 2->SHA1,
- etc.).
-
- 'id_type' contains the public-key identifier type (0->PGP, 1->X.509).
-
- '__pad' should be 0.
-
- 'id_length' should contain in the binary identifier length in BE form.
-
- 'sig_length' should contain in the signature data length in BE form.
-
- The lengths are in BE order rather than CPU order to make dealing with
- cross-compilation easier.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (minor Kconfig fix)
----
- init/Kconfig | 8 ++
- kernel/module_signing.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 229 insertions(+), 1 deletion(-)
-
-diff --git a/init/Kconfig b/init/Kconfig
-index 00d4579..abc6e63 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1588,6 +1588,14 @@ config MODULE_SRCVERSION_ALL
- config MODULE_SIG
- bool "Module signature verification"
- depends on MODULES
-+ select KEYS
-+ select CRYPTO
-+ select ASYMMETRIC_KEY_TYPE
-+ select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
-+ select PUBLIC_KEY_ALGO_RSA
-+ select ASN1
-+ select OID_REGISTRY
-+ select X509_CERTIFICATE_PARSER
- help
- Check modules for valid signatures upon load: the signature
- is simply appended to the module. For more information see
-diff --git a/kernel/module_signing.c b/kernel/module_signing.c
-index 499728a..6b09f69 100644
---- a/kernel/module_signing.c
-+++ b/kernel/module_signing.c
-@@ -11,13 +11,233 @@
-
- #include <linux/kernel.h>
- #include <linux/err.h>
-+#include <crypto/public_key.h>
-+#include <crypto/hash.h>
-+#include <keys/asymmetric-type.h>
- #include "module-internal.h"
-
- /*
-+ * Module signature information block.
-+ *
-+ * The constituents of the signature section are, in order:
-+ *
-+ * - Signer's name
-+ * - Key identifier
-+ * - Signature data
-+ * - Information block
-+ */
-+struct module_signature {
-+ enum pkey_algo algo : 8; /* Public-key crypto algorithm */
-+ enum pkey_hash_algo hash : 8; /* Digest algorithm */
-+ enum pkey_id_type id_type : 8; /* Key identifier type */
-+ u8 signer_len; /* Length of signer's name */
-+ u8 key_id_len; /* Length of key identifier */
-+ u8 __pad[3];
-+ __be32 sig_len; /* Length of signature data */
-+};
-+
-+/*
-+ * Digest the module contents.
-+ */
-+static struct public_key_signature *mod_make_digest(enum pkey_hash_algo hash,
-+ const void *mod,
-+ unsigned long modlen)
-+{
-+ struct public_key_signature *pks;
-+ struct crypto_shash *tfm;
-+ struct shash_desc *desc;
-+ size_t digest_size, desc_size;
-+ int ret;
-+
-+ pr_devel("==>%s()\n", __func__);
-+
-+ /* Allocate the hashing algorithm we're going to need and find out how
-+ * big the hash operational data will be.
-+ */
-+ tfm = crypto_alloc_shash(pkey_hash_algo[hash], 0, 0);
-+ if (IS_ERR(tfm))
-+ return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm);
-+
-+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
-+ digest_size = crypto_shash_digestsize(tfm);
-+
-+ /* We allocate the hash operational data storage on the end of our
-+ * context data and the digest output buffer on the end of that.
-+ */
-+ ret = -ENOMEM;
-+ pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
-+ if (!pks)
-+ goto error_no_pks;
-+
-+ pks->pkey_hash_algo = hash;
-+ pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
-+ pks->digest_size = digest_size;
-+
-+ desc = (void *)pks + sizeof(*pks);
-+ desc->tfm = tfm;
-+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-+
-+ ret = crypto_shash_init(desc);
-+ if (ret < 0)
-+ goto error;
-+
-+ ret = crypto_shash_finup(desc, mod, modlen, pks->digest);
-+ if (ret < 0)
-+ goto error;
-+
-+ crypto_free_shash(tfm);
-+ pr_devel("<==%s() = ok\n", __func__);
-+ return pks;
-+
-+error:
-+ kfree(pks);
-+error_no_pks:
-+ crypto_free_shash(tfm);
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ERR_PTR(ret);
-+}
-+
-+/*
-+ * Extract an MPI array from the signature data. This represents the actual
-+ * signature. Each raw MPI is prefaced by a BE 2-byte value indicating the
-+ * size of the MPI in bytes.
-+ *
-+ * RSA signatures only have one MPI, so currently we only read one.
-+ */
-+static int mod_extract_mpi_array(struct public_key_signature *pks,
-+ const void *data, size_t len)
-+{
-+ size_t nbytes;
-+ MPI mpi;
-+
-+ if (len < 3)
-+ return -EBADMSG;
-+ nbytes = ((const u8 *)data)[0] << 8 | ((const u8 *)data)[1];
-+ data += 2;
-+ len -= 2;
-+ if (len != nbytes)
-+ return -EBADMSG;
-+
-+ mpi = mpi_read_raw_data(data, nbytes);
-+ if (!mpi)
-+ return -ENOMEM;
-+ pks->mpi[0] = mpi;
-+ pks->nr_mpi = 1;
-+ return 0;
-+}
-+
-+/*
-+ * Request an asymmetric key.
-+ */
-+static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
-+ const u8 *key_id, size_t key_id_len)
-+{
-+ key_ref_t key;
-+ size_t i;
-+ char *id, *q;
-+
-+ pr_devel("==>%s(,%zu,,%zu)\n", __func__, signer_len, key_id_len);
-+
-+ /* Construct an identifier. */
-+ id = kmalloc(signer_len + 2 + key_id_len * 2 + 1, GFP_KERNEL);
-+ if (!id)
-+ return ERR_PTR(-ENOKEY);
-+
-+ memcpy(id, signer, signer_len);
-+
-+ q = id + signer_len;
-+ *q++ = ':';
-+ *q++ = ' ';
-+ for (i = 0; i < key_id_len; i++) {
-+ *q++ = hex_asc[*key_id >> 4];
-+ *q++ = hex_asc[*key_id++ & 0x0f];
-+ }
-+
-+ *q = 0;
-+
-+ pr_debug("Look up: \"%s\"\n", id);
-+
-+ key = keyring_search(make_key_ref(modsign_keyring, 1),
-+ &key_type_asymmetric, id);
-+ if (IS_ERR(key))
-+ pr_warn("Request for unknown module key '%s' err %ld\n",
-+ id, PTR_ERR(key));
-+ kfree(id);
-+
-+ if (IS_ERR(key)) {
-+ switch (PTR_ERR(key)) {
-+ /* Hide some search errors */
-+ case -EACCES:
-+ case -ENOTDIR:
-+ case -EAGAIN:
-+ return ERR_PTR(-ENOKEY);
-+ default:
-+ return ERR_CAST(key);
-+ }
-+ }
-+
-+ pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
-+ return key_ref_to_ptr(key);
-+}
-+
-+/*
- * Verify the signature on a module.
- */
- int mod_verify_sig(const void *mod, unsigned long modlen,
- const void *sig, unsigned long siglen)
- {
-- return -ENOKEY;
-+ struct public_key_signature *pks;
-+ struct module_signature ms;
-+ struct key *key;
-+ size_t sig_len;
-+ int ret;
-+
-+ pr_devel("==>%s(,%lu,,%lu,)\n", __func__, modlen, siglen);
-+
-+ if (siglen <= sizeof(ms))
-+ return -EBADMSG;
-+
-+ memcpy(&ms, sig + (siglen - sizeof(ms)), sizeof(ms));
-+ siglen -= sizeof(ms);
-+
-+ sig_len = be32_to_cpu(ms.sig_len);
-+ if (sig_len >= siglen ||
-+ siglen - sig_len != (size_t)ms.signer_len + ms.key_id_len)
-+ return -EBADMSG;
-+
-+ /* For the moment, only support RSA and X.509 identifiers */
-+ if (ms.algo != PKEY_ALGO_RSA ||
-+ ms.id_type != PKEY_ID_X509)
-+ return -ENOPKG;
-+
-+ if (ms.hash >= PKEY_HASH__LAST ||
-+ !pkey_hash_algo[ms.hash])
-+ return -ENOPKG;
-+
-+ key = request_asymmetric_key(sig, ms.signer_len,
-+ sig + ms.signer_len, ms.key_id_len);
-+ if (IS_ERR(key))
-+ return PTR_ERR(key);
-+
-+ pks = mod_make_digest(ms.hash, mod, modlen);
-+ if (IS_ERR(pks)) {
-+ ret = PTR_ERR(pks);
-+ goto error_put_key;
-+ }
-+
-+ ret = mod_extract_mpi_array(pks, sig + ms.signer_len + ms.key_id_len,
-+ sig_len);
-+ if (ret < 0)
-+ goto error_free_pks;
-+
-+ ret = verify_signature(key, pks);
-+ pr_devel("verify_signature() = %d\n", ret);
-+
-+error_free_pks:
-+ mpi_free(pks->rsa.s);
-+ kfree(pks);
-+error_put_key:
-+ key_put(key);
-+ pr_devel("<==%s() = %d\n", __func__, ret);
-+ return ret;
- }
---
-1.7.12.1
-
-
-From 952f5922dd45a25f7896843df02aec2250c41f42 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:11:06 +0100
-Subject: [PATCH 24/37] MODSIGN: Provide a script for generating a key ID from
- an X.509 cert
-
-Provide a script to parse an X.509 certificate and certain pieces of
-information from it in order to generate a key identifier to be included within
-a module signature.
-
-The script takes the Subject Name and extracts (if present) the
-organizationName (O), the commonName (CN) and the emailAddress and fabricates
-the signer's name from them:
-
- (1) If both O and CN exist, then the name will be "O: CN", unless:
-
- (a) CN is prefixed by O, in which case only CN is used.
-
- (b) CN and O share at least the first 7 characters, in which case only CN
- is used.
-
- (2) Otherwise, CN is used if present.
-
- (3) Otherwise, O is used if present.
-
- (4) Otherwise the emailAddress is used, if present.
-
- (5) Otherwise a blank name is used.
-
-The script emits a binary encoded identifier in the following form:
-
- - 2 BE bytes indicating the length of the signer's name.
-
- - 2 BE bytes indicating the length of the subject key identifier.
-
- - The characters of the signer's name.
-
- - The bytes of the subject key identifier.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- scripts/x509keyid | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 268 insertions(+)
- create mode 100755 scripts/x509keyid
-
-diff --git a/scripts/x509keyid b/scripts/x509keyid
-new file mode 100755
-index 0000000..c8e91a4
---- /dev/null
-+++ b/scripts/x509keyid
-@@ -0,0 +1,268 @@
-+#!/usr/bin/perl -w
-+#
-+# Generate an identifier from an X.509 certificate that can be placed in a
-+# module signature to indentify the key to use.
-+#
-+# Format:
-+#
-+# ./scripts/x509keyid <x509-cert> <signer's-name> <key-id>
-+#
-+# We read the DER-encoded X509 certificate and parse it to extract the Subject
-+# name and Subject Key Identifier. The provide the data we need to build the
-+# certificate identifier.
-+#
-+# The signer's name part of the identifier is fabricated from the commonName,
-+# the organizationName or the emailAddress components of the X.509 subject
-+# name and written to the second named file.
-+#
-+# The subject key ID to select which of that signer's certificates we're
-+# intending to use to sign the module is written to the third named file.
-+#
-+use strict;
-+
-+my $raw_data;
-+
-+die "Need three filenames\n" if ($#ARGV != 2);
-+
-+my $src = $ARGV[0];
-+
-+open(FD, "<$src") || die $src;
-+binmode FD;
-+my @st = stat(FD);
-+die $src if (!@st);
-+read(FD, $raw_data, $st[7]) || die $src;
-+close(FD);
-+
-+my $UNIV = 0 << 6;
-+my $APPL = 1 << 6;
-+my $CONT = 2 << 6;
-+my $PRIV = 3 << 6;
-+
-+my $CONS = 0x20;
-+
-+my $BOOLEAN = 0x01;
-+my $INTEGER = 0x02;
-+my $BIT_STRING = 0x03;
-+my $OCTET_STRING = 0x04;
-+my $NULL = 0x05;
-+my $OBJ_ID = 0x06;
-+my $UTF8String = 0x0c;
-+my $SEQUENCE = 0x10;
-+my $SET = 0x11;
-+my $UTCTime = 0x17;
-+my $GeneralizedTime = 0x18;
-+
-+my %OIDs = (
-+ pack("CCC", 85, 4, 3) => "commonName",
-+ pack("CCC", 85, 4, 6) => "countryName",
-+ pack("CCC", 85, 4, 10) => "organizationName",
-+ pack("CCC", 85, 4, 11) => "organizationUnitName",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
-+ pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
-+ pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
-+ pack("CCC", 85, 29, 19) => "basicConstraints"
-+);
-+
-+###############################################################################
-+#
-+# Extract an ASN.1 element from a string and return information about it.
-+#
-+###############################################################################
-+sub asn1_extract($$@)
-+{
-+ my ($cursor, $expected_tag, $optional) = @_;
-+
-+ return [ -1 ]
-+ if ($cursor->[1] == 0 && $optional);
-+
-+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
-+ if ($cursor->[1] < 2);
-+
-+ my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
-+
-+ if ($expected_tag != -1 && $tag != $expected_tag) {
-+ return [ -1 ]
-+ if ($optional);
-+ die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
-+ " not ", $expected_tag, ")\n";
-+ }
-+
-+ $cursor->[0] += 2;
-+ $cursor->[1] -= 2;
-+
-+ die $src, ": ", $cursor->[0], ": ASN.1 long tag\n"
-+ if (($tag & 0x1f) == 0x1f);
-+ die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
-+ if ($len == 0x80);
-+
-+ if ($len > 0x80) {
-+ my $l = $len - 0x80;
-+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
-+ if ($cursor->[1] < $l);
-+
-+ if ($l == 0x1) {
-+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
-+ } elsif ($l = 0x2) {
-+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
-+ } elsif ($l = 0x3) {
-+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
-+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
-+ } elsif ($l = 0x4) {
-+ $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
-+ } else {
-+ die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
-+ }
-+
-+ $cursor->[0] += $l;
-+ $cursor->[1] -= $l;
-+ }
-+
-+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
-+ if ($cursor->[1] < $len);
-+
-+ my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
-+ $cursor->[0] += $len;
-+ $cursor->[1] -= $len;
-+
-+ return $ret;
-+}
-+
-+###############################################################################
-+#
-+# Retrieve the data referred to by a cursor
-+#
-+###############################################################################
-+sub asn1_retrieve($)
-+{
-+ my ($cursor) = @_;
-+ my ($offset, $len, $data) = @$cursor;
-+ return substr($$data, $offset, $len);
-+}
-+
-+###############################################################################
-+#
-+# Roughly parse the X.509 certificate
-+#
-+###############################################################################
-+my $cursor = [ 0, length($raw_data), \$raw_data ];
-+
-+my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
-+my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
-+my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
-+my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
-+my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
-+my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
-+my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
-+
-+my $subject_key_id = ();
-+my $authority_key_id = ();
-+
-+#
-+# Parse the extension list
-+#
-+if ($extension_list->[0] != -1) {
-+ my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
-+
-+ while ($extensions->[1]->[1] > 0) {
-+ my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
-+ my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
-+ my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
-+ my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
-+
-+ my $raw_oid = asn1_retrieve($x_oid->[1]);
-+ next if (!exists($OIDs{$raw_oid}));
-+ my $x_type = $OIDs{$raw_oid};
-+
-+ my $raw_value = asn1_retrieve($x_val->[1]);
-+
-+ if ($x_type eq "subjectKeyIdentifier") {
-+ my $vcursor = [ 0, length($raw_value), \$raw_value ];
-+
-+ $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
-+ }
-+ }
-+}
-+
-+###############################################################################
-+#
-+# Determine what we're going to use as the signer's name. In order of
-+# preference, take one of: commonName, organizationName or emailAddress.
-+#
-+###############################################################################
-+my $org = "";
-+my $cn = "";
-+my $email = "";
-+
-+while ($subject->[1]->[1] > 0) {
-+ my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
-+ my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
-+ my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
-+ my $n_val = asn1_extract($attr->[1], -1);
-+
-+ my $raw_oid = asn1_retrieve($n_oid->[1]);
-+ next if (!exists($OIDs{$raw_oid}));
-+ my $n_type = $OIDs{$raw_oid};
-+
-+ my $raw_value = asn1_retrieve($n_val->[1]);
-+
-+ if ($n_type eq "organizationName") {
-+ $org = $raw_value;
-+ } elsif ($n_type eq "commonName") {
-+ $cn = $raw_value;
-+ } elsif ($n_type eq "emailAddress") {
-+ $email = $raw_value;
-+ }
-+}
-+
-+my $id_name = $email;
-+
-+if ($org && $cn) {
-+ # Don't use the organizationName if the commonName repeats it
-+ if (length($org) <= length($cn) &&
-+ substr($cn, 0, length($org)) eq $org) {
-+ $id_name = $cn;
-+ goto got_id_name;
-+ }
-+
-+ # Or a signifcant chunk of it
-+ if (length($org) >= 7 &&
-+ length($cn) >= 7 &&
-+ substr($cn, 0, 7) eq substr($org, 0, 7)) {
-+ $id_name = $cn;
-+ goto got_id_name;
-+ }
-+
-+ $id_name = $org . ": " . $cn;
-+} elsif ($org) {
-+ $id_name = $org;
-+} elsif ($cn) {
-+ $id_name = $cn;
-+}
-+
-+got_id_name:
-+
-+###############################################################################
-+#
-+# Output the signer's name and the key identifier that we're going to include
-+# in module signatures.
-+#
-+###############################################################################
-+die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
-+ if (!$subject_key_id);
-+
-+my $id_key_id = asn1_retrieve($subject_key_id->[1]);
-+
-+open(OUTFD, ">$ARGV[1]") || die $ARGV[1];
-+print OUTFD $id_name;
-+close OUTFD || die $ARGV[1];
-+
-+open(OUTFD, ">$ARGV[2]") || die $ARGV[2];
-+print OUTFD $id_key_id;
-+close OUTFD || die $ARGV[2];
---
-1.7.12.1
-
-
-From 52a1f2ba9612d689f1a5ed6c1a03bd784f34bf1c Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Wed, 26 Sep 2012 10:11:06 +0100
-Subject: [PATCH 25/37] MODSIGN: Sign modules during the build process
-
-If CONFIG_MODULE_SIG is set, then this patch will cause all modules files to
-to have signatures added. The following steps will occur:
-
- (1) The module will be linked to foo.ko.unsigned instead of foo.ko
-
- (2) The module will be stripped using both "strip -x -g" and "eu-strip" to
- ensure minimal size for inclusion in an initramfs.
-
- (3) The signature will be generated on the stripped module.
-
- (4) The signature will be appended to the module, along with some information
- about the signature and a magic string that indicates the presence of the
- signature.
-
-Step (3) requires private and public keys to be available. By default these
-are expected to be found in files:
-
- signing_key.priv
- signing_key.x509
-
-in the base directory of the build. The first is the private key in PEM form
-and the second is the X.509 certificate in DER form as can be generated from
-openssl:
-
- openssl req \
- -new -x509 -outform PEM -out signing_key.x509 \
- -keyout signing_key.priv -nodes \
- -subj "/CN=H2G2/O=Magrathea/CN=Slartibartfast"
-
-If the secret key is not found then signing will be skipped and the unsigned
-module from (1) will just be copied to foo.ko.
-
-If signing occurs, lines like the following will be seen:
-
- LD [M] fs/foo/foo.ko.unsigned
- STRIP [M] fs/foo/foo.ko.stripped
- SIGN [M] fs/foo/foo.ko
-
-will appear in the build log. If the signature step will be skipped and the
-following will be seen:
-
- LD [M] fs/foo/foo.ko.unsigned
- STRIP [M] fs/foo/foo.ko.stripped
- NO SIGN [M] fs/foo/foo.ko
-
-NOTE! After the signature step, the signed module _must_not_ be passed through
-strip. The unstripped, unsigned module is still available at the name on the
-LD [M] line. This restriction may affect packaging tools (such as rpmbuild)
-and initramfs composition tools.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- scripts/Makefile.modpost | 77 ++++++++++++++++++++++++++++++-
- scripts/sign-file | 115 +++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 191 insertions(+), 1 deletion(-)
- create mode 100644 scripts/sign-file
-
-diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
-index 08dce14..2a4d1a1 100644
---- a/scripts/Makefile.modpost
-+++ b/scripts/Makefile.modpost
-@@ -14,7 +14,8 @@
- # 3) create one <module>.mod.c file pr. module
- # 4) create one Module.symvers file with CRC for all exported symbols
- # 5) compile all <module>.mod.c files
--# 6) final link of the module to a <module.ko> file
-+# 6) final link of the module to a <module.ko> (or <module.unsigned>) file
-+# 7) signs the modules to a <module.ko> file
-
- # Step 3 is used to place certain information in the module's ELF
- # section, including information such as:
-@@ -32,6 +33,8 @@
- # Step 4 is solely used to allow module versioning in external modules,
- # where the CRC of each module is retrieved from the Module.symvers file.
-
-+# Step 7 is dependent on CONFIG_MODULE_SIG being enabled.
-+
- # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
- # symbols in the final module linking stage
- # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
-@@ -116,6 +119,7 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
- targets += $(modules:.ko=.mod.o)
-
- # Step 6), final link of the modules
-+ifneq ($(CONFIG_MODULE_SIG),y)
- quiet_cmd_ld_ko_o = LD [M] $@
- cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
- $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-@@ -125,7 +129,78 @@ $(modules): %.ko :%.o %.mod.o FORCE
- $(call if_changed,ld_ko_o)
-
- targets += $(modules)
-+else
-+quiet_cmd_ld_ko_unsigned_o = LD [M] $@
-+ cmd_ld_ko_unsigned_o = \
-+ $(LD) -r $(LDFLAGS) \
-+ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-+ -o $@ $(filter-out FORCE,$^) \
-+ $(if $(AFTER_LINK),; $(AFTER_LINK))
-+
-+$(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE
-+ $(call if_changed,ld_ko_unsigned_o)
-+
-+targets += $(modules:.ko=.ko.unsigned)
-+
-+# Step 7), sign the modules
-+MODSECKEY = ./signing_key.priv
-+MODPUBKEY = ./signing_key.x509
-+
-+ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY))
-+ifeq ($(KBUILD_SRC),)
-+ # no O= is being used
-+ SCRIPTS_DIR := scripts
-+else
-+ SCRIPTS_DIR := $(KBUILD_SRC)/scripts
-+endif
-+SIGN_MODULES := 1
-+else
-+SIGN_MODULES := 0
-+endif
-+
-+# only sign if it's an in-tree module
-+ifneq ($(KBUILD_EXTMOD),)
-+SIGN_MODULES := 0
-+endif
-
-+# We strip the module as best we can - note that using both strip and eu-strip
-+# results in a smaller module than using either alone.
-+EU_STRIP = $(shell which eu-strip || echo true)
-+
-+quiet_cmd_sign_ko_stripped_ko_unsigned = STRIP [M] $@
-+ cmd_sign_ko_stripped_ko_unsigned = \
-+ cp $< $@ && \
-+ strip -x -g $@ && \
-+ $(EU_STRIP) $@
-+
-+ifeq ($(SIGN_MODULES),1)
-+
-+quiet_cmd_genkeyid = GENKEYID $@
-+ cmd_genkeyid = \
-+ perl $(SCRIPTS_DIR)/x509keyid $< $<.signer $<.keyid
-+
-+%.signer %.keyid: %
-+ $(call if_changed,genkeyid)
-+
-+KEYRING_DEP := $(MODSECKEY) $(MODPUBKEY) $(MODPUBKEY).signer $(MODPUBKEY).keyid
-+quiet_cmd_sign_ko_ko_stripped = SIGN [M] $@
-+ cmd_sign_ko_ko_stripped = \
-+ sh $(SCRIPTS_DIR)/sign-file $(MODSECKEY) $(MODPUBKEY) $< $@
-+else
-+KEYRING_DEP :=
-+quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@
-+ cmd_sign_ko_ko_unsigned = \
-+ cp $< $@
-+endif
-+
-+$(modules): %.ko :%.ko.stripped $(KEYRING_DEP) FORCE
-+ $(call if_changed,sign_ko_ko_stripped)
-+
-+$(patsubst %.ko,%.ko.stripped,$(modules)): %.ko.stripped :%.ko.unsigned FORCE
-+ $(call if_changed,sign_ko_stripped_ko_unsigned)
-+
-+targets += $(modules)
-+endif
-
- # Add FORCE to the prequisites of a target to force it to be always rebuilt.
- # ---------------------------------------------------------------------------
-diff --git a/scripts/sign-file b/scripts/sign-file
-new file mode 100644
-index 0000000..e58e34e
---- /dev/null
-+++ b/scripts/sign-file
-@@ -0,0 +1,115 @@
-+#!/bin/sh
-+#
-+# Sign a module file using the given key.
-+#
-+# Format: sign-file <key> <x509> <src-file> <dst-file>
-+#
-+
-+scripts=`dirname $0`
-+
-+CONFIG_MODULE_SIG_SHA512=y
-+if [ -r .config ]
-+then
-+ . ./.config
-+fi
-+
-+key="$1"
-+x509="$2"
-+src="$3"
-+dst="$4"
-+
-+if [ ! -r "$key" ]
-+then
-+ echo "Can't read private key" >&2
-+ exit 2
-+fi
-+
-+if [ ! -r "$x509" ]
-+then
-+ echo "Can't read X.509 certificate" >&2
-+ exit 2
-+fi
-+if [ ! -r "$x509.signer" ]
-+then
-+ echo "Can't read Signer name" >&2
-+ exit 2;
-+fi
-+if [ ! -r "$x509.keyid" ]
-+then
-+ echo "Can't read Key identifier" >&2
-+ exit 2;
-+fi
-+
-+#
-+# Signature parameters
-+#
-+algo=1 # Public-key crypto algorithm: RSA
-+hash= # Digest algorithm
-+id_type=1 # Identifier type: X.509
-+
-+#
-+# Digest the data
-+#
-+dgst=
-+if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ]
-+then
-+ prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14"
-+ dgst=-sha1
-+ hash=2
-+elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ]
-+then
-+ prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C"
-+ dgst=-sha224
-+ hash=7
-+elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ]
-+then
-+ prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20"
-+ dgst=-sha256
-+ hash=4
-+elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ]
-+then
-+ prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30"
-+ dgst=-sha384
-+ hash=5
-+elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ]
-+then
-+ prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40"
-+ dgst=-sha512
-+ hash=6
-+else
-+ echo "$0: Can't determine hash algorithm" >&2
-+ exit 2
-+fi
-+
-+(
-+perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $?
-+openssl dgst $dgst -binary $src || exit $?
-+) >$src.dig || exit $?
-+
-+#
-+# Generate the binary signature, which will be just the integer that comprises
-+# the signature with no metadata attached.
-+#
-+openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $?
-+signerlen=`stat -c %s $x509.signer`
-+keyidlen=`stat -c %s $x509.keyid`
-+siglen=`stat -c %s $src.sig`
-+
-+#
-+# Build the signed binary
-+#
-+(
-+ cat $src || exit $?
-+ echo '~Module signature appended~' || exit $?
-+ cat $x509.signer $x509.keyid || exit $?
-+
-+ # Preface each signature integer with a 2-byte BE length
-+ perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $?
-+ cat $src.sig || exit $?
-+
-+ # Generate the information block
-+ perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $?
-+) >$dst~ || exit $?
-+
-+# Permit in-place signing
-+mv $dst~ $dst || exit $?
---
-1.7.12.1
-
-
-From 1e9ce85a6c40e2c0ba6c589605ceb565b1c83784 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 28 Sep 2012 11:16:57 +0100
-Subject: [PATCH 26/37] MODSIGN: Use the same digest for the autogen key sig
- as for the module sig
-
-Use the same digest type for the autogenerated key signature as for the module
-signature so that the hash algorithm is guaranteed to be present in the kernel.
-
-Without this, the X.509 certificate loader may reject the X.509 certificate so
-generated because it was self-signed and the signature will be checked against
-itself - but this won't work if the digest algorithm must be loaded as a
-module.
-
-The symptom is that the key fails to load with the following message emitted
-into the kernel log:
-
- MODSIGN: Problem loading in-kernel X.509 certificate (-65)
-
-the error in brackets being -ENOPKG. What you should see is something like:
-
- MODSIGN: Loaded cert 'Magarathea: Glacier signing key: 9588321144239a119d3406d4c4cf1fbae1836fa0'
-
-Note that this doesn't apply to certificates that are not self-signed as we
-don't check those currently as they require the parent CA certificate to be
-available.
-
-Reported-by: Rusty Russell <rusty@rustcorp.com.au>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- kernel/Makefile | 22 +++++++++++++++++++++-
- 1 file changed, 21 insertions(+), 1 deletion(-)
-
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 111a845..a799029 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -149,6 +149,26 @@ kernel/modsign_pubkey.o: signing_key.x509 extra_certificates
- # fail and that the kernel may be used afterwards.
- #
- ###############################################################################
-+sign_key_with_hash :=
-+ifeq ($(CONFIG_MODULE_SIG_SHA1),y)
-+sign_key_with_hash := -sha1
-+endif
-+ifeq ($(CONFIG_MODULE_SIG_SHA224),y)
-+sign_key_with_hash := -sha224
-+endif
-+ifeq ($(CONFIG_MODULE_SIG_SHA256),y)
-+sign_key_with_hash := -sha256
-+endif
-+ifeq ($(CONFIG_MODULE_SIG_SHA384),y)
-+sign_key_with_hash := -sha384
-+endif
-+ifeq ($(CONFIG_MODULE_SIG_SHA512),y)
-+sign_key_with_hash := -sha512
-+endif
-+ifeq ($(sign_key_with_hash),)
-+$(error Could not determine digest type to use from kernel config)
-+endif
-+
- signing_key.priv signing_key.x509: x509.genkey
- @echo "###"
- @echo "### Now generating an X.509 key pair to be used for signing modules."
-@@ -160,7 +180,7 @@ signing_key.priv signing_key.x509: x509.genkey
- @echo "###"
- @echo "### rngd -r /dev/hwrandom"
- @echo "###"
-- openssl req -new -nodes -utf8 -sha1 -days 36500 -batch \
-+ openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \
- -x509 -config x509.genkey \
- -outform DER -out signing_key.x509 \
- -keyout signing_key.priv
---
-1.7.12.1
-
-
-From 4c13d777ecee93ae75dae3184473003acff05a53 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 28 Sep 2012 11:16:57 +0100
-Subject: [PATCH 27/37] MODSIGN: Use utf8 strings in signer's name in
- autogenerated X.509 certs
-
-Place an indication that the certificate should use utf8 strings into the
-x509.genkey template generated by kernel/Makefile.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- kernel/Makefile | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/kernel/Makefile b/kernel/Makefile
-index a799029..e951adf 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -194,6 +194,7 @@ x509.genkey:
- @echo >>x509.genkey "default_bits = 4096"
- @echo >>x509.genkey "distinguished_name = req_distinguished_name"
- @echo >>x509.genkey "prompt = no"
-+ @echo >>x509.genkey "string_mask = utf8only"
- @echo >>x509.genkey "x509_extensions = myexts"
- @echo >>x509.genkey
- @echo >>x509.genkey "[ req_distinguished_name ]"
---
-1.7.12.1
-
-
-From 836513a2dd15675d4ad5fefa585d1b866bec4995 Mon Sep 17 00:00:00 2001
-From: Rusty Russell <rusty@rustcorp.com.au>
-Date: Tue, 2 Oct 2012 14:35:24 +0930
-Subject: [PATCH 28/37] MODSIGN: Make mrproper should remove generated files.
-
-It doesn't, because the clean targets don't include kernel/Makefile, and
-because two files were missing from the list.
-
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- Makefile | 5 ++++-
- kernel/Makefile | 1 -
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index b4f9eb5..e4292ea 100644
---- a/Makefile
-+++ b/Makefile
-@@ -995,7 +995,10 @@ MRPROPER_DIRS += include/config usr/include include/generated \
- arch/*/include/generated
- MRPROPER_FILES += .config .config.old .version .old_version \
- include/linux/version.h \
-- Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
-+ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
-+ signing_key.priv signing_key.x509 x509.genkey \
-+ extra_certificates signing_key.x509.keyid \
-+ signing_key.x509.signer
-
- # clean - Delete most, but leave enough to build external modules
- #
-diff --git a/kernel/Makefile b/kernel/Makefile
-index e951adf..d3611c8 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -208,4 +208,3 @@ x509.genkey:
- @echo >>x509.genkey "subjectKeyIdentifier=hash"
- @echo >>x509.genkey "authorityKeyIdentifier=keyid"
- endif
--CLEAN_FILES += signing_key.priv signing_key.x509 x509.genkey extra_certificates
---
-1.7.12.1
-
-
-From 855c92bdf2fb006e4190650b809a6216579395d5 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Tue, 2 Oct 2012 14:36:16 +0100
-Subject: [PATCH 29/37] MODSIGN: Fix 32-bit overflow in X.509 certificate
- validity date checking
-
-The current choice of lifetime for the autogenerated X.509 of 100 years,
-putting the validTo date in 2112, causes problems on 32-bit systems where a
-32-bit time_t wraps in 2106. 64-bit x86_64 systems seem to be unaffected.
-
-This can result in something like:
-
- Loading module verification certificates
- X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 has expired
- MODSIGN: Problem loading in-kernel X.509 certificate (-127)
-
-Or:
-
- X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 is not yet valid
- MODSIGN: Problem loading in-kernel X.509 certificate (-129)
-
-Instead of turning the dates into time_t values and comparing, turn the system
-clock and the ASN.1 dates into tm structs and compare those piecemeal instead.
-
-Reported-by: Rusty Russell <rusty@rustcorp.com.au>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Acked-by: Josh Boyer <jwboyer@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/x509_cert_parser.c | 25 +++++++++---------
- crypto/asymmetric_keys/x509_parser.h | 4 +--
- crypto/asymmetric_keys/x509_public_key.c | 42 +++++++++++++++++++++++++++----
- 3 files changed, 51 insertions(+), 20 deletions(-)
-
-diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
-index 8fcac94..db07e8c 100644
---- a/crypto/asymmetric_keys/x509_cert_parser.c
-+++ b/crypto/asymmetric_keys/x509_cert_parser.c
-@@ -434,11 +434,10 @@ int x509_process_extension(void *context, size_t hdrlen,
- /*
- * Record a certificate time.
- */
--static int x509_note_time(time_t *_time, size_t hdrlen,
-+static int x509_note_time(struct tm *tm, size_t hdrlen,
- unsigned char tag,
- const unsigned char *value, size_t vlen)
- {
-- unsigned YY, MM, DD, hh, mm, ss;
- const unsigned char *p = value;
-
- #define dec2bin(X) ((X) - '0')
-@@ -448,30 +447,30 @@ static int x509_note_time(time_t *_time, size_t hdrlen,
- /* UTCTime: YYMMDDHHMMSSZ */
- if (vlen != 13)
- goto unsupported_time;
-- YY = DD2bin(p);
-- if (YY > 50)
-- YY += 1900;
-+ tm->tm_year = DD2bin(p);
-+ if (tm->tm_year >= 50)
-+ tm->tm_year += 1900;
- else
-- YY += 2000;
-+ tm->tm_year += 2000;
- } else if (tag == ASN1_GENTIM) {
- /* GenTime: YYYYMMDDHHMMSSZ */
- if (vlen != 15)
- goto unsupported_time;
-- YY = DD2bin(p) * 100 + DD2bin(p);
-+ tm->tm_year = DD2bin(p) * 100 + DD2bin(p);
- } else {
- goto unsupported_time;
- }
-
-- MM = DD2bin(p);
-- DD = DD2bin(p);
-- hh = DD2bin(p);
-- mm = DD2bin(p);
-- ss = DD2bin(p);
-+ tm->tm_year -= 1900;
-+ tm->tm_mon = DD2bin(p) - 1;
-+ tm->tm_mday = DD2bin(p);
-+ tm->tm_hour = DD2bin(p);
-+ tm->tm_min = DD2bin(p);
-+ tm->tm_sec = DD2bin(p);
-
- if (*p != 'Z')
- goto unsupported_time;
-
-- *_time = mktime(YY, MM, DD, hh, mm, ss);
- return 0;
-
- unsupported_time:
-diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
-index 635053f..f86dc5f 100644
---- a/crypto/asymmetric_keys/x509_parser.h
-+++ b/crypto/asymmetric_keys/x509_parser.h
-@@ -18,8 +18,8 @@ struct x509_certificate {
- char *subject; /* Name of certificate subject */
- char *fingerprint; /* Key fingerprint as hex */
- char *authority; /* Authority key fingerprint as hex */
-- time_t valid_from;
-- time_t valid_to;
-+ struct tm valid_from;
-+ struct tm valid_to;
- enum pkey_algo pkey_algo : 8; /* Public key algorithm */
- enum pkey_algo sig_pkey_algo : 8; /* Signature public key algorithm */
- enum pkey_hash_algo sig_hash_algo : 8; /* Signature hash algorithm */
-diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
-index 716917c..5ab736d 100644
---- a/crypto/asymmetric_keys/x509_public_key.c
-+++ b/crypto/asymmetric_keys/x509_public_key.c
-@@ -106,7 +106,7 @@ error_no_sig:
- static int x509_key_preparse(struct key_preparsed_payload *prep)
- {
- struct x509_certificate *cert;
-- time_t now;
-+ struct tm now;
- size_t srlen, sulen;
- char *desc = NULL;
- int ret;
-@@ -118,7 +118,14 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
- pr_devel("Cert Issuer: %s\n", cert->issuer);
- pr_devel("Cert Subject: %s\n", cert->subject);
- pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
-- pr_devel("Cert Valid: %lu - %lu\n", cert->valid_from, cert->valid_to);
-+ printk("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
-+ cert->valid_from.tm_mday, cert->valid_from.tm_hour,
-+ cert->valid_from.tm_min, cert->valid_from.tm_sec);
-+ printk("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1,
-+ cert->valid_to.tm_mday, cert->valid_to.tm_hour,
-+ cert->valid_to.tm_min, cert->valid_to.tm_sec);
- pr_devel("Cert Signature: %s + %s\n",
- pkey_algo[cert->sig_pkey_algo],
- pkey_hash_algo[cert->sig_hash_algo]);
-@@ -130,13 +137,38 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
- goto error_free_cert;
- }
-
-- now = CURRENT_TIME.tv_sec;
-- if (now < cert->valid_from) {
-+ time_to_tm(CURRENT_TIME.tv_sec, 0, &now);
-+ printk("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
-+ now.tm_hour, now.tm_min, now.tm_sec);
-+ if (now.tm_year < cert->valid_from.tm_year ||
-+ (now.tm_year == cert->valid_from.tm_year &&
-+ (now.tm_mon < cert->valid_from.tm_mon ||
-+ (now.tm_mon == cert->valid_from.tm_mon &&
-+ (now.tm_mday < cert->valid_from.tm_mday ||
-+ (now.tm_mday == cert->valid_from.tm_mday &&
-+ (now.tm_hour < cert->valid_from.tm_hour ||
-+ (now.tm_hour == cert->valid_from.tm_hour &&
-+ (now.tm_min < cert->valid_from.tm_min ||
-+ (now.tm_min == cert->valid_from.tm_min &&
-+ (now.tm_sec < cert->valid_from.tm_sec
-+ ))))))))))) {
- pr_warn("Cert %s is not yet valid\n", cert->fingerprint);
- ret = -EKEYREJECTED;
- goto error_free_cert;
- }
-- if (now >= cert->valid_to) {
-+ if (now.tm_year > cert->valid_to.tm_year ||
-+ (now.tm_year == cert->valid_to.tm_year &&
-+ (now.tm_mon > cert->valid_to.tm_mon ||
-+ (now.tm_mon == cert->valid_to.tm_mon &&
-+ (now.tm_mday > cert->valid_to.tm_mday ||
-+ (now.tm_mday == cert->valid_to.tm_mday &&
-+ (now.tm_hour > cert->valid_to.tm_hour ||
-+ (now.tm_hour == cert->valid_to.tm_hour &&
-+ (now.tm_min > cert->valid_to.tm_min ||
-+ (now.tm_min == cert->valid_to.tm_min &&
-+ (now.tm_sec > cert->valid_to.tm_sec
-+ ))))))))))) {
- pr_warn("Cert %s has expired\n", cert->fingerprint);
- ret = -EKEYEXPIRED;
- goto error_free_cert;
---
-1.7.12.1
-
-
-From f69bc56c32645bcc0b1a9ee88be662e8246398b4 Mon Sep 17 00:00:00 2001
-From: Randy Dunlap <rdunlap@xenotime.net>
-Date: Wed, 3 Oct 2012 16:04:46 -0700
-Subject: [PATCH 30/37] asymmetric keys: fix printk format warning
-
-Fix printk format warning in x509_cert_parser.c:
-
-crypto/asymmetric_keys/x509_cert_parser.c: In function 'x509_note_OID':
-crypto/asymmetric_keys/x509_cert_parser.c:113:3: warning: format '%zu' expects type 'size_t', but argument 2 has type 'long unsigned int'
-
-Builds cleanly on i386 and x86_64.
-
-Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
-Cc: David Howells <dhowells@redhat.com>
-Cc: Herbert Xu <herbert@gondor.apana.org.au>
-Cc: linux-crypto@vger.kernel.org
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/x509_cert_parser.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
-index db07e8c..7fabc4c 100644
---- a/crypto/asymmetric_keys/x509_cert_parser.c
-+++ b/crypto/asymmetric_keys/x509_cert_parser.c
-@@ -110,7 +110,7 @@ int x509_note_OID(void *context, size_t hdrlen,
- if (ctx->last_oid == OID__NR) {
- char buffer[50];
- sprint_oid(value, vlen, buffer, sizeof(buffer));
-- pr_debug("Unknown OID: [%zu] %s\n",
-+ pr_debug("Unknown OID: [%lu] %s\n",
- (unsigned long)value - ctx->data, buffer);
- }
- return 0;
---
-1.7.12.1
-
-
-From 81338d71c284b7d001004e4a03abfce2d2144087 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 4 Oct 2012 14:21:23 +0100
-Subject: [PATCH 31/37] X.509: Convert some printk calls to pr_devel
-
-Some debugging printk() calls should've been converted to pr_devel() calls.
-Do that now.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- crypto/asymmetric_keys/x509_public_key.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
-index 5ab736d..06007f0 100644
---- a/crypto/asymmetric_keys/x509_public_key.c
-+++ b/crypto/asymmetric_keys/x509_public_key.c
-@@ -118,11 +118,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
- pr_devel("Cert Issuer: %s\n", cert->issuer);
- pr_devel("Cert Subject: %s\n", cert->subject);
- pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
-- printk("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
- cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
- cert->valid_from.tm_mday, cert->valid_from.tm_hour,
- cert->valid_from.tm_min, cert->valid_from.tm_sec);
-- printk("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ pr_devel("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n",
- cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1,
- cert->valid_to.tm_mday, cert->valid_to.tm_hour,
- cert->valid_to.tm_min, cert->valid_to.tm_sec);
-@@ -138,7 +138,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
- }
-
- time_to_tm(CURRENT_TIME.tv_sec, 0, &now);
-- printk("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
-+ pr_devel("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
- now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
- now.tm_hour, now.tm_min, now.tm_sec);
- if (now.tm_year < cert->valid_from.tm_year ||
---
-1.7.12.1
-
-
-From 1054ea17fe1bf8f2087197c453626153d4649ac5 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Thu, 4 Oct 2012 14:21:23 +0100
-Subject: [PATCH 32/37] X.509: Fix indefinite length element skip error
- handling
-
-asn1_find_indefinite_length() returns an error indicator of -1, which the
-caller asn1_ber_decoder() places in a size_t (which is usually unsigned) and
-then checks to see whether it is less than 0 (which it can't be). This can
-lead to the following warning:
-
- lib/asn1_decoder.c:320 asn1_ber_decoder()
- warn: unsigned 'len' is never less than zero.
-
-Instead, asn1_find_indefinite_length() update the caller's idea of the data
-cursor and length separately from returning the error code.
-
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- lib/asn1_decoder.c | 28 +++++++++++++++++++---------
- 1 file changed, 19 insertions(+), 9 deletions(-)
-
-diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
-index 2e4196d..de2c8b5 100644
---- a/lib/asn1_decoder.c
-+++ b/lib/asn1_decoder.c
-@@ -46,12 +46,18 @@ static const unsigned char asn1_op_lengths[ASN1_OP__NR] = {
-
- /*
- * Find the length of an indefinite length object
-+ * @data: The data buffer
-+ * @datalen: The end of the innermost containing element in the buffer
-+ * @_dp: The data parse cursor (updated before returning)
-+ * @_len: Where to return the size of the element.
-+ * @_errmsg: Where to return a pointer to an error message on error
- */
- static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen,
-- const char **_errmsg, size_t *_err_dp)
-+ size_t *_dp, size_t *_len,
-+ const char **_errmsg)
- {
- unsigned char tag, tmp;
-- size_t dp = 0, len, n;
-+ size_t dp = *_dp, len, n;
- int indef_level = 1;
-
- next_tag:
-@@ -67,8 +73,11 @@ next_tag:
- /* It appears to be an EOC. */
- if (data[dp++] != 0)
- goto invalid_eoc;
-- if (--indef_level <= 0)
-- return dp;
-+ if (--indef_level <= 0) {
-+ *_len = dp - *_dp;
-+ *_dp = dp;
-+ return 0;
-+ }
- goto next_tag;
- }
-
-@@ -122,7 +131,7 @@ data_overrun_error:
- missing_eoc:
- *_errmsg = "Missing EOC in indefinite len cons";
- error:
-- *_err_dp = dp;
-+ *_dp = dp;
- return -1;
- }
-
-@@ -315,13 +324,14 @@ next_op:
- skip_data:
- if (!(flags & FLAG_CONS)) {
- if (flags & FLAG_INDEFINITE_LENGTH) {
-- len = asn1_find_indefinite_length(
-- data + dp, datalen - dp, &errmsg, &dp);
-- if (len < 0)
-+ ret = asn1_find_indefinite_length(
-+ data, datalen, &dp, &len, &errmsg);
-+ if (ret < 0)
- goto error;
-+ } else {
-+ dp += len;
- }
- pr_debug("- LEAF: %zu\n", len);
-- dp += len;
- }
- pc += asn1_op_lengths[op];
- goto next_op;
---
-1.7.12.1
-
-
-From 4ae37452e7450971072481b98f6e1c29e5165c1e Mon Sep 17 00:00:00 2001
-From: Rusty Russell <rusty@rustcorp.com.au>
-Date: Fri, 19 Oct 2012 11:53:15 +1030
-Subject: [PATCH 33/37] kbuild: sign the modules at install time
-
-Linus deleted the old code and put signing on the install command,
-I fixed it to extract the keyid and signer-name within sign-file
-and cleaned up that script now it always signs in-place.
-
-Some enthusiast should convert sign-key to perl and pull
-x509keyid into it.
-
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- Makefile | 11 +++++++
- scripts/Makefile.modinst | 2 +-
- scripts/Makefile.modpost | 77 +-----------------------------------------------
- scripts/sign-file | 44 +++++++++++----------------
- scripts/x509keyid | 16 +++++-----
- 5 files changed, 39 insertions(+), 111 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index e4292ea..1cc5de4 100644
---- a/Makefile
-+++ b/Makefile
-@@ -714,6 +714,17 @@ endif # INSTALL_MOD_STRIP
- export mod_strip_cmd
-
-
-+ifeq ($(CONFIG_MODULE_SIG),y)
-+MODSECKEY = ./signing_key.priv
-+MODPUBKEY = ./signing_key.x509
-+export MODPUBKEY
-+mod_sign_cmd = sh $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY) $(srctree)/scripts/x509keyid
-+else
-+mod_sign_cmd = true
-+endif
-+export mod_sign_cmd
-+
-+
- ifeq ($(KBUILD_EXTMOD),)
- core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
-
-diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
-index efa5d94..38367bd 100644
---- a/scripts/Makefile.modinst
-+++ b/scripts/Makefile.modinst
-@@ -17,7 +17,7 @@ __modinst: $(modules)
- @:
-
- quiet_cmd_modules_install = INSTALL $@
-- cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@)
-+ cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@)
-
- # Modules built outside the kernel source tree go into extra by default
- INSTALL_MOD_DIR ?= extra
-diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
-index 2a4d1a1..08dce14 100644
---- a/scripts/Makefile.modpost
-+++ b/scripts/Makefile.modpost
-@@ -14,8 +14,7 @@
- # 3) create one <module>.mod.c file pr. module
- # 4) create one Module.symvers file with CRC for all exported symbols
- # 5) compile all <module>.mod.c files
--# 6) final link of the module to a <module.ko> (or <module.unsigned>) file
--# 7) signs the modules to a <module.ko> file
-+# 6) final link of the module to a <module.ko> file
-
- # Step 3 is used to place certain information in the module's ELF
- # section, including information such as:
-@@ -33,8 +32,6 @@
- # Step 4 is solely used to allow module versioning in external modules,
- # where the CRC of each module is retrieved from the Module.symvers file.
-
--# Step 7 is dependent on CONFIG_MODULE_SIG being enabled.
--
- # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
- # symbols in the final module linking stage
- # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
-@@ -119,7 +116,6 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
- targets += $(modules:.ko=.mod.o)
-
- # Step 6), final link of the modules
--ifneq ($(CONFIG_MODULE_SIG),y)
- quiet_cmd_ld_ko_o = LD [M] $@
- cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
- $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-@@ -129,78 +125,7 @@ $(modules): %.ko :%.o %.mod.o FORCE
- $(call if_changed,ld_ko_o)
-
- targets += $(modules)
--else
--quiet_cmd_ld_ko_unsigned_o = LD [M] $@
-- cmd_ld_ko_unsigned_o = \
-- $(LD) -r $(LDFLAGS) \
-- $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-- -o $@ $(filter-out FORCE,$^) \
-- $(if $(AFTER_LINK),; $(AFTER_LINK))
--
--$(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE
-- $(call if_changed,ld_ko_unsigned_o)
--
--targets += $(modules:.ko=.ko.unsigned)
--
--# Step 7), sign the modules
--MODSECKEY = ./signing_key.priv
--MODPUBKEY = ./signing_key.x509
--
--ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY))
--ifeq ($(KBUILD_SRC),)
-- # no O= is being used
-- SCRIPTS_DIR := scripts
--else
-- SCRIPTS_DIR := $(KBUILD_SRC)/scripts
--endif
--SIGN_MODULES := 1
--else
--SIGN_MODULES := 0
--endif
--
--# only sign if it's an in-tree module
--ifneq ($(KBUILD_EXTMOD),)
--SIGN_MODULES := 0
--endif
-
--# We strip the module as best we can - note that using both strip and eu-strip
--# results in a smaller module than using either alone.
--EU_STRIP = $(shell which eu-strip || echo true)
--
--quiet_cmd_sign_ko_stripped_ko_unsigned = STRIP [M] $@
-- cmd_sign_ko_stripped_ko_unsigned = \
-- cp $< $@ && \
-- strip -x -g $@ && \
-- $(EU_STRIP) $@
--
--ifeq ($(SIGN_MODULES),1)
--
--quiet_cmd_genkeyid = GENKEYID $@
-- cmd_genkeyid = \
-- perl $(SCRIPTS_DIR)/x509keyid $< $<.signer $<.keyid
--
--%.signer %.keyid: %
-- $(call if_changed,genkeyid)
--
--KEYRING_DEP := $(MODSECKEY) $(MODPUBKEY) $(MODPUBKEY).signer $(MODPUBKEY).keyid
--quiet_cmd_sign_ko_ko_stripped = SIGN [M] $@
-- cmd_sign_ko_ko_stripped = \
-- sh $(SCRIPTS_DIR)/sign-file $(MODSECKEY) $(MODPUBKEY) $< $@
--else
--KEYRING_DEP :=
--quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@
-- cmd_sign_ko_ko_unsigned = \
-- cp $< $@
--endif
--
--$(modules): %.ko :%.ko.stripped $(KEYRING_DEP) FORCE
-- $(call if_changed,sign_ko_ko_stripped)
--
--$(patsubst %.ko,%.ko.stripped,$(modules)): %.ko.stripped :%.ko.unsigned FORCE
-- $(call if_changed,sign_ko_stripped_ko_unsigned)
--
--targets += $(modules)
--endif
-
- # Add FORCE to the prequisites of a target to force it to be always rebuilt.
- # ---------------------------------------------------------------------------
-diff --git a/scripts/sign-file b/scripts/sign-file
-index e58e34e..095a953 100644
---- a/scripts/sign-file
-+++ b/scripts/sign-file
-@@ -1,8 +1,8 @@
--#!/bin/sh
-+#!/bin/bash
- #
- # Sign a module file using the given key.
- #
--# Format: sign-file <key> <x509> <src-file> <dst-file>
-+# Format: sign-file <key> <x509> <keyid-script> <module>
- #
-
- scripts=`dirname $0`
-@@ -15,8 +15,8 @@ fi
-
- key="$1"
- x509="$2"
--src="$3"
--dst="$4"
-+keyid_script="$3"
-+mod="$4"
-
- if [ ! -r "$key" ]
- then
-@@ -29,16 +29,6 @@ then
- echo "Can't read X.509 certificate" >&2
- exit 2
- fi
--if [ ! -r "$x509.signer" ]
--then
-- echo "Can't read Signer name" >&2
-- exit 2;
--fi
--if [ ! -r "$x509.keyid" ]
--then
-- echo "Can't read Key identifier" >&2
-- exit 2;
--fi
-
- #
- # Signature parameters
-@@ -83,33 +73,35 @@ fi
-
- (
- perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $?
--openssl dgst $dgst -binary $src || exit $?
--) >$src.dig || exit $?
-+openssl dgst $dgst -binary $mod || exit $?
-+) >$mod.dig || exit $?
-
- #
- # Generate the binary signature, which will be just the integer that comprises
- # the signature with no metadata attached.
- #
--openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $?
--signerlen=`stat -c %s $x509.signer`
--keyidlen=`stat -c %s $x509.keyid`
--siglen=`stat -c %s $src.sig`
-+openssl rsautl -sign -inkey $key -keyform PEM -in $mod.dig -out $mod.sig || exit $?
-+
-+SIGNER="`perl $keyid_script $x509 signer-name`"
-+KEYID="`perl $keyid_script $x509 keyid`"
-+keyidlen=${#KEYID}
-+siglen=${#SIGNER}
-
- #
- # Build the signed binary
- #
- (
-- cat $src || exit $?
-+ cat $mod || exit $?
- echo '~Module signature appended~' || exit $?
-- cat $x509.signer $x509.keyid || exit $?
-+ echo -n "$SIGNER" || exit $?
-+ echo -n "$KEYID" || exit $?
-
- # Preface each signature integer with a 2-byte BE length
- perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $?
-- cat $src.sig || exit $?
-+ cat $mod.sig || exit $?
-
- # Generate the information block
- perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $?
--) >$dst~ || exit $?
-+) >$mod~ || exit $?
-
--# Permit in-place signing
--mv $dst~ $dst || exit $?
-+mv $mod~ $mod || exit $?
-diff --git a/scripts/x509keyid b/scripts/x509keyid
-index c8e91a4..4241ec6 100755
---- a/scripts/x509keyid
-+++ b/scripts/x509keyid
-@@ -22,7 +22,7 @@ use strict;
-
- my $raw_data;
-
--die "Need three filenames\n" if ($#ARGV != 2);
-+die "Need a filename [keyid|signer-name]\n" if ($#ARGV != 1);
-
- my $src = $ARGV[0];
-
-@@ -259,10 +259,10 @@ die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
-
- my $id_key_id = asn1_retrieve($subject_key_id->[1]);
-
--open(OUTFD, ">$ARGV[1]") || die $ARGV[1];
--print OUTFD $id_name;
--close OUTFD || die $ARGV[1];
--
--open(OUTFD, ">$ARGV[2]") || die $ARGV[2];
--print OUTFD $id_key_id;
--close OUTFD || die $ARGV[2];
-+if ($ARGV[1] eq "signer-name") {
-+ print $id_name;
-+} elsif ($ARGV[1] eq "keyid") {
-+ print $id_key_id;
-+} else {
-+ die "Unknown arg";
-+}
---
-1.7.12.1
-
-
-From 4aa23562520f07f4f27edb5c289bc289438005a0 Mon Sep 17 00:00:00 2001
-From: Linus Torvalds <torvalds@linux-foundation.org>
-Date: Fri, 19 Oct 2012 12:43:19 -0700
-Subject: [PATCH 34/37] kbuild: Fix module signature generation
-
-Rusty had clearly not actually tested his module signing changes that I
-(trustingly) applied as commit e2a666d52b48 ("kbuild: sign the modules
-at install time"). That commit had multiple bugs:
-
- - using "${#VARIABLE}" to get the number of characters in a shell
- variable may look clever, but it's locale-dependent: it returns the
- number of *characters*, not bytes. And we do need bytes.
-
- So don't use "${#..}" expansion, do the stupid "wc -c" thing instead
- (where "c" stands for "bytes", not "characters", despite the letter.
-
- - Rusty had confused "siglen" and "signerlen", and his conversion
- didn't set "signerlen" at all, and incorrectly set "siglen" to the
- size of the signer, not the size of the signature.
-
-End result: the modified sign-file script did create something that
-superficially *looked* like a signature, but didn't actually work at
-all, and would fail the signature check. Oops.
-
-Tssk, tssk, Rusty.
-
-But Rusty was definitely right that this whole thing should be rewritten
-in perl by somebody who has the perl-fu to do so. That is not me,
-though - I'm just doing an emergency fix for the shell script.
-
-Cc: Rusty Russell <rusty@rustcorp.com.au>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- scripts/sign-file | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/scripts/sign-file b/scripts/sign-file
-index 095a953..d014abd 100644
---- a/scripts/sign-file
-+++ b/scripts/sign-file
-@@ -81,11 +81,12 @@ openssl dgst $dgst -binary $mod || exit $?
- # the signature with no metadata attached.
- #
- openssl rsautl -sign -inkey $key -keyform PEM -in $mod.dig -out $mod.sig || exit $?
-+siglen=`stat -c %s $mod.sig`
-
- SIGNER="`perl $keyid_script $x509 signer-name`"
- KEYID="`perl $keyid_script $x509 keyid`"
--keyidlen=${#KEYID}
--siglen=${#SIGNER}
-+keyidlen=$(echo -n "$KEYID" | wc -c)
-+signerlen=$(echo -n "$SIGNER" | wc -c)
-
- #
- # Build the signed binary
---
-1.7.12.1
-
-
-From f51b71db2cae9539acaa4d64a9e708d7aac1f879 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 19 Oct 2012 23:56:37 +0100
-Subject: [PATCH 35/37] MODSIGN: perlify sign-file and merge in x509keyid
-
-Turn sign-file into perl and merge in x509keyid. The latter doesn't
-need to be a separate script as it doesn't actually need to work out the
-SHA1 sum of the X.509 certificate itself, since it can get that from the
-X.509 certificate.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- Makefile | 2 +-
- scripts/sign-file | 477 +++++++++++++++++++++++++++++++++++++++++++++---------
- scripts/x509keyid | 268 ------------------------------
- 3 files changed, 400 insertions(+), 347 deletions(-)
- mode change 100644 => 100755 scripts/sign-file
- delete mode 100755 scripts/x509keyid
-
-diff --git a/Makefile b/Makefile
-index 1cc5de4..f4f9cdb 100644
---- a/Makefile
-+++ b/Makefile
-@@ -718,7 +718,7 @@ ifeq ($(CONFIG_MODULE_SIG),y)
- MODSECKEY = ./signing_key.priv
- MODPUBKEY = ./signing_key.x509
- export MODPUBKEY
--mod_sign_cmd = sh $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY) $(srctree)/scripts/x509keyid
-+mod_sign_cmd = perl $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY)
- else
- mod_sign_cmd = true
- endif
-diff --git a/scripts/sign-file b/scripts/sign-file
-old mode 100644
-new mode 100755
-index d014abd..d37d130
---- a/scripts/sign-file
-+++ b/scripts/sign-file
-@@ -1,108 +1,429 @@
--#!/bin/bash
-+#!/usr/bin/perl -w
- #
- # Sign a module file using the given key.
- #
--# Format: sign-file <key> <x509> <keyid-script> <module>
-+# Format:
- #
-+# ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]
-+#
-+#
-+use strict;
-+use FileHandle;
-+use IPC::Open2;
-+
-+my $verbose = 0;
-+if ($#ARGV >= 0 && $ARGV[0] eq "-v") {
-+ $verbose = 1;
-+ shift;
-+}
-+
-+die "Format: ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]\n"
-+ if ($#ARGV != 2 && $#ARGV != 3);
-+
-+my $private_key = $ARGV[0];
-+my $x509 = $ARGV[1];
-+my $module = $ARGV[2];
-+my $dest = ($#ARGV == 3) ? $ARGV[3] : $ARGV[2] . "~";
-+
-+die "Can't read private key\n" unless (-r $private_key);
-+die "Can't read X.509 certificate\n" unless (-r $x509);
-+die "Can't read module\n" unless (-r $module);
-+
-+#
-+# Read the kernel configuration
-+#
-+my %config = (
-+ CONFIG_MODULE_SIG_SHA512 => 1
-+ );
-+
-+if (-r ".config") {
-+ open(FD, "<.config") || die ".config";
-+ while (<FD>) {
-+ if ($_ =~ /^(CONFIG_.*)=[ym]/) {
-+ $config{$1} = 1;
-+ }
-+ }
-+ close(FD);
-+}
-
--scripts=`dirname $0`
-+#
-+# Function to read the contents of a file into a variable.
-+#
-+sub read_file($)
-+{
-+ my ($file) = @_;
-+ my $contents;
-+ my $len;
-+
-+ open(FD, "<$file") || die $file;
-+ binmode FD;
-+ my @st = stat(FD);
-+ die $file if (!@st);
-+ $len = read(FD, $contents, $st[7]) || die $file;
-+ close(FD) || die $file;
-+ die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
-+ if ($len != $st[7]);
-+ return $contents;
-+}
-+
-+###############################################################################
-+#
-+# First of all, we have to parse the X.509 certificate to find certain details
-+# about it.
-+#
-+# We read the DER-encoded X509 certificate and parse it to extract the Subject
-+# name and Subject Key Identifier. Theis provides the data we need to build
-+# the certificate identifier.
-+#
-+# The signer's name part of the identifier is fabricated from the commonName,
-+# the organizationName or the emailAddress components of the X.509 subject
-+# name.
-+#
-+# The subject key ID is used to select which of that signer's certificates
-+# we're intending to use to sign the module.
-+#
-+###############################################################################
-+my $x509_certificate = read_file($x509);
-
--CONFIG_MODULE_SIG_SHA512=y
--if [ -r .config ]
--then
-- . ./.config
--fi
-+my $UNIV = 0 << 6;
-+my $APPL = 1 << 6;
-+my $CONT = 2 << 6;
-+my $PRIV = 3 << 6;
-
--key="$1"
--x509="$2"
--keyid_script="$3"
--mod="$4"
-+my $CONS = 0x20;
-
--if [ ! -r "$key" ]
--then
-- echo "Can't read private key" >&2
-- exit 2
--fi
-+my $BOOLEAN = 0x01;
-+my $INTEGER = 0x02;
-+my $BIT_STRING = 0x03;
-+my $OCTET_STRING = 0x04;
-+my $NULL = 0x05;
-+my $OBJ_ID = 0x06;
-+my $UTF8String = 0x0c;
-+my $SEQUENCE = 0x10;
-+my $SET = 0x11;
-+my $UTCTime = 0x17;
-+my $GeneralizedTime = 0x18;
-
--if [ ! -r "$x509" ]
--then
-- echo "Can't read X.509 certificate" >&2
-- exit 2
--fi
-+my %OIDs = (
-+ pack("CCC", 85, 4, 3) => "commonName",
-+ pack("CCC", 85, 4, 6) => "countryName",
-+ pack("CCC", 85, 4, 10) => "organizationName",
-+ pack("CCC", 85, 4, 11) => "organizationUnitName",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
-+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
-+ pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
-+ pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
-+ pack("CCC", 85, 29, 19) => "basicConstraints"
-+);
-+
-+###############################################################################
-+#
-+# Extract an ASN.1 element from a string and return information about it.
-+#
-+###############################################################################
-+sub asn1_extract($$@)
-+{
-+ my ($cursor, $expected_tag, $optional) = @_;
-+
-+ return [ -1 ]
-+ if ($cursor->[1] == 0 && $optional);
-+
-+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
-+ if ($cursor->[1] < 2);
-+
-+ my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
-+
-+ if ($expected_tag != -1 && $tag != $expected_tag) {
-+ return [ -1 ]
-+ if ($optional);
-+ die $x509, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
-+ " not ", $expected_tag, ")\n";
-+ }
-+
-+ $cursor->[0] += 2;
-+ $cursor->[1] -= 2;
-+
-+ die $x509, ": ", $cursor->[0], ": ASN.1 long tag\n"
-+ if (($tag & 0x1f) == 0x1f);
-+ die $x509, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
-+ if ($len == 0x80);
-+
-+ if ($len > 0x80) {
-+ my $l = $len - 0x80;
-+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
-+ if ($cursor->[1] < $l);
-+
-+ if ($l == 0x1) {
-+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
-+ } elsif ($l = 0x2) {
-+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
-+ } elsif ($l = 0x3) {
-+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
-+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
-+ } elsif ($l = 0x4) {
-+ $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
-+ } else {
-+ die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
-+ }
-+
-+ $cursor->[0] += $l;
-+ $cursor->[1] -= $l;
-+ }
-+
-+ die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
-+ if ($cursor->[1] < $len);
-+
-+ my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
-+ $cursor->[0] += $len;
-+ $cursor->[1] -= $len;
-+
-+ return $ret;
-+}
-+
-+###############################################################################
-+#
-+# Retrieve the data referred to by a cursor
-+#
-+###############################################################################
-+sub asn1_retrieve($)
-+{
-+ my ($cursor) = @_;
-+ my ($offset, $len, $data) = @$cursor;
-+ return substr($$data, $offset, $len);
-+}
-+
-+###############################################################################
-+#
-+# Roughly parse the X.509 certificate
-+#
-+###############################################################################
-+my $cursor = [ 0, length($x509_certificate), \$x509_certificate ];
-+
-+my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
-+my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
-+my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
-+my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
-+my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
-+my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
-+my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
-+my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
-+
-+my $subject_key_id = ();
-+my $authority_key_id = ();
-+
-+#
-+# Parse the extension list
-+#
-+if ($extension_list->[0] != -1) {
-+ my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
-+
-+ while ($extensions->[1]->[1] > 0) {
-+ my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
-+ my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
-+ my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
-+ my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
-+
-+ my $raw_oid = asn1_retrieve($x_oid->[1]);
-+ next if (!exists($OIDs{$raw_oid}));
-+ my $x_type = $OIDs{$raw_oid};
-+
-+ my $raw_value = asn1_retrieve($x_val->[1]);
-+
-+ if ($x_type eq "subjectKeyIdentifier") {
-+ my $vcursor = [ 0, length($raw_value), \$raw_value ];
-+
-+ $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
-+ }
-+ }
-+}
-+
-+###############################################################################
-+#
-+# Determine what we're going to use as the signer's name. In order of
-+# preference, take one of: commonName, organizationName or emailAddress.
-+#
-+###############################################################################
-+my $org = "";
-+my $cn = "";
-+my $email = "";
-+
-+while ($subject->[1]->[1] > 0) {
-+ my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
-+ my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
-+ my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
-+ my $n_val = asn1_extract($attr->[1], -1);
-+
-+ my $raw_oid = asn1_retrieve($n_oid->[1]);
-+ next if (!exists($OIDs{$raw_oid}));
-+ my $n_type = $OIDs{$raw_oid};
-+
-+ my $raw_value = asn1_retrieve($n_val->[1]);
-+
-+ if ($n_type eq "organizationName") {
-+ $org = $raw_value;
-+ } elsif ($n_type eq "commonName") {
-+ $cn = $raw_value;
-+ } elsif ($n_type eq "emailAddress") {
-+ $email = $raw_value;
-+ }
-+}
-+
-+my $signers_name = $email;
-+
-+if ($org && $cn) {
-+ # Don't use the organizationName if the commonName repeats it
-+ if (length($org) <= length($cn) &&
-+ substr($cn, 0, length($org)) eq $org) {
-+ $signers_name = $cn;
-+ goto got_id_name;
-+ }
-+
-+ # Or a signifcant chunk of it
-+ if (length($org) >= 7 &&
-+ length($cn) >= 7 &&
-+ substr($cn, 0, 7) eq substr($org, 0, 7)) {
-+ $signers_name = $cn;
-+ goto got_id_name;
-+ }
-+
-+ $signers_name = $org . ": " . $cn;
-+} elsif ($org) {
-+ $signers_name = $org;
-+} elsif ($cn) {
-+ $signers_name = $cn;
-+}
-+
-+got_id_name:
-+
-+die $x509, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
-+ if (!$subject_key_id);
-+
-+my $key_identifier = asn1_retrieve($subject_key_id->[1]);
-+
-+###############################################################################
-+#
-+# Create and attach the module signature
-+#
-+###############################################################################
-
- #
- # Signature parameters
- #
--algo=1 # Public-key crypto algorithm: RSA
--hash= # Digest algorithm
--id_type=1 # Identifier type: X.509
-+my $algo = 1; # Public-key crypto algorithm: RSA
-+my $hash = 0; # Digest algorithm
-+my $id_type = 1; # Identifier type: X.509
-
- #
- # Digest the data
- #
--dgst=
--if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ]
--then
-- prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14"
-- dgst=-sha1
-- hash=2
--elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ]
--then
-- prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C"
-- dgst=-sha224
-- hash=7
--elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ]
--then
-- prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20"
-- dgst=-sha256
-- hash=4
--elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ]
--then
-- prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30"
-- dgst=-sha384
-- hash=5
--elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ]
--then
-- prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40"
-- dgst=-sha512
-- hash=6
--else
-- echo "$0: Can't determine hash algorithm" >&2
-- exit 2
--fi
--
--(
--perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $?
--openssl dgst $dgst -binary $mod || exit $?
--) >$mod.dig || exit $?
-+my ($dgst, $prologue) = ();
-+if (exists $config{"CONFIG_MODULE_SIG_SHA1"}) {
-+ $prologue = pack("C*",
-+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-+ 0x2B, 0x0E, 0x03, 0x02, 0x1A,
-+ 0x05, 0x00, 0x04, 0x14);
-+ $dgst = "-sha1";
-+ $hash = 2;
-+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA224"}) {
-+ $prologue = pack("C*",
-+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
-+ 0x05, 0x00, 0x04, 0x1C);
-+ $dgst = "-sha224";
-+ $hash = 7;
-+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA256"}) {
-+ $prologue = pack("C*",
-+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-+ 0x05, 0x00, 0x04, 0x20);
-+ $dgst = "-sha256";
-+ $hash = 4;
-+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA384"}) {
-+ $prologue = pack("C*",
-+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
-+ 0x05, 0x00, 0x04, 0x30);
-+ $dgst = "-sha384";
-+ $hash = 5;
-+} elsif (exists $config{"CONFIG_MODULE_SIG_SHA512"}) {
-+ $prologue = pack("C*",
-+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
-+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
-+ 0x05, 0x00, 0x04, 0x40);
-+ $dgst = "-sha512";
-+ $hash = 6;
-+} else {
-+ die "Can't determine hash algorithm";
-+}
-+
-+#
-+# Generate the digest and read from openssl's stdout
-+#
-+my $digest;
-+$digest = readpipe("openssl dgst $dgst -binary $module") || die "openssl dgst";
-
- #
- # Generate the binary signature, which will be just the integer that comprises
- # the signature with no metadata attached.
- #
--openssl rsautl -sign -inkey $key -keyform PEM -in $mod.dig -out $mod.sig || exit $?
--siglen=`stat -c %s $mod.sig`
-+my $pid;
-+$pid = open2(*read_from, *write_to,
-+ "openssl rsautl -sign -inkey $private_key -keyform PEM") ||
-+ die "openssl rsautl";
-+binmode write_to;
-+print write_to $prologue . $digest || die "pipe to openssl rsautl";
-+close(write_to) || die "pipe to openssl rsautl";
-+
-+binmode read_from;
-+my $signature;
-+read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
-+close(read_from) || die "pipe from openssl rsautl";
-+$signature = pack("n", length($signature)) . $signature,
-
--SIGNER="`perl $keyid_script $x509 signer-name`"
--KEYID="`perl $keyid_script $x509 keyid`"
--keyidlen=$(echo -n "$KEYID" | wc -c)
--signerlen=$(echo -n "$SIGNER" | wc -c)
-+waitpid($pid, 0) || die;
-+die "openssl rsautl died: $?" if ($? >> 8);
-
- #
- # Build the signed binary
- #
--(
-- cat $mod || exit $?
-- echo '~Module signature appended~' || exit $?
-- echo -n "$SIGNER" || exit $?
-- echo -n "$KEYID" || exit $?
-+my $unsigned_module = read_file($module);
-+
-+my $magic_number = "~Module signature appended~\n";
-+
-+my $info = pack("CCCCCxxxN",
-+ $algo, $hash, $id_type,
-+ length($signers_name),
-+ length($key_identifier),
-+ length($signature));
-
-- # Preface each signature integer with a 2-byte BE length
-- perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $?
-- cat $mod.sig || exit $?
-+if ($verbose) {
-+ print "Size of unsigned module: ", length($unsigned_module), "\n";
-+ print "Size of magic number : ", length($magic_number), "\n";
-+ print "Size of signer's name : ", length($signers_name), "\n";
-+ print "Size of key identifier : ", length($key_identifier), "\n";
-+ print "Size of signature : ", length($signature), "\n";
-+ print "Size of informaton : ", length($info), "\n";
-+ print "Signer's name : '", $signers_name, "'\n";
-+ print "Digest : $dgst\n";
-+}
-
-- # Generate the information block
-- perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $?
--) >$mod~ || exit $?
-+open(FD, ">$dest") || die $dest;
-+binmode FD;
-+print FD
-+ $unsigned_module,
-+ $magic_number,
-+ $signers_name,
-+ $key_identifier,
-+ $signature,
-+ $info
-+ ;
-+close FD || die $dest;
-
--mv $mod~ $mod || exit $?
-+if ($#ARGV != 3) {
-+ rename($dest, $module) || die $module;
-+}
-diff --git a/scripts/x509keyid b/scripts/x509keyid
-deleted file mode 100755
-index 4241ec6..0000000
---- a/scripts/x509keyid
-+++ /dev/null
-@@ -1,268 +0,0 @@
--#!/usr/bin/perl -w
--#
--# Generate an identifier from an X.509 certificate that can be placed in a
--# module signature to indentify the key to use.
--#
--# Format:
--#
--# ./scripts/x509keyid <x509-cert> <signer's-name> <key-id>
--#
--# We read the DER-encoded X509 certificate and parse it to extract the Subject
--# name and Subject Key Identifier. The provide the data we need to build the
--# certificate identifier.
--#
--# The signer's name part of the identifier is fabricated from the commonName,
--# the organizationName or the emailAddress components of the X.509 subject
--# name and written to the second named file.
--#
--# The subject key ID to select which of that signer's certificates we're
--# intending to use to sign the module is written to the third named file.
--#
--use strict;
--
--my $raw_data;
--
--die "Need a filename [keyid|signer-name]\n" if ($#ARGV != 1);
--
--my $src = $ARGV[0];
--
--open(FD, "<$src") || die $src;
--binmode FD;
--my @st = stat(FD);
--die $src if (!@st);
--read(FD, $raw_data, $st[7]) || die $src;
--close(FD);
--
--my $UNIV = 0 << 6;
--my $APPL = 1 << 6;
--my $CONT = 2 << 6;
--my $PRIV = 3 << 6;
--
--my $CONS = 0x20;
--
--my $BOOLEAN = 0x01;
--my $INTEGER = 0x02;
--my $BIT_STRING = 0x03;
--my $OCTET_STRING = 0x04;
--my $NULL = 0x05;
--my $OBJ_ID = 0x06;
--my $UTF8String = 0x0c;
--my $SEQUENCE = 0x10;
--my $SET = 0x11;
--my $UTCTime = 0x17;
--my $GeneralizedTime = 0x18;
--
--my %OIDs = (
-- pack("CCC", 85, 4, 3) => "commonName",
-- pack("CCC", 85, 4, 6) => "countryName",
-- pack("CCC", 85, 4, 10) => "organizationName",
-- pack("CCC", 85, 4, 11) => "organizationUnitName",
-- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
-- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
-- pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
-- pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
-- pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
-- pack("CCC", 85, 29, 19) => "basicConstraints"
--);
--
--###############################################################################
--#
--# Extract an ASN.1 element from a string and return information about it.
--#
--###############################################################################
--sub asn1_extract($$@)
--{
-- my ($cursor, $expected_tag, $optional) = @_;
--
-- return [ -1 ]
-- if ($cursor->[1] == 0 && $optional);
--
-- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
-- if ($cursor->[1] < 2);
--
-- my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
--
-- if ($expected_tag != -1 && $tag != $expected_tag) {
-- return [ -1 ]
-- if ($optional);
-- die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
-- " not ", $expected_tag, ")\n";
-- }
--
-- $cursor->[0] += 2;
-- $cursor->[1] -= 2;
--
-- die $src, ": ", $cursor->[0], ": ASN.1 long tag\n"
-- if (($tag & 0x1f) == 0x1f);
-- die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
-- if ($len == 0x80);
--
-- if ($len > 0x80) {
-- my $l = $len - 0x80;
-- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
-- if ($cursor->[1] < $l);
--
-- if ($l == 0x1) {
-- $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
-- } elsif ($l = 0x2) {
-- $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
-- } elsif ($l = 0x3) {
-- $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
-- $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
-- } elsif ($l = 0x4) {
-- $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
-- } else {
-- die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
-- }
--
-- $cursor->[0] += $l;
-- $cursor->[1] -= $l;
-- }
--
-- die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
-- if ($cursor->[1] < $len);
--
-- my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
-- $cursor->[0] += $len;
-- $cursor->[1] -= $len;
--
-- return $ret;
--}
--
--###############################################################################
--#
--# Retrieve the data referred to by a cursor
--#
--###############################################################################
--sub asn1_retrieve($)
--{
-- my ($cursor) = @_;
-- my ($offset, $len, $data) = @$cursor;
-- return substr($$data, $offset, $len);
--}
--
--###############################################################################
--#
--# Roughly parse the X.509 certificate
--#
--###############################################################################
--my $cursor = [ 0, length($raw_data), \$raw_data ];
--
--my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
--my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
--my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
--my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
--my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
--my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
--my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
--my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
--my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
--my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
--my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
--my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
--
--my $subject_key_id = ();
--my $authority_key_id = ();
--
--#
--# Parse the extension list
--#
--if ($extension_list->[0] != -1) {
-- my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
--
-- while ($extensions->[1]->[1] > 0) {
-- my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
-- my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
-- my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
-- my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
--
-- my $raw_oid = asn1_retrieve($x_oid->[1]);
-- next if (!exists($OIDs{$raw_oid}));
-- my $x_type = $OIDs{$raw_oid};
--
-- my $raw_value = asn1_retrieve($x_val->[1]);
--
-- if ($x_type eq "subjectKeyIdentifier") {
-- my $vcursor = [ 0, length($raw_value), \$raw_value ];
--
-- $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
-- }
-- }
--}
--
--###############################################################################
--#
--# Determine what we're going to use as the signer's name. In order of
--# preference, take one of: commonName, organizationName or emailAddress.
--#
--###############################################################################
--my $org = "";
--my $cn = "";
--my $email = "";
--
--while ($subject->[1]->[1] > 0) {
-- my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
-- my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
-- my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
-- my $n_val = asn1_extract($attr->[1], -1);
--
-- my $raw_oid = asn1_retrieve($n_oid->[1]);
-- next if (!exists($OIDs{$raw_oid}));
-- my $n_type = $OIDs{$raw_oid};
--
-- my $raw_value = asn1_retrieve($n_val->[1]);
--
-- if ($n_type eq "organizationName") {
-- $org = $raw_value;
-- } elsif ($n_type eq "commonName") {
-- $cn = $raw_value;
-- } elsif ($n_type eq "emailAddress") {
-- $email = $raw_value;
-- }
--}
--
--my $id_name = $email;
--
--if ($org && $cn) {
-- # Don't use the organizationName if the commonName repeats it
-- if (length($org) <= length($cn) &&
-- substr($cn, 0, length($org)) eq $org) {
-- $id_name = $cn;
-- goto got_id_name;
-- }
--
-- # Or a signifcant chunk of it
-- if (length($org) >= 7 &&
-- length($cn) >= 7 &&
-- substr($cn, 0, 7) eq substr($org, 0, 7)) {
-- $id_name = $cn;
-- goto got_id_name;
-- }
--
-- $id_name = $org . ": " . $cn;
--} elsif ($org) {
-- $id_name = $org;
--} elsif ($cn) {
-- $id_name = $cn;
--}
--
--got_id_name:
--
--###############################################################################
--#
--# Output the signer's name and the key identifier that we're going to include
--# in module signatures.
--#
--###############################################################################
--die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
-- if (!$subject_key_id);
--
--my $id_key_id = asn1_retrieve($subject_key_id->[1]);
--
--if ($ARGV[1] eq "signer-name") {
-- print $id_name;
--} elsif ($ARGV[1] eq "keyid") {
-- print $id_key_id;
--} else {
-- die "Unknown arg";
--}
---
-1.7.12.1
-
-
-From 02c76d9df8ff5387b9131799750895475f87c351 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Fri, 19 Oct 2012 23:56:45 +0100
-Subject: [PATCH 36/37] MODSIGN: Cleanup .gitignore
-
-The module build process no longer creates intermediate files for module
-signing, so remove them from .gitignore.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- .gitignore | 6 ------
- 1 file changed, 6 deletions(-)
-
-diff --git a/.gitignore b/.gitignore
-index 0f2f40f..92bd0e4 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -14,10 +14,6 @@
- *.o.*
- *.a
- *.s
--*.ko.unsigned
--*.ko.stripped
--*.ko.stripped.dig
--*.ko.stripped.sig
- *.ko
- *.so
- *.so.dbg
-@@ -95,6 +91,4 @@ GTAGS
- extra_certificates
- signing_key.priv
- signing_key.x509
--signing_key.x509.keyid
--signing_key.x509.signer
- x509.genkey
---
-1.7.12.1
-
-
-From fd08dfdc1a0022b48b7a5d4599cb4d46bf099882 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Sat, 20 Oct 2012 01:19:29 +0100
-Subject: [PATCH 37/37] MODSIGN: Move the magic string to the end of a module
- and eliminate the search
-
-Emit the magic string that indicates a module has a signature after the
-signature data instead of before it. This allows module_sig_check() to
-be made simpler and faster by the elimination of the search for the
-magic string. Instead we just need to do a single memcmp().
-
-This works because at the end of the signature data there is the
-fixed-length signature information block. This block then falls
-immediately prior to the magic number.
-
-From the contents of the information block, it is trivial to calculate
-the size of the signature data and thus the size of the actual module
-data.
-
-Signed-off-by: David Howells <dhowells@redhat.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- kernel/module-internal.h | 3 +--
- kernel/module.c | 26 +++++++++-----------------
- kernel/module_signing.c | 24 +++++++++++++++---------
- scripts/sign-file | 6 +++---
- 4 files changed, 28 insertions(+), 31 deletions(-)
-
-diff --git a/kernel/module-internal.h b/kernel/module-internal.h
-index 6114a13..24f9247 100644
---- a/kernel/module-internal.h
-+++ b/kernel/module-internal.h
-@@ -11,5 +11,4 @@
-
- extern struct key *modsign_keyring;
-
--extern int mod_verify_sig(const void *mod, unsigned long modlen,
-- const void *sig, unsigned long siglen);
-+extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
-diff --git a/kernel/module.c b/kernel/module.c
-index 3e8b1a7..0cfcccc 100644
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -2441,25 +2441,17 @@ static inline void kmemleak_load_module(const struct module *mod,
-
- #ifdef CONFIG_MODULE_SIG
- static int module_sig_check(struct load_info *info,
-- const void *mod, unsigned long *len)
-+ const void *mod, unsigned long *_len)
- {
- int err = -ENOKEY;
-- const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-- const void *p = mod, *end = mod + *len;
--
-- /* Poor man's memmem. */
-- while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) {
-- if (p + markerlen > end)
-- break;
--
-- if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) {
-- const void *sig = p + markerlen;
-- /* Truncate module up to signature. */
-- *len = p - mod;
-- err = mod_verify_sig(mod, *len, sig, end - sig);
-- break;
-- }
-- p++;
-+ unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-+ unsigned long len = *_len;
-+
-+ if (len > markerlen &&
-+ memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
-+ /* We truncate the module to discard the signature */
-+ *_len -= markerlen;
-+ err = mod_verify_sig(mod, _len);
- }
-
- if (!err) {
-diff --git a/kernel/module_signing.c b/kernel/module_signing.c
-index 6b09f69..d492a23 100644
---- a/kernel/module_signing.c
-+++ b/kernel/module_signing.c
-@@ -183,27 +183,33 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
- /*
- * Verify the signature on a module.
- */
--int mod_verify_sig(const void *mod, unsigned long modlen,
-- const void *sig, unsigned long siglen)
-+int mod_verify_sig(const void *mod, unsigned long *_modlen)
- {
- struct public_key_signature *pks;
- struct module_signature ms;
- struct key *key;
-- size_t sig_len;
-+ const void *sig;
-+ size_t modlen = *_modlen, sig_len;
- int ret;
-
-- pr_devel("==>%s(,%lu,,%lu,)\n", __func__, modlen, siglen);
-+ pr_devel("==>%s(,%lu)\n", __func__, modlen);
-
-- if (siglen <= sizeof(ms))
-+ if (modlen <= sizeof(ms))
- return -EBADMSG;
-
-- memcpy(&ms, sig + (siglen - sizeof(ms)), sizeof(ms));
-- siglen -= sizeof(ms);
-+ memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
-+ modlen -= sizeof(ms);
-
- sig_len = be32_to_cpu(ms.sig_len);
-- if (sig_len >= siglen ||
-- siglen - sig_len != (size_t)ms.signer_len + ms.key_id_len)
-+ if (sig_len >= modlen)
- return -EBADMSG;
-+ modlen -= sig_len;
-+ if ((size_t)ms.signer_len + ms.key_id_len >= modlen)
-+ return -EBADMSG;
-+ modlen -= (size_t)ms.signer_len + ms.key_id_len;
-+
-+ *_modlen = modlen;
-+ sig = mod + modlen;
-
- /* For the moment, only support RSA and X.509 identifiers */
- if (ms.algo != PKEY_ALGO_RSA ||
-diff --git a/scripts/sign-file b/scripts/sign-file
-index d37d130..87ca59d 100755
---- a/scripts/sign-file
-+++ b/scripts/sign-file
-@@ -403,11 +403,11 @@ my $info = pack("CCCCCxxxN",
-
- if ($verbose) {
- print "Size of unsigned module: ", length($unsigned_module), "\n";
-- print "Size of magic number : ", length($magic_number), "\n";
- print "Size of signer's name : ", length($signers_name), "\n";
- print "Size of key identifier : ", length($key_identifier), "\n";
- print "Size of signature : ", length($signature), "\n";
- print "Size of informaton : ", length($info), "\n";
-+ print "Size of magic number : ", length($magic_number), "\n";
- print "Signer's name : '", $signers_name, "'\n";
- print "Digest : $dgst\n";
- }
-@@ -416,11 +416,11 @@ open(FD, ">$dest") || die $dest;
- binmode FD;
- print FD
- $unsigned_module,
-- $magic_number,
- $signers_name,
- $key_identifier,
- $signature,
-- $info
-+ $info,
-+ $magic_number
- ;
- close FD || die $dest;
-
---
-1.7.12.1
-
-From f6a79af8f3701b5a0df431a76adee212616154dc Mon Sep 17 00:00:00 2001
-From: Rusty Russell <rusty@rustcorp.com.au>
-Date: Tue, 6 Nov 2012 11:46:59 +1030
-Subject: [PATCH] modules: don't break modules_install on external modules
- with no key.
-
-The script still spits out an error ("Can't read private key") but we
-don't break modules_install.
-
-Reported-by: Bruno Wolff III <bruno@wolff.to>
-Original-patch-by: Josh Boyer <jwboyer@redhat.com>
-Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
----
- scripts/Makefile.modinst | 3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
-index dda4b2b..ecbb447 100644
---- a/scripts/Makefile.modinst
-+++ b/scripts/Makefile.modinst
-@@ -16,8 +16,9 @@ PHONY += $(modules)
- __modinst: $(modules)
- @:
-
-+# Don't stop modules_install if we can't sign external modules.
- quiet_cmd_modules_install = INSTALL $@
-- cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@)
-+ cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD))
-
- # Modules built outside the kernel source tree go into extra by default
- INSTALL_MOD_DIR ?= extra
---
-1.7.6.5
-
diff --git a/freed-ora/current/f18/patch-3.6-gnu-3.6.11-gnu.xz.sign b/freed-ora/current/f18/patch-3.6-gnu-3.6.11-gnu.xz.sign
deleted file mode 100644
index b6f9b307c..000000000
--- a/freed-ora/current/f18/patch-3.6-gnu-3.6.11-gnu.xz.sign
+++ /dev/null
@@ -1,7 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.18 (GNU/Linux)
-
-iEYEABECAAYFAlDPnLwACgkQvLfPh359R6cYogCfXcKutcYI0E1kffdoSPnlCJU3
-3ZQAnRuh1P/7RkYtUpaplVdCUETQ0u7g
-=cIkL
------END PGP SIGNATURE-----
diff --git a/freed-ora/current/f18/secure-boot-20121212.patch b/freed-ora/current/f18/secure-boot-20121212.patch
index d435eb217..387302b90 100644
--- a/freed-ora/current/f18/secure-boot-20121212.patch
+++ b/freed-ora/current/f18/secure-boot-20121212.patch
@@ -1,4 +1,4 @@
-From 925befaba2477067aa12fa1fdc9fcc135c80b4fd Mon Sep 17 00:00:00 2001
+From d510ea864f470d96aafb75d0de7f09450407095e Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:40:56 -0400
Subject: [PATCH 01/20] Secure boot: Add new capability
@@ -11,14 +11,14 @@ capability set if required.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
- include/linux/capability.h | 6 +++++-
+ include/uapi/linux/capability.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
-diff --git a/include/linux/capability.h b/include/linux/capability.h
-index d10b7ed..4345bc8 100644
---- a/include/linux/capability.h
-+++ b/include/linux/capability.h
-@@ -364,7 +364,11 @@ struct cpu_vfs_cap_data {
+diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
+index ba478fa..7109e65 100644
+--- a/include/uapi/linux/capability.h
++++ b/include/uapi/linux/capability.h
+@@ -343,7 +343,11 @@ struct vfs_cap_data {
#define CAP_BLOCK_SUSPEND 36
@@ -35,7 +35,7 @@ index d10b7ed..4345bc8 100644
1.8.0.1
-From 1c5873679d750bda038d22210d9fd40c8673211f Mon Sep 17 00:00:00 2001
+From a07ae01ac4b304ac7f0e2b5d4193519f1a9eee8d Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:40:57 -0400
Subject: [PATCH 02/20] PCI: Lock down BAR access in secure boot environments
@@ -87,7 +87,7 @@ index f39378d..1db1e74 100644
}
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
-index af028c7..53372eb 100644
+index 9b8505c..35580bc 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -139,6 +139,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
@@ -136,7 +136,7 @@ index e1c1ec5..97e785f 100644
1.8.0.1
-From f067c7702f46b85d06da6c34dd907b44e594c2cf Mon Sep 17 00:00:00 2001
+From 1b5a1b53577992b32a3f51b18aa07cb9b300a3b1 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:40:58 -0400
Subject: [PATCH 03/20] x86: Lock down IO port access in secure boot
@@ -176,7 +176,7 @@ index 8c96897..a2578c4 100644
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
-index e5eedfa..1e0a660 100644
+index 0537903..47501fc 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -597,6 +597,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
@@ -193,7 +193,7 @@ index e5eedfa..1e0a660 100644
1.8.0.1
-From 95b440833e9002bc7e1950f403f2fb2953b69317 Mon Sep 17 00:00:00 2001
+From 09c266136915eb1f4a9b36423b7ba65e3d024de4 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:40:59 -0400
Subject: [PATCH 04/20] ACPI: Limit access to custom_method
@@ -225,7 +225,7 @@ index 5d42c24..247d58b 100644
1.8.0.1
-From fd40b868d55992f71acffa74b559923ffde81638 Mon Sep 17 00:00:00 2001
+From f3e9cb16e5ab3e680ec3ef464682c52371bbbbe3 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:41:00 -0400
Subject: [PATCH 05/20] asus-wmi: Restrict debugfs interface
@@ -278,7 +278,7 @@ index c0e9ff4..3c10167 100644
1.8.0.1
-From 470e4dbf6215d40a340b3ad7fd6d4533ffbf6a6d Mon Sep 17 00:00:00 2001
+From 23372d2a40135aca7a6d73511bd88790b598b489 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:41:01 -0400
Subject: [PATCH 06/20] Restrict /dev/mem and /dev/kmem in secure boot setups
@@ -292,7 +292,7 @@ Signed-off-by: Matthew Garrett <mjg@redhat.com>
1 file changed, 6 insertions(+)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
-index 1e0a660..33eb947 100644
+index 47501fc..8817cdc 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -158,6 +158,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
@@ -319,7 +319,7 @@ index 1e0a660..33eb947 100644
1.8.0.1
-From fdb24af2d20faea8bae60058f0cda8db8be9394d Mon Sep 17 00:00:00 2001
+From a0c80b01e80a1f6484a2a2811b4a212322494614 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Thu, 20 Sep 2012 10:41:02 -0400
Subject: [PATCH 07/20] Secure boot: Add a dummy kernel parameter that will
@@ -336,10 +336,10 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
2 files changed, 24 insertions(+)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 9b2b8d3..93978d5 100644
+index 9776f06..0d6c28d 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
-@@ -2562,6 +2562,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+@@ -2599,6 +2599,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Note: increases power consumption, thus should only be
enabled if running jitter sensitive (HPC/RT) workloads.
@@ -354,7 +354,7 @@ index 9b2b8d3..93978d5 100644
If this boot parameter is not specified, only the first
security module asking for security registration will be
diff --git a/kernel/cred.c b/kernel/cred.c
-index de728ac..7e6e83f 100644
+index 48cea3d..3f5be65 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -623,6 +623,23 @@ void __init cred_init(void)
@@ -385,7 +385,7 @@ index de728ac..7e6e83f 100644
1.8.0.1
-From 033a0db83fe140b040a5f5a5754ba326b0d4f587 Mon Sep 17 00:00:00 2001
+From 640f088c49da87a344417f58d3faa72d63a4f6ed Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Thu, 20 Sep 2012 10:41:03 -0400
Subject: [PATCH 08/20] efi: Enable secure boot lockdown automatically when
@@ -418,10 +418,10 @@ index cf5437d..7f9ed48 100644
2D0/A00 ALL e820_map E820 memory map table
(array of struct e820entry)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
-index 90201aa..bdf0eb7 100644
+index e87b0ca..260cace 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
-@@ -726,6 +726,36 @@ fail:
+@@ -732,6 +732,36 @@ fail:
return status;
}
@@ -458,7 +458,7 @@ index 90201aa..bdf0eb7 100644
/*
* Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create
-@@ -1020,6 +1050,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
+@@ -1026,6 +1056,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
goto fail;
@@ -482,10 +482,10 @@ index 2ad874c..c7338e0 100644
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index 5cee802..b4f4666 100644
+index ca45696..800673d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
-@@ -961,6 +961,9 @@ void __init setup_arch(char **cmdline_p)
+@@ -962,6 +962,9 @@ void __init setup_arch(char **cmdline_p)
io_delay_init();
@@ -512,7 +512,7 @@ index ebbed2c..a24faf1 100644
1.8.0.1
-From 7a24fb283b72797e219a3283c5cf880ebb80443f Mon Sep 17 00:00:00 2001
+From 994d895b5b684fc53c3b43dda9aee460c1f526f2 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Thu, 20 Sep 2012 10:41:04 -0400
Subject: [PATCH 09/20] acpi: Ignore acpi_rsdp kernel parameter in a secure
@@ -544,7 +544,7 @@ index 9eaf708..f94341b 100644
1.8.0.1
-From a21ccbd8461fd9780c348faa78bbd3d13db04e3d Mon Sep 17 00:00:00 2001
+From c80aaf3eee3cb6b0d1a051e418ee99cd238c868c Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Thu, 20 Sep 2012 10:41:05 -0400
Subject: [PATCH 10/20] SELinux: define mapping for new Secure Boot capability
@@ -577,7 +577,7 @@ index df2de54..70e2834 100644
1.8.0.1
-From 01af02988477c4bde39436adec1edfd1499709d9 Mon Sep 17 00:00:00 2001
+From 26352bcb92468233dd960b5d02ba1db344df72b9 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Tue, 4 Sep 2012 11:55:13 -0400
Subject: [PATCH 11/20] kexec: Disable in a secure boot environment
@@ -593,10 +593,10 @@ Signed-off-by: Matthew Garrett <mjg@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/kexec.c b/kernel/kexec.c
-index 0668d58..8b976a5 100644
+index 5e4bd78..dd464e0 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
-@@ -944,7 +944,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
+@@ -943,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
int result;
/* We only trust the superuser with rebooting the system. */
@@ -609,7 +609,7 @@ index 0668d58..8b976a5 100644
1.8.0.1
-From 883409d0fadeefe2c44d7034d2acc0e366c339f3 Mon Sep 17 00:00:00 2001
+From c03c68adceaec9656c55c47190fb4243bf903b40 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Mon, 25 Jun 2012 21:29:46 -0400
Subject: [PATCH 12/20] Documentation: kernel-parameters.txt remove
@@ -630,7 +630,7 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
1 file changed, 6 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 93978d5..e3e5f8c 100644
+index 0d6c28d..d9af501 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -446,12 +446,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
@@ -650,7 +650,7 @@ index 93978d5..e3e5f8c 100644
1.8.0.1
-From b2ee7008ee39d04b3439f81e42586ee8e16af2e9 Mon Sep 17 00:00:00 2001
+From 3f1bda64d2c7b369e2833bd32cd1f3ba6c90348f Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 5 Oct 2012 10:12:48 -0400
Subject: [PATCH 13/20] modsign: Always enforce module signing in a Secure Boot
@@ -669,7 +669,7 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/kernel/cred.c b/kernel/cred.c
-index 7e6e83f..6e828e2 100644
+index 3f5be65..a381e27 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -623,11 +623,19 @@ void __init cred_init(void)
@@ -693,7 +693,7 @@ index 7e6e83f..6e828e2 100644
/* Dummy Secure Boot enable option to fake out UEFI SB=1 */
diff --git a/kernel/module.c b/kernel/module.c
-index e0785b3..b964a03 100644
+index 6e48c3a..6d5d2aa 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -106,9 +106,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
@@ -712,7 +712,7 @@ index e0785b3..b964a03 100644
1.8.0.1
-From 4fe6ecce3e9168f538fc8970fe8a964438beabbb Mon Sep 17 00:00:00 2001
+From e6e3ec77b2fa037b32829e7f5ee468ad8a62dd05 Mon Sep 17 00:00:00 2001
From: Dave Howells <dhowells@redhat.com>
Date: Tue, 23 Oct 2012 09:30:54 -0400
Subject: [PATCH 14/20] Add EFI signature data types, such as are used for
@@ -724,7 +724,7 @@ Signed-off-by: David Howells <dhowells@redhat.com>
1 file changed, 20 insertions(+)
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index bff4b5e..52ce2c4 100644
+index 337aefb..a01f8a7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -317,6 +317,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
@@ -765,7 +765,7 @@ index bff4b5e..52ce2c4 100644
1.8.0.1
-From 768ab9ef88b2caa9588e577fe547792dfe513fca Mon Sep 17 00:00:00 2001
+From c2542256f632a22232cf02d5fd64568a5afa4516 Mon Sep 17 00:00:00 2001
From: Dave Howells <dhowells@redhat.com>
Date: Tue, 23 Oct 2012 09:36:28 -0400
Subject: [PATCH 15/20] Add an EFI signature blob parser and key loader. X.509
@@ -922,10 +922,10 @@ index 0000000..59b859a
+ return 0;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 52ce2c4..54b5936 100644
+index a01f8a7..44a7faa 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
-@@ -538,6 +538,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime);
+@@ -541,6 +541,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime);
extern void efi_reserve_boot_services(void);
extern struct efi_memory_map memmap;
@@ -940,7 +940,7 @@ index 52ce2c4..54b5936 100644
1.8.0.1
-From 967a1b02af199f07fd7603bda2f0aeec50b412b9 Mon Sep 17 00:00:00 2001
+From a418e6fdd2aa946a30cf1bee5c9540d03d626981 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 26 Oct 2012 12:29:49 -0400
Subject: [PATCH 16/20] EFI: Add in-kernel variable to determine if Secure Boot
@@ -959,10 +959,10 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index b4f4666..db74940 100644
+index 800673d..cf8823b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
-@@ -961,8 +961,12 @@ void __init setup_arch(char **cmdline_p)
+@@ -962,8 +962,12 @@ void __init setup_arch(char **cmdline_p)
io_delay_init();
@@ -977,10 +977,10 @@ index b4f4666..db74940 100644
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
-index 72d8899..882d794 100644
+index ad44391..d22bfeb 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
-@@ -53,6 +53,8 @@
+@@ -54,6 +54,8 @@
int efi_enabled;
EXPORT_SYMBOL(efi_enabled);
@@ -990,10 +990,10 @@ index 72d8899..882d794 100644
.mps = EFI_INVALID_TABLE_ADDR,
.acpi = EFI_INVALID_TABLE_ADDR,
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 54b5936..411997f 100644
+index 44a7faa..b5403ae 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
-@@ -575,11 +575,14 @@ extern int __init efi_setup_pcdp_console(char *);
+@@ -578,11 +578,14 @@ extern int __init efi_setup_pcdp_console(char *);
# ifdef CONFIG_X86
extern int efi_enabled;
extern bool efi_64bit;
@@ -1012,7 +1012,7 @@ index 54b5936..411997f 100644
1.8.0.1
-From 6e946d64dc843d9caa587780801de035b38fd4b3 Mon Sep 17 00:00:00 2001
+From f6d05f0974f6a7667ebbbf91624678bcf32169ae Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 26 Oct 2012 12:36:24 -0400
Subject: [PATCH 17/20] MODSIGN: Add module certificate blacklist keyring
@@ -1031,10 +1031,10 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig
-index abc6e63..78f3e280 100644
+index 6fdd6e3..7a9bf00 100644
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -1613,6 +1613,14 @@ config MODULE_SIG_FORCE
+@@ -1602,6 +1602,14 @@ config MODULE_SIG_FORCE
Reject unsigned modules or signed modules for which we don't have a
key. Without this, such modules will simply taint the kernel.
@@ -1050,7 +1050,7 @@ index abc6e63..78f3e280 100644
prompt "Which hash algorithm should modules be signed with?"
depends on MODULE_SIG
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
-index 4646eb2..6d70783 100644
+index 767e559..3bfb7ed 100644
--- a/kernel/modsign_pubkey.c
+++ b/kernel/modsign_pubkey.c
@@ -17,6 +17,9 @@
@@ -1098,7 +1098,7 @@ index 24f9247..51a8380 100644
extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
-index d492a23..39131d3 100644
+index f2970bd..8ab83a6 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -132,7 +132,7 @@ static int mod_extract_mpi_array(struct public_key_signature *pks,
@@ -1133,7 +1133,7 @@ index d492a23..39131d3 100644
1.8.0.1
-From 02905ddf41b18af3c3dd5d99771eba4e453d24ca Mon Sep 17 00:00:00 2001
+From ff0ed221fe8d5a46a9bc36323ca8fb6f75c22a83 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 26 Oct 2012 12:42:16 -0400
Subject: [PATCH 18/20] MODSIGN: Import certificates from UEFI Secure Boot
@@ -1161,7 +1161,7 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com>
create mode 100644 kernel/modsign_uefi.c
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 411997f..31f84ff 100644
+index b5403ae..bba53e3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -323,6 +323,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
@@ -1178,10 +1178,10 @@ index 411997f..31f84ff 100644
efi_guid_t guid;
u64 table;
diff --git a/init/Kconfig b/init/Kconfig
-index 78f3e280..754ee66 100644
+index 7a9bf00..51aa170 100644
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -1621,6 +1621,15 @@ config MODULE_SIG_BLACKLIST
+@@ -1610,6 +1610,15 @@ config MODULE_SIG_BLACKLIST
should not pass module signature verification. If a module is
signed with something in this keyring, the load will be rejected.
@@ -1198,10 +1198,10 @@ index 78f3e280..754ee66 100644
prompt "Which hash algorithm should modules be signed with?"
depends on MODULE_SIG
diff --git a/kernel/Makefile b/kernel/Makefile
-index d3611c8..927a264 100644
+index 86e3285..12e17ab 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
-@@ -56,6 +56,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
+@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o
@@ -1209,7 +1209,7 @@ index d3611c8..927a264 100644
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_KEXEC) += kexec.o
-@@ -114,6 +115,8 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+@@ -113,6 +114,8 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
$(obj)/configs.o: $(obj)/config_data.h
@@ -1318,7 +1318,7 @@ index 0000000..76a5a34
1.8.0.1
-From b1bc4417dcec5c603baae2de2523bdf3a0c96b11 Mon Sep 17 00:00:00 2001
+From 7d5629a2000d9dc92da91d2f1258af748e89cfd7 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 26 Oct 2012 14:02:09 -0400
Subject: [PATCH 19/20] hibernate: Disable in a Secure Boot environment
@@ -1414,7 +1414,7 @@ index 4ed81e7..b11a0f4 100644
1.8.0.1
-From 96c9c61996828908833b680149525b4b7acff664 Mon Sep 17 00:00:00 2001
+From 81adc779dba0f45f10b5ff307bd55832305f1112 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Wed, 12 Dec 2012 11:48:49 -0500
Subject: [PATCH 20/20] Don't soft lockup on bad EFI signature lists
diff --git a/freed-ora/current/f18/smp_irq_move_cleanup_interrupt.patch b/freed-ora/current/f18/smp_irq_move_cleanup_interrupt.patch
deleted file mode 100644
index c9b385a94..000000000
--- a/freed-ora/current/f18/smp_irq_move_cleanup_interrupt.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-commit 94777fc51b3ad85ff9f705ddf7cdd0eb3bbad5a6
-Author: Dimitri Sivanich <sivanich@sgi.com>
-Date: Tue Oct 16 07:50:21 2012 -0500
-
- x86/irq/ioapic: Check for valid irq_cfg pointer in smp_irq_move_cleanup_interrupt
-
- Posting this patch to fix an issue concerning sparse irq's that
- I raised a while back. There was discussion about adding
- refcounting to sparse irqs (to fix other potential race
- conditions), but that does not appear to have been addressed
- yet. This covers the only issue of this type that I've
- encountered in this area.
-
- A NULL pointer dereference can occur in
- smp_irq_move_cleanup_interrupt() if we haven't yet setup the
- irq_cfg pointer in the irq_desc.irq_data.chip_data.
-
- In create_irq_nr() there is a window where we have set
- vector_irq in __assign_irq_vector(), but not yet called
- irq_set_chip_data() to set the irq_cfg pointer.
-
- Should an IRQ_MOVE_CLEANUP_VECTOR hit the cpu in question during
- this time, smp_irq_move_cleanup_interrupt() will attempt to
- process the aforementioned irq, but panic when accessing
- irq_cfg.
-
- Only continue processing the irq if irq_cfg is non-NULL.
-
- Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
- Cc: Suresh Siddha <suresh.b.siddha@intel.com>
- Cc: Joerg Roedel <joerg.roedel@amd.com>
- Cc: Yinghai Lu <yinghai@kernel.org>
- Cc: Alexander Gordeev <agordeev@redhat.com>
- Link: http://lkml.kernel.org/r/20121016125021.GA22935@sgi.com
- Signed-off-by: Ingo Molnar <mingo@kernel.org>
-
-diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
-index c265593..1817fa9 100644
---- a/arch/x86/kernel/apic/io_apic.c
-+++ b/arch/x86/kernel/apic/io_apic.c
-@@ -2257,6 +2257,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
- continue;
-
- cfg = irq_cfg(irq);
-+ if (!cfg)
-+ continue;
-+
- raw_spin_lock(&desc->lock);
-
- /*
diff --git a/freed-ora/current/f18/sources b/freed-ora/current/f18/sources
index 4362eb911..e54b5c017 100644
--- a/freed-ora/current/f18/sources
+++ b/freed-ora/current/f18/sources
@@ -1,2 +1,2 @@
-a2312edd0265b5b07bd4b50afae2b380 linux-libre-3.6-gnu.tar.xz
-ced16b674906cf8c3733c012f804f5c7 patch-3.6-gnu-3.6.11-gnu.xz
+06bf9601d859531e7378eb43d4ca7dd3 linux-libre-3.7-gnu.tar.xz
+48f5f530b048e387e978e3e49de7742a patch-3.7.1.xz
diff --git a/freed-ora/current/f18/team-net-next-20120808.patch b/freed-ora/current/f18/team-net-next-20120808.patch
deleted file mode 100644
index c738a4724..000000000
--- a/freed-ora/current/f18/team-net-next-20120808.patch
+++ /dev/null
@@ -1,499 +0,0 @@
-Update team driver to latest net-next.
-
-Split patches available here:
-http://people.redhat.com/jpirko/f18_team_update_2/
-
-Jiri Pirko (4):
- netlink: add signed types
- team: add signed 32-bit team option type
- team: add per port priority option
- team: add support for queue override by setting queue_id for port
-
- drivers/net/team/team.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++-
- include/linux/if_team.h | 7 ++
- include/net/netlink.h | 98 +++++++++++++++++++++++
- 3 files changed, 303 insertions(+), 2 deletions(-)
-
-Signed-off-by: Jiri Pirko <jpirko@redhat.com>
-
-diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
-index 87707ab..ba10c46 100644
---- a/drivers/net/team/team.c
-+++ b/drivers/net/team/team.c
-@@ -658,6 +658,122 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
- }
-
-
-+/*************************************
-+ * Multiqueue Tx port select override
-+ *************************************/
-+
-+static int team_queue_override_init(struct team *team)
-+{
-+ struct list_head *listarr;
-+ unsigned int queue_cnt = team->dev->num_tx_queues - 1;
-+ unsigned int i;
-+
-+ if (!queue_cnt)
-+ return 0;
-+ listarr = kmalloc(sizeof(struct list_head) * queue_cnt, GFP_KERNEL);
-+ if (!listarr)
-+ return -ENOMEM;
-+ team->qom_lists = listarr;
-+ for (i = 0; i < queue_cnt; i++)
-+ INIT_LIST_HEAD(listarr++);
-+ return 0;
-+}
-+
-+static void team_queue_override_fini(struct team *team)
-+{
-+ kfree(team->qom_lists);
-+}
-+
-+static struct list_head *__team_get_qom_list(struct team *team, u16 queue_id)
-+{
-+ return &team->qom_lists[queue_id - 1];
-+}
-+
-+/*
-+ * note: already called with rcu_read_lock
-+ */
-+static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
-+{
-+ struct list_head *qom_list;
-+ struct team_port *port;
-+
-+ if (!team->queue_override_enabled || !skb->queue_mapping)
-+ return false;
-+ qom_list = __team_get_qom_list(team, skb->queue_mapping);
-+ list_for_each_entry_rcu(port, qom_list, qom_list) {
-+ if (!team_dev_queue_xmit(team, port, skb))
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static void __team_queue_override_port_del(struct team *team,
-+ struct team_port *port)
-+{
-+ list_del_rcu(&port->qom_list);
-+ synchronize_rcu();
-+ INIT_LIST_HEAD(&port->qom_list);
-+}
-+
-+static bool team_queue_override_port_has_gt_prio_than(struct team_port *port,
-+ struct team_port *cur)
-+{
-+ if (port->priority < cur->priority)
-+ return true;
-+ if (port->priority > cur->priority)
-+ return false;
-+ if (port->index < cur->index)
-+ return true;
-+ return false;
-+}
-+
-+static void __team_queue_override_port_add(struct team *team,
-+ struct team_port *port)
-+{
-+ struct team_port *cur;
-+ struct list_head *qom_list;
-+ struct list_head *node;
-+
-+ if (!port->queue_id || !team_port_enabled(port))
-+ return;
-+
-+ qom_list = __team_get_qom_list(team, port->queue_id);
-+ node = qom_list;
-+ list_for_each_entry(cur, qom_list, qom_list) {
-+ if (team_queue_override_port_has_gt_prio_than(port, cur))
-+ break;
-+ node = &cur->qom_list;
-+ }
-+ list_add_tail_rcu(&port->qom_list, node);
-+}
-+
-+static void __team_queue_override_enabled_check(struct team *team)
-+{
-+ struct team_port *port;
-+ bool enabled = false;
-+
-+ list_for_each_entry(port, &team->port_list, list) {
-+ if (!list_empty(&port->qom_list)) {
-+ enabled = true;
-+ break;
-+ }
-+ }
-+ if (enabled == team->queue_override_enabled)
-+ return;
-+ netdev_dbg(team->dev, "%s queue override\n",
-+ enabled ? "Enabling" : "Disabling");
-+ team->queue_override_enabled = enabled;
-+}
-+
-+static void team_queue_override_port_refresh(struct team *team,
-+ struct team_port *port)
-+{
-+ __team_queue_override_port_del(team, port);
-+ __team_queue_override_port_add(team, port);
-+ __team_queue_override_enabled_check(team);
-+}
-+
-+
- /****************
- * Port handling
- ****************/
-@@ -688,6 +804,7 @@ static void team_port_enable(struct team *team,
- hlist_add_head_rcu(&port->hlist,
- team_port_index_hash(team, port->index));
- team_adjust_ops(team);
-+ team_queue_override_port_refresh(team, port);
- if (team->ops.port_enabled)
- team->ops.port_enabled(team, port);
- }
-@@ -716,6 +833,7 @@ static void team_port_disable(struct team *team,
- hlist_del_rcu(&port->hlist);
- __reconstruct_port_hlist(team, port->index);
- port->index = -1;
-+ team_queue_override_port_refresh(team, port);
- __team_adjust_ops(team, team->en_port_count - 1);
- /*
- * Wait until readers see adjusted ops. This ensures that
-@@ -881,6 +999,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
-
- port->dev = port_dev;
- port->team = team;
-+ INIT_LIST_HEAD(&port->qom_list);
-
- port->orig.mtu = port_dev->mtu;
- err = dev_set_mtu(port_dev, dev->mtu);
-@@ -1092,6 +1211,49 @@ static int team_user_linkup_en_option_set(struct team *team,
- return 0;
- }
-
-+static int team_priority_option_get(struct team *team,
-+ struct team_gsetter_ctx *ctx)
-+{
-+ struct team_port *port = ctx->info->port;
-+
-+ ctx->data.s32_val = port->priority;
-+ return 0;
-+}
-+
-+static int team_priority_option_set(struct team *team,
-+ struct team_gsetter_ctx *ctx)
-+{
-+ struct team_port *port = ctx->info->port;
-+
-+ port->priority = ctx->data.s32_val;
-+ team_queue_override_port_refresh(team, port);
-+ return 0;
-+}
-+
-+static int team_queue_id_option_get(struct team *team,
-+ struct team_gsetter_ctx *ctx)
-+{
-+ struct team_port *port = ctx->info->port;
-+
-+ ctx->data.u32_val = port->queue_id;
-+ return 0;
-+}
-+
-+static int team_queue_id_option_set(struct team *team,
-+ struct team_gsetter_ctx *ctx)
-+{
-+ struct team_port *port = ctx->info->port;
-+
-+ if (port->queue_id == ctx->data.u32_val)
-+ return 0;
-+ if (ctx->data.u32_val >= team->dev->real_num_tx_queues)
-+ return -EINVAL;
-+ port->queue_id = ctx->data.u32_val;
-+ team_queue_override_port_refresh(team, port);
-+ return 0;
-+}
-+
-+
- static const struct team_option team_options[] = {
- {
- .name = "mode",
-@@ -1120,6 +1282,20 @@ static const struct team_option team_options[] = {
- .getter = team_user_linkup_en_option_get,
- .setter = team_user_linkup_en_option_set,
- },
-+ {
-+ .name = "priority",
-+ .type = TEAM_OPTION_TYPE_S32,
-+ .per_port = true,
-+ .getter = team_priority_option_get,
-+ .setter = team_priority_option_set,
-+ },
-+ {
-+ .name = "queue_id",
-+ .type = TEAM_OPTION_TYPE_U32,
-+ .per_port = true,
-+ .getter = team_queue_id_option_get,
-+ .setter = team_queue_id_option_set,
-+ },
- };
-
- static struct lock_class_key team_netdev_xmit_lock_key;
-@@ -1155,6 +1331,9 @@ static int team_init(struct net_device *dev)
- for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
- INIT_HLIST_HEAD(&team->en_port_hlist[i]);
- INIT_LIST_HEAD(&team->port_list);
-+ err = team_queue_override_init(team);
-+ if (err)
-+ goto err_team_queue_override_init;
-
- team_adjust_ops(team);
-
-@@ -1170,6 +1349,8 @@ static int team_init(struct net_device *dev)
- return 0;
-
- err_options_register:
-+ team_queue_override_fini(team);
-+err_team_queue_override_init:
- free_percpu(team->pcpu_stats);
-
- return err;
-@@ -1187,6 +1368,7 @@ static void team_uninit(struct net_device *dev)
-
- __team_change_mode(team, NULL); /* cleanup */
- __team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
-+ team_queue_override_fini(team);
- mutex_unlock(&team->lock);
- }
-
-@@ -1216,10 +1398,12 @@ static int team_close(struct net_device *dev)
- static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct team *team = netdev_priv(dev);
-- bool tx_success = false;
-+ bool tx_success;
- unsigned int len = skb->len;
-
-- tx_success = team->ops.transmit(team, skb);
-+ tx_success = team_queue_override_transmit(team, skb);
-+ if (!tx_success)
-+ tx_success = team->ops.transmit(team, skb);
- if (tx_success) {
- struct team_pcpu_stats *pcpu_stats;
-
-@@ -1787,6 +1971,12 @@ static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team,
- nla_put_flag(skb, TEAM_ATTR_OPTION_DATA))
- goto nest_cancel;
- break;
-+ case TEAM_OPTION_TYPE_S32:
-+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_S32))
-+ goto nest_cancel;
-+ if (nla_put_s32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.s32_val))
-+ goto nest_cancel;
-+ break;
- default:
- BUG();
- }
-@@ -1975,6 +2165,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
- case NLA_FLAG:
- opt_type = TEAM_OPTION_TYPE_BOOL;
- break;
-+ case NLA_S32:
-+ opt_type = TEAM_OPTION_TYPE_S32;
-+ break;
- default:
- goto team_put;
- }
-@@ -2031,6 +2224,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
- case TEAM_OPTION_TYPE_BOOL:
- ctx.data.bool_val = attr_data ? true : false;
- break;
-+ case TEAM_OPTION_TYPE_S32:
-+ ctx.data.s32_val = nla_get_s32(attr_data);
-+ break;
- default:
- BUG();
- }
-diff --git a/include/linux/if_team.h b/include/linux/if_team.h
-index 6960fc1..33fcc20 100644
---- a/include/linux/if_team.h
-+++ b/include/linux/if_team.h
-@@ -67,6 +67,9 @@ struct team_port {
- struct netpoll *np;
- #endif
-
-+ s32 priority; /* lower number ~ higher priority */
-+ u16 queue_id;
-+ struct list_head qom_list; /* node in queue override mapping list */
- long mode_priv[0];
- };
-
-@@ -130,6 +133,7 @@ enum team_option_type {
- TEAM_OPTION_TYPE_STRING,
- TEAM_OPTION_TYPE_BINARY,
- TEAM_OPTION_TYPE_BOOL,
-+ TEAM_OPTION_TYPE_S32,
- };
-
- struct team_option_inst_info {
-@@ -146,6 +150,7 @@ struct team_gsetter_ctx {
- u32 len;
- } bin_val;
- bool bool_val;
-+ s32 s32_val;
- } data;
- struct team_option_inst_info *info;
- };
-@@ -197,6 +202,8 @@ struct team {
-
- const struct team_mode *mode;
- struct team_mode_ops ops;
-+ bool queue_override_enabled;
-+ struct list_head *qom_lists; /* array of queue override mapping lists */
- long mode_priv[TEAM_MODE_PRIV_LONGS];
- };
-
-diff --git a/include/net/netlink.h b/include/net/netlink.h
-index 785f37a..09175d5 100644
---- a/include/net/netlink.h
-+++ b/include/net/netlink.h
-@@ -98,6 +98,10 @@
- * nla_put_u16(skb, type, value) add u16 attribute to skb
- * nla_put_u32(skb, type, value) add u32 attribute to skb
- * nla_put_u64(skb, type, value) add u64 attribute to skb
-+ * nla_put_s8(skb, type, value) add s8 attribute to skb
-+ * nla_put_s16(skb, type, value) add s16 attribute to skb
-+ * nla_put_s32(skb, type, value) add s32 attribute to skb
-+ * nla_put_s64(skb, type, value) add s64 attribute to skb
- * nla_put_string(skb, type, str) add string attribute to skb
- * nla_put_flag(skb, type) add flag attribute to skb
- * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
-@@ -121,6 +125,10 @@
- * nla_get_u16(nla) get payload for a u16 attribute
- * nla_get_u32(nla) get payload for a u32 attribute
- * nla_get_u64(nla) get payload for a u64 attribute
-+ * nla_get_s8(nla) get payload for a s8 attribute
-+ * nla_get_s16(nla) get payload for a s16 attribute
-+ * nla_get_s32(nla) get payload for a s32 attribute
-+ * nla_get_s64(nla) get payload for a s64 attribute
- * nla_get_flag(nla) return 1 if flag is true
- * nla_get_msecs(nla) get payload for a msecs attribute
- *
-@@ -160,6 +168,10 @@ enum {
- NLA_NESTED_COMPAT,
- NLA_NUL_STRING,
- NLA_BINARY,
-+ NLA_S8,
-+ NLA_S16,
-+ NLA_S32,
-+ NLA_S64,
- __NLA_TYPE_MAX,
- };
-
-@@ -183,6 +195,8 @@ enum {
- * NLA_NESTED_COMPAT Minimum length of structure payload
- * NLA_U8, NLA_U16,
- * NLA_U32, NLA_U64,
-+ * NLA_S8, NLA_S16,
-+ * NLA_S32, NLA_S64,
- * NLA_MSECS Leaving the length field zero will verify the
- * given type fits, using it verifies minimum length
- * just like "All other"
-@@ -879,6 +893,50 @@ static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value)
- }
-
- /**
-+ * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
-+ * @skb: socket buffer to add attribute to
-+ * @attrtype: attribute type
-+ * @value: numeric value
-+ */
-+static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
-+{
-+ return nla_put(skb, attrtype, sizeof(s8), &value);
-+}
-+
-+/**
-+ * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
-+ * @skb: socket buffer to add attribute to
-+ * @attrtype: attribute type
-+ * @value: numeric value
-+ */
-+static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
-+{
-+ return nla_put(skb, attrtype, sizeof(s16), &value);
-+}
-+
-+/**
-+ * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
-+ * @skb: socket buffer to add attribute to
-+ * @attrtype: attribute type
-+ * @value: numeric value
-+ */
-+static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
-+{
-+ return nla_put(skb, attrtype, sizeof(s32), &value);
-+}
-+
-+/**
-+ * nla_put_s64 - Add a s64 netlink attribute to a socket buffer
-+ * @skb: socket buffer to add attribute to
-+ * @attrtype: attribute type
-+ * @value: numeric value
-+ */
-+static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value)
-+{
-+ return nla_put(skb, attrtype, sizeof(s64), &value);
-+}
-+
-+/**
- * nla_put_string - Add a string netlink attribute to a socket buffer
- * @skb: socket buffer to add attribute to
- * @attrtype: attribute type
-@@ -994,6 +1052,46 @@ static inline __be64 nla_get_be64(const struct nlattr *nla)
- }
-
- /**
-+ * nla_get_s32 - return payload of s32 attribute
-+ * @nla: s32 netlink attribute
-+ */
-+static inline s32 nla_get_s32(const struct nlattr *nla)
-+{
-+ return *(s32 *) nla_data(nla);
-+}
-+
-+/**
-+ * nla_get_s16 - return payload of s16 attribute
-+ * @nla: s16 netlink attribute
-+ */
-+static inline s16 nla_get_s16(const struct nlattr *nla)
-+{
-+ return *(s16 *) nla_data(nla);
-+}
-+
-+/**
-+ * nla_get_s8 - return payload of s8 attribute
-+ * @nla: s8 netlink attribute
-+ */
-+static inline s8 nla_get_s8(const struct nlattr *nla)
-+{
-+ return *(s8 *) nla_data(nla);
-+}
-+
-+/**
-+ * nla_get_s64 - return payload of s64 attribute
-+ * @nla: s64 netlink attribute
-+ */
-+static inline s64 nla_get_s64(const struct nlattr *nla)
-+{
-+ s64 tmp;
-+
-+ nla_memcpy(&tmp, nla, sizeof(tmp));
-+
-+ return tmp;
-+}
-+
-+/**
- * nla_get_flag - return payload of flag attribute
- * @nla: flag netlink attribute
- */
-
diff --git a/freed-ora/current/f18/team-net-next-20121205.patch b/freed-ora/current/f18/team-net-next-20121205.patch
deleted file mode 100644
index 51249f9c1..000000000
--- a/freed-ora/current/f18/team-net-next-20121205.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-
-Backport fixes from linus's tree.
-
-upstream commits backported:
-commit 403f43c937d24832b18524f65415c0bbba6b5064
- team: bcast: convert return value of team_dev_queue_xmit() to bool correctly
-commit 3ed7147189d2fbe8ac6da95db2fd9d6d52f53ce9
- team: fix hw_features setup
-
-Signed-off-by: Jiri Pirko <jpirko@redhat.com>
----
- drivers/net/team/team.c | 4 +++-
- drivers/net/team/team_mode_broadcast.c | 6 +++---
- 2 files changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
-index 5d8e1cb..f504773 100644
---- a/drivers/net/team/team.c
-+++ b/drivers/net/team/team.c
-@@ -1792,10 +1792,12 @@ static void team_setup(struct net_device *dev)
-
- dev->features |= NETIF_F_LLTX;
- dev->features |= NETIF_F_GRO;
-- dev->hw_features = NETIF_F_HW_VLAN_TX |
-+ dev->hw_features = TEAM_VLAN_FEATURES |
-+ NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
-
-+ dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
- dev->features |= dev->hw_features;
- }
-
-diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c
-index 9db0171..c5db428 100644
---- a/drivers/net/team/team_mode_broadcast.c
-+++ b/drivers/net/team/team_mode_broadcast.c
-@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
- if (last) {
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (skb2) {
-- ret = team_dev_queue_xmit(team, last,
-- skb2);
-+ ret = !team_dev_queue_xmit(team, last,
-+ skb2);
- if (!sum_ret)
- sum_ret = ret;
- }
-@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
- }
- }
- if (last) {
-- ret = team_dev_queue_xmit(team, last, skb);
-+ ret = !team_dev_queue_xmit(team, last, skb);
- if (!sum_ret)
- sum_ret = ret;
- }
---
-1.7.11.7
-
diff --git a/freed-ora/current/f18/team-net-next-update-20120927.patch b/freed-ora/current/f18/team-net-next-update-20120927.patch
deleted file mode 100644
index a61311619..000000000
--- a/freed-ora/current/f18/team-net-next-update-20120927.patch
+++ /dev/null
@@ -1,335 +0,0 @@
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/Kconfig
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/Kconfig
-@@ -21,7 +21,7 @@ config NET_TEAM_MODE_BROADCAST
- ---help---
- Basic mode where packets are transmitted always by all suitable ports.
-
-- All added ports are setup to have team's mac address.
-+ All added ports are setup to have team's device address.
-
- To compile this team mode as a module, choose M here: the module
- will be called team_mode_broadcast.
-@@ -33,7 +33,7 @@ config NET_TEAM_MODE_ROUNDROBIN
- Basic mode where port used for transmitting packets is selected in
- round-robin fashion using packet counter.
-
-- All added ports are setup to have team's mac address.
-+ All added ports are setup to have team's device address.
-
- To compile this team mode as a module, choose M here: the module
- will be called team_mode_roundrobin.
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team.c
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team.c
-@@ -54,29 +54,29 @@ static struct team_port *team_port_get_r
- }
-
- /*
-- * Since the ability to change mac address for open port device is tested in
-+ * Since the ability to change device address for open port device is tested in
- * team_port_add, this function can be called without control of return value
- */
--static int __set_port_mac(struct net_device *port_dev,
-- const unsigned char *dev_addr)
-+static int __set_port_dev_addr(struct net_device *port_dev,
-+ const unsigned char *dev_addr)
- {
- struct sockaddr addr;
-
-- memcpy(addr.sa_data, dev_addr, ETH_ALEN);
-- addr.sa_family = ARPHRD_ETHER;
-+ memcpy(addr.sa_data, dev_addr, port_dev->addr_len);
-+ addr.sa_family = port_dev->type;
- return dev_set_mac_address(port_dev, &addr);
- }
-
--static int team_port_set_orig_mac(struct team_port *port)
-+static int team_port_set_orig_dev_addr(struct team_port *port)
- {
-- return __set_port_mac(port->dev, port->orig.dev_addr);
-+ return __set_port_dev_addr(port->dev, port->orig.dev_addr);
- }
-
--int team_port_set_team_mac(struct team_port *port)
-+int team_port_set_team_dev_addr(struct team_port *port)
- {
-- return __set_port_mac(port->dev, port->team->dev->dev_addr);
-+ return __set_port_dev_addr(port->dev, port->team->dev->dev_addr);
- }
--EXPORT_SYMBOL(team_port_set_team_mac);
-+EXPORT_SYMBOL(team_port_set_team_dev_addr);
-
- static void team_refresh_port_linkup(struct team_port *port)
- {
-@@ -967,6 +967,8 @@ static struct netpoll_info *team_netpoll
- #endif
-
- static void __team_port_change_port_added(struct team_port *port, bool linkup);
-+static int team_dev_type_check_change(struct net_device *dev,
-+ struct net_device *port_dev);
-
- static int team_port_add(struct team *team, struct net_device *port_dev)
- {
-@@ -975,9 +977,8 @@ static int team_port_add(struct team *te
- char *portname = port_dev->name;
- int err;
-
-- if (port_dev->flags & IFF_LOOPBACK ||
-- port_dev->type != ARPHRD_ETHER) {
-- netdev_err(dev, "Device %s is of an unsupported type\n",
-+ if (port_dev->flags & IFF_LOOPBACK) {
-+ netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n",
- portname);
- return -EINVAL;
- }
-@@ -988,6 +989,17 @@ static int team_port_add(struct team *te
- return -EBUSY;
- }
-
-+ if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
-+ vlan_uses_dev(dev)) {
-+ netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n",
-+ portname);
-+ return -EPERM;
-+ }
-+
-+ err = team_dev_type_check_change(dev, port_dev);
-+ if (err)
-+ return err;
-+
- if (port_dev->flags & IFF_UP) {
- netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
- portname);
-@@ -1010,7 +1022,7 @@ static int team_port_add(struct team *te
- goto err_set_mtu;
- }
-
-- memcpy(port->orig.dev_addr, port_dev->dev_addr, ETH_ALEN);
-+ memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
-
- err = team_port_enter(team, port);
- if (err) {
-@@ -1091,7 +1103,7 @@ err_vids_add:
-
- err_dev_open:
- team_port_leave(team, port);
-- team_port_set_orig_mac(port);
-+ team_port_set_orig_dev_addr(port);
-
- err_port_enter:
- dev_set_mtu(port_dev, port->orig.mtu);
-@@ -1129,7 +1141,7 @@ static int team_port_del(struct team *te
- vlan_vids_del_by_dev(port_dev, dev);
- dev_close(port_dev);
- team_port_leave(team, port);
-- team_port_set_orig_mac(port);
-+ team_port_set_orig_dev_addr(port);
- dev_set_mtu(port_dev, port->orig.mtu);
- synchronize_rcu();
- kfree(port);
-@@ -1480,17 +1492,18 @@ static void team_set_rx_mode(struct net_
-
- static int team_set_mac_address(struct net_device *dev, void *p)
- {
-+ struct sockaddr *addr = p;
- struct team *team = netdev_priv(dev);
- struct team_port *port;
-- int err;
-
-- err = eth_mac_addr(dev, p);
-- if (err)
-- return err;
-+ if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
-+ return -EADDRNOTAVAIL;
-+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
- rcu_read_lock();
- list_for_each_entry_rcu(port, &team->port_list, list)
-- if (team->ops.port_change_mac)
-- team->ops.port_change_mac(team, port);
-+ if (team->ops.port_change_dev_addr)
-+ team->ops.port_change_dev_addr(team, port);
- rcu_read_unlock();
- return 0;
- }
-@@ -1721,6 +1734,45 @@ static const struct net_device_ops team_
- * rt netlink interface
- ***********************/
-
-+static void team_setup_by_port(struct net_device *dev,
-+ struct net_device *port_dev)
-+{
-+ dev->header_ops = port_dev->header_ops;
-+ dev->type = port_dev->type;
-+ dev->hard_header_len = port_dev->hard_header_len;
-+ dev->addr_len = port_dev->addr_len;
-+ dev->mtu = port_dev->mtu;
-+ memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len);
-+ memcpy(dev->dev_addr, port_dev->dev_addr, port_dev->addr_len);
-+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
-+}
-+
-+static int team_dev_type_check_change(struct net_device *dev,
-+ struct net_device *port_dev)
-+{
-+ struct team *team = netdev_priv(dev);
-+ char *portname = port_dev->name;
-+ int err;
-+
-+ if (dev->type == port_dev->type)
-+ return 0;
-+ if (!list_empty(&team->port_list)) {
-+ netdev_err(dev, "Device %s is of different type\n", portname);
-+ return -EBUSY;
-+ }
-+ err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
-+ err = notifier_to_errno(err);
-+ if (err) {
-+ netdev_err(dev, "Refused to change device type\n");
-+ return err;
-+ }
-+ dev_uc_flush(dev);
-+ dev_mc_flush(dev);
-+ team_setup_by_port(dev, port_dev);
-+ call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
-+ return 0;
-+}
-+
- static void team_setup(struct net_device *dev)
- {
- ether_setup(dev);
-@@ -2442,7 +2494,7 @@ static void __team_options_change_check(
- list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list);
- }
- err = team_nl_send_event_options_get(team, &sel_opt_inst_list);
-- if (err)
-+ if (err && err != -ESRCH)
- netdev_warn(team->dev, "Failed to send options change via netlink (err %d)\n",
- err);
- }
-@@ -2471,9 +2523,9 @@ static void __team_port_change_send(stru
-
- send_event:
- err = team_nl_send_event_port_list_get(port->team);
-- if (err)
-- netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n",
-- port->dev->name);
-+ if (err && err != -ESRCH)
-+ netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink (err %d)\n",
-+ port->dev->name, err);
-
- }
-
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team_mode_broadcast.c
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team_mode_broadcast.c
-@@ -48,18 +48,18 @@ static bool bc_transmit(struct team *tea
-
- static int bc_port_enter(struct team *team, struct team_port *port)
- {
-- return team_port_set_team_mac(port);
-+ return team_port_set_team_dev_addr(port);
- }
-
--static void bc_port_change_mac(struct team *team, struct team_port *port)
-+static void bc_port_change_dev_addr(struct team *team, struct team_port *port)
- {
-- team_port_set_team_mac(port);
-+ team_port_set_team_dev_addr(port);
- }
-
- static const struct team_mode_ops bc_mode_ops = {
- .transmit = bc_transmit,
- .port_enter = bc_port_enter,
-- .port_change_mac = bc_port_change_mac,
-+ .port_change_dev_addr = bc_port_change_dev_addr,
- };
-
- static const struct team_mode bc_mode = {
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/drivers/net/team/team_mode_roundrobin.c
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/drivers/net/team/team_mode_roundrobin.c
-@@ -66,18 +66,18 @@ drop:
-
- static int rr_port_enter(struct team *team, struct team_port *port)
- {
-- return team_port_set_team_mac(port);
-+ return team_port_set_team_dev_addr(port);
- }
-
--static void rr_port_change_mac(struct team *team, struct team_port *port)
-+static void rr_port_change_dev_addr(struct team *team, struct team_port *port)
- {
-- team_port_set_team_mac(port);
-+ team_port_set_team_dev_addr(port);
- }
-
- static const struct team_mode_ops rr_mode_ops = {
- .transmit = rr_transmit,
- .port_enter = rr_port_enter,
-- .port_change_mac = rr_port_change_mac,
-+ .port_change_dev_addr = rr_port_change_dev_addr,
- };
-
- static const struct team_mode rr_mode = {
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/include/linux/if_team.h
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/include/linux/if_team.h
-@@ -108,7 +108,7 @@ struct team_mode_ops {
- bool (*transmit)(struct team *team, struct sk_buff *skb);
- int (*port_enter)(struct team *team, struct team_port *port);
- void (*port_leave)(struct team *team, struct team_port *port);
-- void (*port_change_mac)(struct team *team, struct team_port *port);
-+ void (*port_change_dev_addr)(struct team *team, struct team_port *port);
- void (*port_enabled)(struct team *team, struct team_port *port);
- void (*port_disabled)(struct team *team, struct team_port *port);
- };
-@@ -238,7 +238,7 @@ static inline struct team_port *team_get
- return NULL;
- }
-
--extern int team_port_set_team_mac(struct team_port *port);
-+extern int team_port_set_team_dev_addr(struct team_port *port);
- extern int team_options_register(struct team *team,
- const struct team_option *option,
- size_t option_count);
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/include/linux/if_vlan.h
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/include/linux/if_vlan.h
-@@ -74,8 +74,6 @@ static inline struct vlan_ethhdr *vlan_e
- /* found in socket.c */
- extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
-
--struct vlan_info;
--
- static inline int is_vlan_dev(struct net_device *dev)
- {
- return dev->priv_flags & IFF_802_1Q_VLAN;
-@@ -101,6 +99,8 @@ extern int vlan_vids_add_by_dev(struct n
- const struct net_device *by_dev);
- extern void vlan_vids_del_by_dev(struct net_device *dev,
- const struct net_device *by_dev);
-+
-+extern bool vlan_uses_dev(const struct net_device *dev);
- #else
- static inline struct net_device *
- __vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id)
-@@ -151,6 +151,11 @@ static inline void vlan_vids_del_by_dev(
- const struct net_device *by_dev)
- {
- }
-+
-+static inline bool vlan_uses_dev(const struct net_device *dev)
-+{
-+ return false;
-+}
- #endif
-
- /**
---- linux-3.6.0-0.rc7.git2.1.fc18.x86_64.orig/net/8021q/vlan_core.c
-+++ linux-3.6.0-0.rc7.git2.1.fc18.x86_64/net/8021q/vlan_core.c
-@@ -368,3 +368,9 @@ void vlan_vids_del_by_dev(struct net_dev
- vlan_vid_del(dev, vid_info->vid);
- }
- EXPORT_SYMBOL(vlan_vids_del_by_dev);
-+
-+bool vlan_uses_dev(const struct net_device *dev)
-+{
-+ return rtnl_dereference(dev->vlan_info) ? true : false;
-+}
-+EXPORT_SYMBOL(vlan_uses_dev);
diff --git a/freed-ora/current/f18/uprobes-upstream-backport.patch b/freed-ora/current/f18/uprobes-upstream-backport.patch
deleted file mode 100644
index 9614e41b9..000000000
--- a/freed-ora/current/f18/uprobes-upstream-backport.patch
+++ /dev/null
@@ -1,1376 +0,0 @@
-Hello,
-
-Test builds:
- f18: http://koji.fedoraproject.org/koji/taskinfo?taskID=4635065
- f17: http://koji.fedoraproject.org/koji/taskinfo?taskID=4635062
-
-The split-out series is available in the git repository at:
- http://fedorapeople.org/cgit/aarapov/public_git/kernel-uprobes.git
-
-Just <at> jistone's patch is not upstream that exports functions.
-Yes, I know it must go to upstream. :-) I will try to do what I can before
-the next uprobes update.
-
----------------------------------------------------------------
-Josh Stone (1):
- uprobes: add exports necessary for uprobes use by modules
-
-Oleg Nesterov (35):
- uprobes: Kill uprobes_state->count
- uprobes: Kill dup_mmap()->uprobe_mmap(), simplify uprobe_mmap/munmap
- uprobes: Change uprobe_mmap() to ignore the errors but check fatal_signal_pending()
- uprobes: Do not use -EEXIST in install_breakpoint() paths
- uprobes: Introduce MMF_HAS_UPROBES
- uprobes: Fold uprobe_reset_state() into uprobe_dup_mmap()
- uprobes: Remove "verify" argument from set_orig_insn()
- uprobes: uprobes_treelock should not disable irqs
- uprobes: Introduce MMF_RECALC_UPROBES
- uprobes: Teach find_active_uprobe() to clear MMF_HAS_UPROBES
- ptrace/x86: Introduce set_task_blockstep() helper
- ptrace/x86: Partly fix set_task_blockstep()->update_debugctlmsr() logic
- uprobes/x86: Do not (ab)use TIF_SINGLESTEP/user_*_single_step() for single-stepping
- uprobes/x86: Xol should send SIGTRAP if X86_EFLAGS_TF was set
- uprobes/x86: Fix arch_uprobe_disable_step() && UTASK_SSTEP_TRAPPED interaction
- uprobes: Make arch_uprobe_task->saved_trap_nr "unsigned int"
- uprobes: Do not leak UTASK_BP_HIT if find_active_uprobe() fails
- uprobes: Do not setup ->active_uprobe/state prematurely
- uprobes: Fix UPROBE_SKIP_SSTEP checks in handle_swbp()
- uprobes: Kill UTASK_BP_HIT state
- uprobes: Move clear_thread_flag(TIF_UPROBE) to uprobe_notify_resume()
- uprobes: Change write_opcode() to use FOLL_FORCE
- uprobes: Change valid_vma() to demand VM_MAYEXEC rather than VM_EXEC
- uprobes: Restrict valid_vma(false) to skip VM_SHARED vmas
- uprobes: Kill set_swbp()->is_swbp_at_addr()
- uprobes: Introduce copy_opcode(), kill read_opcode()
- uprobes: Kill set_orig_insn()->is_swbp_at_addr()
- uprobes: Simplify is_swbp_at_addr(), remove stale comments
- uprobes/x86: Only rep+nop can be emulated correctly
- uprobes: Don't return success if alloc_uprobe() fails
- uprobes: Do not delete uprobe if uprobe_unregister() fails
- uprobes: Fix handle_swbp() vs unregister() + register() race
- uprobes: Introduce prepare_uprobe()
- uprobes: Fix prepare_uprobe() race with itself
- uprobes: Fix the racy uprobe->flags manipulation
-
-Sebastian Andrzej Siewior (4):
- uprobes: Remove check for uprobe variable in handle_swbp()
- uprobes: Don't put NULL pointer in uprobe_register()
- uprobes: Introduce arch_uprobe_enable/disable_step()
- uprobes/x86: Implement x86 specific arch_uprobe_*_step
-
-Srikar Dronamraju (1):
- uprobes: Remove redundant lock_page/unlock_page
-
- arch/x86/include/asm/processor.h | 2 +
- arch/x86/include/asm/uprobes.h | 3 +-
- arch/x86/kernel/signal.c | 4 +-
- arch/x86/kernel/step.c | 53 ++--
- arch/x86/kernel/uprobes.c | 64 ++++-
- include/linux/sched.h | 3 +
- include/linux/uprobes.h | 26 +-
- kernel/events/uprobes.c | 564 ++++++++++++++++++---------------------
- kernel/fork.c | 6 +-
- kernel/ptrace.c | 6 +
- 10 files changed, 375 insertions(+), 356 deletions(-)
-
-diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
-index d048cad..433d2e5 100644
---- a/arch/x86/include/asm/processor.h
-+++ b/arch/x86/include/asm/processor.h
-@@ -759,6 +759,8 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
- }
-
-+extern void set_task_blockstep(struct task_struct *task, bool on);
-+
- /*
- * from system description table in BIOS. Mostly for MCA use, but
- * others may find it useful:
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index f3971bb..8ff8be7 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -42,10 +42,11 @@ struct arch_uprobe {
- };
-
- struct arch_uprobe_task {
-- unsigned long saved_trap_nr;
- #ifdef CONFIG_X86_64
- unsigned long saved_scratch_register;
- #endif
-+ unsigned int saved_trap_nr;
-+ unsigned int saved_tf;
- };
-
- extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
-diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
-index b280908..0041e5a 100644
---- a/arch/x86/kernel/signal.c
-+++ b/arch/x86/kernel/signal.c
-@@ -785,10 +785,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
- mce_notify_process();
- #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
-
-- if (thread_info_flags & _TIF_UPROBE) {
-- clear_thread_flag(TIF_UPROBE);
-+ if (thread_info_flags & _TIF_UPROBE)
- uprobe_notify_resume(regs);
-- }
-
- /* deal with pending signal delivery */
- if (thread_info_flags & _TIF_SIGPENDING)
-diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
-index c346d11..cd3b243 100644
---- a/arch/x86/kernel/step.c
-+++ b/arch/x86/kernel/step.c
-@@ -157,6 +157,33 @@ static int enable_single_step(struct task_struct *child)
- return 1;
- }
-
-+void set_task_blockstep(struct task_struct *task, bool on)
-+{
-+ unsigned long debugctl;
-+
-+ /*
-+ * Ensure irq/preemption can't change debugctl in between.
-+ * Note also that both TIF_BLOCKSTEP and debugctl should
-+ * be changed atomically wrt preemption.
-+ * FIXME: this means that set/clear TIF_BLOCKSTEP is simply
-+ * wrong if task != current, SIGKILL can wakeup the stopped
-+ * tracee and set/clear can play with the running task, this
-+ * can confuse the next __switch_to_xtra().
-+ */
-+ local_irq_disable();
-+ debugctl = get_debugctlmsr();
-+ if (on) {
-+ debugctl |= DEBUGCTLMSR_BTF;
-+ set_tsk_thread_flag(task, TIF_BLOCKSTEP);
-+ } else {
-+ debugctl &= ~DEBUGCTLMSR_BTF;
-+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
-+ }
-+ if (task == current)
-+ update_debugctlmsr(debugctl);
-+ local_irq_enable();
-+}
-+
- /*
- * Enable single or block step.
- */
-@@ -169,19 +196,10 @@ static void enable_step(struct task_struct *child, bool block)
- * So no one should try to use debugger block stepping in a program
- * that uses user-mode single stepping itself.
- */
-- if (enable_single_step(child) && block) {
-- unsigned long debugctl = get_debugctlmsr();
--
-- debugctl |= DEBUGCTLMSR_BTF;
-- update_debugctlmsr(debugctl);
-- set_tsk_thread_flag(child, TIF_BLOCKSTEP);
-- } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
-- unsigned long debugctl = get_debugctlmsr();
--
-- debugctl &= ~DEBUGCTLMSR_BTF;
-- update_debugctlmsr(debugctl);
-- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
-- }
-+ if (enable_single_step(child) && block)
-+ set_task_blockstep(child, true);
-+ else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
-+ set_task_blockstep(child, false);
- }
-
- void user_enable_single_step(struct task_struct *child)
-@@ -199,13 +217,8 @@ void user_disable_single_step(struct task_struct *child)
- /*
- * Make sure block stepping (BTF) is disabled.
- */
-- if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
-- unsigned long debugctl = get_debugctlmsr();
--
-- debugctl &= ~DEBUGCTLMSR_BTF;
-- update_debugctlmsr(debugctl);
-- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
-- }
-+ if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
-+ set_task_blockstep(child, false);
-
- /* Always clear TIF_SINGLESTEP... */
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 36fd420..aafa555 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -41,6 +41,9 @@
- /* Adjust the return address of a call insn */
- #define UPROBE_FIX_CALL 0x2
-
-+/* Instruction will modify TF, don't change it */
-+#define UPROBE_FIX_SETF 0x4
-+
- #define UPROBE_FIX_RIP_AX 0x8000
- #define UPROBE_FIX_RIP_CX 0x4000
-
-@@ -239,6 +242,10 @@ static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
- insn_get_opcode(insn); /* should be a nop */
-
- switch (OPCODE1(insn)) {
-+ case 0x9d:
-+ /* popf */
-+ auprobe->fixups |= UPROBE_FIX_SETF;
-+ break;
- case 0xc3: /* ret/lret */
- case 0xcb:
- case 0xc2:
-@@ -644,32 +651,63 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-
- /*
- * Skip these instructions as per the currently known x86 ISA.
-- * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 }
-+ * rep=0x66*; nop=0x90
- */
--bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
- {
- int i;
-
- for (i = 0; i < MAX_UINSN_BYTES; i++) {
-- if ((auprobe->insn[i] == 0x66))
-+ if (auprobe->insn[i] == 0x66)
- continue;
-
- if (auprobe->insn[i] == 0x90)
- return true;
-
-- if (i == (MAX_UINSN_BYTES - 1))
-- break;
-+ break;
-+ }
-+ return false;
-+}
-
-- if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f))
-- return true;
-+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+ bool ret = __skip_sstep(auprobe, regs);
-+ if (ret && (regs->flags & X86_EFLAGS_TF))
-+ send_sig(SIGTRAP, current, 0);
-+ return ret;
-+}
-
-- if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19))
-- return true;
-+void arch_uprobe_enable_step(struct arch_uprobe *auprobe)
-+{
-+ struct task_struct *task = current;
-+ struct arch_uprobe_task *autask = &task->utask->autask;
-+ struct pt_regs *regs = task_pt_regs(task);
-
-- if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0))
-- return true;
-+ autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF);
-
-- break;
-+ regs->flags |= X86_EFLAGS_TF;
-+ if (test_tsk_thread_flag(task, TIF_BLOCKSTEP))
-+ set_task_blockstep(task, false);
-+}
-+
-+void arch_uprobe_disable_step(struct arch_uprobe *auprobe)
-+{
-+ struct task_struct *task = current;
-+ struct arch_uprobe_task *autask = &task->utask->autask;
-+ bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED);
-+ struct pt_regs *regs = task_pt_regs(task);
-+ /*
-+ * The state of TIF_BLOCKSTEP was not saved so we can get an extra
-+ * SIGTRAP if we do not clear TF. We need to examine the opcode to
-+ * make it right.
-+ */
-+ if (unlikely(trapped)) {
-+ if (!autask->saved_tf)
-+ regs->flags &= ~X86_EFLAGS_TF;
-+ } else {
-+ if (autask->saved_tf)
-+ send_sig(SIGTRAP, task, 0);
-+ else if (!(auprobe->fixups & UPROBE_FIX_SETF))
-+ regs->flags &= ~X86_EFLAGS_TF;
- }
-- return false;
- }
-diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 23bddac..ba300be 100644
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -446,6 +446,9 @@ extern int get_dumpable(struct mm_struct *mm);
- #define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */
- #define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */
-
-+#define MMF_HAS_UPROBES 19 /* has uprobes */
-+#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */
-+
- #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
-
- struct sighand_struct {
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index efe4b33..2459457 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -35,16 +35,6 @@ struct inode;
- # include <asm/uprobes.h>
- #endif
-
--/* flags that denote/change uprobes behaviour */
--
--/* Have a copy of original instruction */
--#define UPROBE_COPY_INSN 0x1
--
--/* Dont run handlers when first register/ last unregister in progress*/
--#define UPROBE_RUN_HANDLER 0x2
--/* Can skip singlestep */
--#define UPROBE_SKIP_SSTEP 0x4
--
- struct uprobe_consumer {
- int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
- /*
-@@ -59,7 +49,6 @@ struct uprobe_consumer {
- #ifdef CONFIG_UPROBES
- enum uprobe_task_state {
- UTASK_RUNNING,
-- UTASK_BP_HIT,
- UTASK_SSTEP,
- UTASK_SSTEP_ACK,
- UTASK_SSTEP_TRAPPED,
-@@ -99,25 +88,27 @@ struct xol_area {
-
- struct uprobes_state {
- struct xol_area *xol_area;
-- atomic_t count;
- };
-+
- extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
--extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr, bool verify);
-+extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
- extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
- extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end);
-+extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm);
- extern void uprobe_free_utask(struct task_struct *t);
- extern void uprobe_copy_process(struct task_struct *t);
- extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
-+extern void __weak arch_uprobe_enable_step(struct arch_uprobe *arch);
-+extern void __weak arch_uprobe_disable_step(struct arch_uprobe *arch);
- extern int uprobe_post_sstep_notifier(struct pt_regs *regs);
- extern int uprobe_pre_sstep_notifier(struct pt_regs *regs);
- extern void uprobe_notify_resume(struct pt_regs *regs);
- extern bool uprobe_deny_signal(void);
- extern bool __weak arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs);
- extern void uprobe_clear_state(struct mm_struct *mm);
--extern void uprobe_reset_state(struct mm_struct *mm);
- #else /* !CONFIG_UPROBES */
- struct uprobes_state {
- };
-@@ -138,6 +129,10 @@ static inline void
- uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
- {
- }
-+static inline void
-+uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
-+{
-+}
- static inline void uprobe_notify_resume(struct pt_regs *regs)
- {
- }
-@@ -158,8 +153,5 @@ static inline void uprobe_copy_process(struct task_struct *t)
- static inline void uprobe_clear_state(struct mm_struct *mm)
- {
- }
--static inline void uprobe_reset_state(struct mm_struct *mm)
--{
--}
- #endif /* !CONFIG_UPROBES */
- #endif /* _LINUX_UPROBES_H */
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index c08a22d..e933f65 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -27,6 +27,7 @@
- #include <linux/pagemap.h> /* read_mapping_page */
- #include <linux/slab.h>
- #include <linux/sched.h>
-+#include <linux/export.h>
- #include <linux/rmap.h> /* anon_vma_prepare */
- #include <linux/mmu_notifier.h> /* set_pte_at_notify */
- #include <linux/swap.h> /* try_to_free_swap */
-@@ -78,15 +79,23 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
- */
- static atomic_t uprobe_events = ATOMIC_INIT(0);
-
-+/* Have a copy of original instruction */
-+#define UPROBE_COPY_INSN 0
-+/* Dont run handlers when first register/ last unregister in progress*/
-+#define UPROBE_RUN_HANDLER 1
-+/* Can skip singlestep */
-+#define UPROBE_SKIP_SSTEP 2
-+
- struct uprobe {
- struct rb_node rb_node; /* node in the rb tree */
- atomic_t ref;
- struct rw_semaphore consumer_rwsem;
-+ struct mutex copy_mutex; /* TODO: kill me and UPROBE_COPY_INSN */
- struct list_head pending_list;
- struct uprobe_consumer *consumers;
- struct inode *inode; /* Also hold a ref to inode */
- loff_t offset;
-- int flags;
-+ unsigned long flags;
- struct arch_uprobe arch;
- };
-
-@@ -100,17 +109,12 @@ struct uprobe {
- */
- static bool valid_vma(struct vm_area_struct *vma, bool is_register)
- {
-- if (!vma->vm_file)
-- return false;
-+ vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED;
-
-- if (!is_register)
-- return true;
-+ if (is_register)
-+ flags |= VM_WRITE;
-
-- if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED))
-- == (VM_READ|VM_EXEC))
-- return true;
--
-- return false;
-+ return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC;
- }
-
- static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset)
-@@ -188,19 +192,44 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn)
- return *insn == UPROBE_SWBP_INSN;
- }
-
-+static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode)
-+{
-+ void *kaddr = kmap_atomic(page);
-+ memcpy(opcode, kaddr + (vaddr & ~PAGE_MASK), UPROBE_SWBP_INSN_SIZE);
-+ kunmap_atomic(kaddr);
-+}
-+
-+static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode)
-+{
-+ uprobe_opcode_t old_opcode;
-+ bool is_swbp;
-+
-+ copy_opcode(page, vaddr, &old_opcode);
-+ is_swbp = is_swbp_insn(&old_opcode);
-+
-+ if (is_swbp_insn(new_opcode)) {
-+ if (is_swbp) /* register: already installed? */
-+ return 0;
-+ } else {
-+ if (!is_swbp) /* unregister: was it changed by us? */
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
- /*
- * NOTE:
- * Expect the breakpoint instruction to be the smallest size instruction for
- * the architecture. If an arch has variable length instruction and the
- * breakpoint instruction is not of the smallest length instruction
-- * supported by that architecture then we need to modify read_opcode /
-+ * supported by that architecture then we need to modify is_swbp_at_addr and
- * write_opcode accordingly. This would never be a problem for archs that
- * have fixed length instructions.
- */
-
- /*
- * write_opcode - write the opcode at a given virtual address.
-- * @auprobe: arch breakpointing information.
- * @mm: the probed process address space.
- * @vaddr: the virtual address to store the opcode.
- * @opcode: opcode to be written at @vaddr.
-@@ -211,8 +240,8 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn)
- * For mm @mm, write the opcode at @vaddr.
- * Return 0 (success) or a negative errno.
- */
--static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
-- unsigned long vaddr, uprobe_opcode_t opcode)
-+static int write_opcode(struct mm_struct *mm, unsigned long vaddr,
-+ uprobe_opcode_t opcode)
- {
- struct page *old_page, *new_page;
- void *vaddr_old, *vaddr_new;
-@@ -221,10 +250,14 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
-
- retry:
- /* Read the page with vaddr into memory */
-- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
-+ ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
- if (ret <= 0)
- return ret;
-
-+ ret = verify_opcode(old_page, vaddr, &opcode);
-+ if (ret <= 0)
-+ goto put_old;
-+
- ret = -ENOMEM;
- new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
- if (!new_page)
-@@ -259,65 +292,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
- }
-
- /**
-- * read_opcode - read the opcode at a given virtual address.
-- * @mm: the probed process address space.
-- * @vaddr: the virtual address to read the opcode.
-- * @opcode: location to store the read opcode.
-- *
-- * Called with mm->mmap_sem held (for read and with a reference to
-- * mm.
-- *
-- * For mm @mm, read the opcode at @vaddr and store it in @opcode.
-- * Return 0 (success) or a negative errno.
-- */
--static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode)
--{
-- struct page *page;
-- void *vaddr_new;
-- int ret;
--
-- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
-- if (ret <= 0)
-- return ret;
--
-- lock_page(page);
-- vaddr_new = kmap_atomic(page);
-- vaddr &= ~PAGE_MASK;
-- memcpy(opcode, vaddr_new + vaddr, UPROBE_SWBP_INSN_SIZE);
-- kunmap_atomic(vaddr_new);
-- unlock_page(page);
--
-- put_page(page);
--
-- return 0;
--}
--
--static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
--{
-- uprobe_opcode_t opcode;
-- int result;
--
-- if (current->mm == mm) {
-- pagefault_disable();
-- result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
-- sizeof(opcode));
-- pagefault_enable();
--
-- if (likely(result == 0))
-- goto out;
-- }
--
-- result = read_opcode(mm, vaddr, &opcode);
-- if (result)
-- return result;
--out:
-- if (is_swbp_insn(&opcode))
-- return 1;
--
-- return 0;
--}
--
--/**
- * set_swbp - store breakpoint at a given address.
- * @auprobe: arch specific probepoint information.
- * @mm: the probed process address space.
-@@ -328,18 +302,7 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
- */
- int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
- {
-- int result;
-- /*
-- * See the comment near uprobes_hash().
-- */
-- result = is_swbp_at_addr(mm, vaddr);
-- if (result == 1)
-- return -EEXIST;
--
-- if (result)
-- return result;
--
-- return write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
-+ return write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
- }
-
- /**
-@@ -347,25 +310,14 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned
- * @mm: the probed process address space.
- * @auprobe: arch specific probepoint information.
- * @vaddr: the virtual address to insert the opcode.
-- * @verify: if true, verify existance of breakpoint instruction.
- *
- * For mm @mm, restore the original opcode (opcode) at @vaddr.
- * Return 0 (success) or a negative errno.
- */
- int __weak
--set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, bool verify)
-+set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
- {
-- if (verify) {
-- int result;
--
-- result = is_swbp_at_addr(mm, vaddr);
-- if (!result)
-- return -EINVAL;
--
-- if (result != 1)
-- return result;
-- }
-- return write_opcode(auprobe, mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
-+ return write_opcode(mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
- }
-
- static int match_uprobe(struct uprobe *l, struct uprobe *r)
-@@ -415,11 +367,10 @@ static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
- static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
- {
- struct uprobe *uprobe;
-- unsigned long flags;
-
-- spin_lock_irqsave(&uprobes_treelock, flags);
-+ spin_lock(&uprobes_treelock);
- uprobe = __find_uprobe(inode, offset);
-- spin_unlock_irqrestore(&uprobes_treelock, flags);
-+ spin_unlock(&uprobes_treelock);
-
- return uprobe;
- }
-@@ -466,15 +417,14 @@ static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
- */
- static struct uprobe *insert_uprobe(struct uprobe *uprobe)
- {
-- unsigned long flags;
- struct uprobe *u;
-
-- spin_lock_irqsave(&uprobes_treelock, flags);
-+ spin_lock(&uprobes_treelock);
- u = __insert_uprobe(uprobe);
-- spin_unlock_irqrestore(&uprobes_treelock, flags);
-+ spin_unlock(&uprobes_treelock);
-
- /* For now assume that the instruction need not be single-stepped */
-- uprobe->flags |= UPROBE_SKIP_SSTEP;
-+ __set_bit(UPROBE_SKIP_SSTEP, &uprobe->flags);
-
- return u;
- }
-@@ -496,6 +446,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
- uprobe->inode = igrab(inode);
- uprobe->offset = offset;
- init_rwsem(&uprobe->consumer_rwsem);
-+ mutex_init(&uprobe->copy_mutex);
-
- /* add to uprobes_tree, sorted on inode:offset */
- cur_uprobe = insert_uprobe(uprobe);
-@@ -516,7 +467,7 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
- {
- struct uprobe_consumer *uc;
-
-- if (!(uprobe->flags & UPROBE_RUN_HANDLER))
-+ if (!test_bit(UPROBE_RUN_HANDLER, &uprobe->flags))
- return;
-
- down_read(&uprobe->consumer_rwsem);
-@@ -622,33 +573,48 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp)
- return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset);
- }
-
--/*
-- * How mm->uprobes_state.count gets updated
-- * uprobe_mmap() increments the count if
-- * - it successfully adds a breakpoint.
-- * - it cannot add a breakpoint, but sees that there is a underlying
-- * breakpoint (via a is_swbp_at_addr()).
-- *
-- * uprobe_munmap() decrements the count if
-- * - it sees a underlying breakpoint, (via is_swbp_at_addr)
-- * (Subsequent uprobe_unregister wouldnt find the breakpoint
-- * unless a uprobe_mmap kicks in, since the old vma would be
-- * dropped just after uprobe_munmap.)
-- *
-- * uprobe_register increments the count if:
-- * - it successfully adds a breakpoint.
-- *
-- * uprobe_unregister decrements the count if:
-- * - it sees a underlying breakpoint and removes successfully.
-- * (via is_swbp_at_addr)
-- * (Subsequent uprobe_munmap wouldnt find the breakpoint
-- * since there is no underlying breakpoint after the
-- * breakpoint removal.)
-- */
-+static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
-+ struct mm_struct *mm, unsigned long vaddr)
-+{
-+ int ret = 0;
-+
-+ if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
-+ return ret;
-+
-+ mutex_lock(&uprobe->copy_mutex);
-+ if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
-+ goto out;
-+
-+ ret = copy_insn(uprobe, file);
-+ if (ret)
-+ goto out;
-+
-+ ret = -ENOTSUPP;
-+ if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
-+ goto out;
-+
-+ ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
-+ if (ret)
-+ goto out;
-+
-+ /* write_opcode() assumes we don't cross page boundary */
-+ BUG_ON((uprobe->offset & ~PAGE_MASK) +
-+ UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-+
-+ smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
-+ set_bit(UPROBE_COPY_INSN, &uprobe->flags);
-+
-+ out:
-+ mutex_unlock(&uprobe->copy_mutex);
-+
-+ return ret;
-+}
-+
- static int
- install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- struct vm_area_struct *vma, unsigned long vaddr)
- {
-+ bool first_uprobe;
- int ret;
-
- /*
-@@ -659,48 +625,38 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- * Hence behave as if probe already existed.
- */
- if (!uprobe->consumers)
-- return -EEXIST;
--
-- if (!(uprobe->flags & UPROBE_COPY_INSN)) {
-- ret = copy_insn(uprobe, vma->vm_file);
-- if (ret)
-- return ret;
--
-- if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
-- return -ENOTSUPP;
--
-- ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
-- if (ret)
-- return ret;
--
-- /* write_opcode() assumes we don't cross page boundary */
-- BUG_ON((uprobe->offset & ~PAGE_MASK) +
-- UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-+ return 0;
-
-- uprobe->flags |= UPROBE_COPY_INSN;
-- }
-+ ret = prepare_uprobe(uprobe, vma->vm_file, mm, vaddr);
-+ if (ret)
-+ return ret;
-
- /*
-- * Ideally, should be updating the probe count after the breakpoint
-- * has been successfully inserted. However a thread could hit the
-- * breakpoint we just inserted even before the probe count is
-- * incremented. If this is the first breakpoint placed, breakpoint
-- * notifier might ignore uprobes and pass the trap to the thread.
-- * Hence increment before and decrement on failure.
-+ * set MMF_HAS_UPROBES in advance for uprobe_pre_sstep_notifier(),
-+ * the task can hit this breakpoint right after __replace_page().
- */
-- atomic_inc(&mm->uprobes_state.count);
-+ first_uprobe = !test_bit(MMF_HAS_UPROBES, &mm->flags);
-+ if (first_uprobe)
-+ set_bit(MMF_HAS_UPROBES, &mm->flags);
-+
- ret = set_swbp(&uprobe->arch, mm, vaddr);
-- if (ret)
-- atomic_dec(&mm->uprobes_state.count);
-+ if (!ret)
-+ clear_bit(MMF_RECALC_UPROBES, &mm->flags);
-+ else if (first_uprobe)
-+ clear_bit(MMF_HAS_UPROBES, &mm->flags);
-
- return ret;
- }
-
--static void
-+static int
- remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
- {
-- if (!set_orig_insn(&uprobe->arch, mm, vaddr, true))
-- atomic_dec(&mm->uprobes_state.count);
-+ /* can happen if uprobe_register() fails */
-+ if (!test_bit(MMF_HAS_UPROBES, &mm->flags))
-+ return 0;
-+
-+ set_bit(MMF_RECALC_UPROBES, &mm->flags);
-+ return set_orig_insn(&uprobe->arch, mm, vaddr);
- }
-
- /*
-@@ -710,11 +666,9 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vad
- */
- static void delete_uprobe(struct uprobe *uprobe)
- {
-- unsigned long flags;
--
-- spin_lock_irqsave(&uprobes_treelock, flags);
-+ spin_lock(&uprobes_treelock);
- rb_erase(&uprobe->rb_node, &uprobes_tree);
-- spin_unlock_irqrestore(&uprobes_treelock, flags);
-+ spin_unlock(&uprobes_treelock);
- iput(uprobe->inode);
- put_uprobe(uprobe);
- atomic_dec(&uprobe_events);
-@@ -818,7 +772,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- struct mm_struct *mm = info->mm;
- struct vm_area_struct *vma;
-
-- if (err)
-+ if (err && is_register)
- goto free;
-
- down_write(&mm->mmap_sem);
-@@ -831,17 +785,11 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- vaddr_to_offset(vma, info->vaddr) != uprobe->offset)
- goto unlock;
-
-- if (is_register) {
-+ if (is_register)
- err = install_breakpoint(uprobe, mm, vma, info->vaddr);
-- /*
-- * We can race against uprobe_mmap(), see the
-- * comment near uprobe_hash().
-- */
-- if (err == -EEXIST)
-- err = 0;
-- } else {
-- remove_breakpoint(uprobe, mm, info->vaddr);
-- }
-+ else
-+ err |= remove_breakpoint(uprobe, mm, info->vaddr);
-+
- unlock:
- up_write(&mm->mmap_sem);
- free:
-@@ -897,21 +845,25 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
- mutex_lock(uprobes_hash(inode));
- uprobe = alloc_uprobe(inode, offset);
-
-- if (uprobe && !consumer_add(uprobe, uc)) {
-+ if (!uprobe) {
-+ ret = -ENOMEM;
-+ } else if (!consumer_add(uprobe, uc)) {
- ret = __uprobe_register(uprobe);
- if (ret) {
- uprobe->consumers = NULL;
- __uprobe_unregister(uprobe);
- } else {
-- uprobe->flags |= UPROBE_RUN_HANDLER;
-+ set_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
- }
- }
-
- mutex_unlock(uprobes_hash(inode));
-- put_uprobe(uprobe);
-+ if (uprobe)
-+ put_uprobe(uprobe);
-
- return ret;
- }
-+EXPORT_SYMBOL_GPL(uprobe_register);
-
- /*
- * uprobe_unregister - unregister a already registered probe.
-@@ -935,7 +887,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
- if (consumer_del(uprobe, uc)) {
- if (!uprobe->consumers) {
- __uprobe_unregister(uprobe);
-- uprobe->flags &= ~UPROBE_RUN_HANDLER;
-+ clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
- }
- }
-
-@@ -943,6 +895,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
- if (uprobe)
- put_uprobe(uprobe);
- }
-+EXPORT_SYMBOL_GPL(uprobe_unregister);
-
- static struct rb_node *
- find_node_in_range(struct inode *inode, loff_t min, loff_t max)
-@@ -978,7 +931,6 @@ static void build_probe_list(struct inode *inode,
- struct list_head *head)
- {
- loff_t min, max;
-- unsigned long flags;
- struct rb_node *n, *t;
- struct uprobe *u;
-
-@@ -986,7 +938,7 @@ static void build_probe_list(struct inode *inode,
- min = vaddr_to_offset(vma, start);
- max = min + (end - start) - 1;
-
-- spin_lock_irqsave(&uprobes_treelock, flags);
-+ spin_lock(&uprobes_treelock);
- n = find_node_in_range(inode, min, max);
- if (n) {
- for (t = n; t; t = rb_prev(t)) {
-@@ -1004,27 +956,20 @@ static void build_probe_list(struct inode *inode,
- atomic_inc(&u->ref);
- }
- }
-- spin_unlock_irqrestore(&uprobes_treelock, flags);
-+ spin_unlock(&uprobes_treelock);
- }
-
- /*
-- * Called from mmap_region.
-- * called with mm->mmap_sem acquired.
-- *
-- * Return -ve no if we fail to insert probes and we cannot
-- * bail-out.
-- * Return 0 otherwise. i.e:
-+ * Called from mmap_region/vma_adjust with mm->mmap_sem acquired.
- *
-- * - successful insertion of probes
-- * - (or) no possible probes to be inserted.
-- * - (or) insertion of probes failed but we can bail-out.
-+ * Currently we ignore all errors and always return 0, the callers
-+ * can't handle the failure anyway.
- */
- int uprobe_mmap(struct vm_area_struct *vma)
- {
- struct list_head tmp_list;
- struct uprobe *uprobe, *u;
- struct inode *inode;
-- int ret, count;
-
- if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
- return 0;
-@@ -1036,44 +981,35 @@ int uprobe_mmap(struct vm_area_struct *vma)
- mutex_lock(uprobes_mmap_hash(inode));
- build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list);
-
-- ret = 0;
-- count = 0;
--
- list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
-- if (!ret) {
-+ if (!fatal_signal_pending(current)) {
- unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset);
--
-- ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
-- /*
-- * We can race against uprobe_register(), see the
-- * comment near uprobe_hash().
-- */
-- if (ret == -EEXIST) {
-- ret = 0;
--
-- if (!is_swbp_at_addr(vma->vm_mm, vaddr))
-- continue;
--
-- /*
-- * Unable to insert a breakpoint, but
-- * breakpoint lies underneath. Increment the
-- * probe count.
-- */
-- atomic_inc(&vma->vm_mm->uprobes_state.count);
-- }
--
-- if (!ret)
-- count++;
-+ install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
- }
- put_uprobe(uprobe);
- }
--
- mutex_unlock(uprobes_mmap_hash(inode));
-
-- if (ret)
-- atomic_sub(count, &vma->vm_mm->uprobes_state.count);
-+ return 0;
-+}
-
-- return ret;
-+static bool
-+vma_has_uprobes(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-+{
-+ loff_t min, max;
-+ struct inode *inode;
-+ struct rb_node *n;
-+
-+ inode = vma->vm_file->f_mapping->host;
-+
-+ min = vaddr_to_offset(vma, start);
-+ max = min + (end - start) - 1;
-+
-+ spin_lock(&uprobes_treelock);
-+ n = find_node_in_range(inode, min, max);
-+ spin_unlock(&uprobes_treelock);
-+
-+ return !!n;
- }
-
- /*
-@@ -1081,37 +1017,18 @@ int uprobe_mmap(struct vm_area_struct *vma)
- */
- void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
- {
-- struct list_head tmp_list;
-- struct uprobe *uprobe, *u;
-- struct inode *inode;
--
- if (!atomic_read(&uprobe_events) || !valid_vma(vma, false))
- return;
-
- if (!atomic_read(&vma->vm_mm->mm_users)) /* called by mmput() ? */
- return;
-
-- if (!atomic_read(&vma->vm_mm->uprobes_state.count))
-- return;
--
-- inode = vma->vm_file->f_mapping->host;
-- if (!inode)
-+ if (!test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags) ||
-+ test_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags))
- return;
-
-- mutex_lock(uprobes_mmap_hash(inode));
-- build_probe_list(inode, vma, start, end, &tmp_list);
--
-- list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
-- unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset);
-- /*
-- * An unregister could have removed the probe before
-- * unmap. So check before we decrement the count.
-- */
-- if (is_swbp_at_addr(vma->vm_mm, vaddr) == 1)
-- atomic_dec(&vma->vm_mm->uprobes_state.count);
-- put_uprobe(uprobe);
-- }
-- mutex_unlock(uprobes_mmap_hash(inode));
-+ if (vma_has_uprobes(vma, start, end))
-+ set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
- }
-
- /* Slot allocation for XOL */
-@@ -1213,13 +1130,15 @@ void uprobe_clear_state(struct mm_struct *mm)
- kfree(area);
- }
-
--/*
-- * uprobe_reset_state - Free the area allocated for slots.
-- */
--void uprobe_reset_state(struct mm_struct *mm)
-+void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm)
- {
-- mm->uprobes_state.xol_area = NULL;
-- atomic_set(&mm->uprobes_state.count, 0);
-+ newmm->uprobes_state.xol_area = NULL;
-+
-+ if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) {
-+ set_bit(MMF_HAS_UPROBES, &newmm->flags);
-+ /* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */
-+ set_bit(MMF_RECALC_UPROBES, &newmm->flags);
-+ }
- }
-
- /*
-@@ -1430,13 +1349,57 @@ bool uprobe_deny_signal(void)
- */
- static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs)
- {
-- if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
-- return true;
--
-- uprobe->flags &= ~UPROBE_SKIP_SSTEP;
-+ if (test_bit(UPROBE_SKIP_SSTEP, &uprobe->flags)) {
-+ if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
-+ return true;
-+ clear_bit(UPROBE_SKIP_SSTEP, &uprobe->flags);
-+ }
- return false;
- }
-
-+static void mmf_recalc_uprobes(struct mm_struct *mm)
-+{
-+ struct vm_area_struct *vma;
-+
-+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
-+ if (!valid_vma(vma, false))
-+ continue;
-+ /*
-+ * This is not strictly accurate, we can race with
-+ * uprobe_unregister() and see the already removed
-+ * uprobe if delete_uprobe() was not yet called.
-+ */
-+ if (vma_has_uprobes(vma, vma->vm_start, vma->vm_end))
-+ return;
-+ }
-+
-+ clear_bit(MMF_HAS_UPROBES, &mm->flags);
-+}
-+
-+static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
-+{
-+ struct page *page;
-+ uprobe_opcode_t opcode;
-+ int result;
-+
-+ pagefault_disable();
-+ result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
-+ sizeof(opcode));
-+ pagefault_enable();
-+
-+ if (likely(result == 0))
-+ goto out;
-+
-+ result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
-+ if (result < 0)
-+ return result;
-+
-+ copy_opcode(page, vaddr, &opcode);
-+ put_page(page);
-+ out:
-+ return is_swbp_insn(&opcode);
-+}
-+
- static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
- {
- struct mm_struct *mm = current->mm;
-@@ -1458,11 +1421,24 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
- } else {
- *is_swbp = -EFAULT;
- }
-+
-+ if (!uprobe && test_and_clear_bit(MMF_RECALC_UPROBES, &mm->flags))
-+ mmf_recalc_uprobes(mm);
- up_read(&mm->mmap_sem);
-
- return uprobe;
- }
-
-+void __weak arch_uprobe_enable_step(struct arch_uprobe *arch)
-+{
-+ user_enable_single_step(current);
-+}
-+
-+void __weak arch_uprobe_disable_step(struct arch_uprobe *arch)
-+{
-+ user_disable_single_step(current);
-+}
-+
- /*
- * Run handler and ask thread to singlestep.
- * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
-@@ -1494,41 +1470,42 @@ static void handle_swbp(struct pt_regs *regs)
- }
- return;
- }
-+ /*
-+ * TODO: move copy_insn/etc into _register and remove this hack.
-+ * After we hit the bp, _unregister + _register can install the
-+ * new and not-yet-analyzed uprobe at the same address, restart.
-+ */
-+ smp_rmb(); /* pairs with wmb() in install_breakpoint() */
-+ if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags)))
-+ goto restart;
-
- utask = current->utask;
- if (!utask) {
- utask = add_utask();
- /* Cannot allocate; re-execute the instruction. */
- if (!utask)
-- goto cleanup_ret;
-+ goto restart;
- }
-- utask->active_uprobe = uprobe;
-+
- handler_chain(uprobe, regs);
-- if (uprobe->flags & UPROBE_SKIP_SSTEP && can_skip_sstep(uprobe, regs))
-- goto cleanup_ret;
-+ if (can_skip_sstep(uprobe, regs))
-+ goto out;
-
-- utask->state = UTASK_SSTEP;
- if (!pre_ssout(uprobe, regs, bp_vaddr)) {
-- user_enable_single_step(current);
-+ arch_uprobe_enable_step(&uprobe->arch);
-+ utask->active_uprobe = uprobe;
-+ utask->state = UTASK_SSTEP;
- return;
- }
-
--cleanup_ret:
-- if (utask) {
-- utask->active_uprobe = NULL;
-- utask->state = UTASK_RUNNING;
-- }
-- if (uprobe) {
-- if (!(uprobe->flags & UPROBE_SKIP_SSTEP))
--
-- /*
-- * cannot singlestep; cannot skip instruction;
-- * re-execute the instruction.
-- */
-- instruction_pointer_set(regs, bp_vaddr);
--
-- put_uprobe(uprobe);
-- }
-+restart:
-+ /*
-+ * cannot singlestep; cannot skip instruction;
-+ * re-execute the instruction.
-+ */
-+ instruction_pointer_set(regs, bp_vaddr);
-+out:
-+ put_uprobe(uprobe);
- }
-
- /*
-@@ -1547,10 +1524,10 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
- else
- WARN_ON_ONCE(1);
-
-+ arch_uprobe_disable_step(&uprobe->arch);
- put_uprobe(uprobe);
- utask->active_uprobe = NULL;
- utask->state = UTASK_RUNNING;
-- user_disable_single_step(current);
- xol_free_insn_slot(current);
-
- spin_lock_irq(&current->sighand->siglock);
-@@ -1559,13 +1536,12 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
- }
-
- /*
-- * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag. (and on
-- * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and
-- * allows the thread to return from interrupt.
-+ * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and
-+ * allows the thread to return from interrupt. After that handle_swbp()
-+ * sets utask->active_uprobe.
- *
-- * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and
-- * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from
-- * interrupt.
-+ * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag
-+ * and allows the thread to return from interrupt.
- *
- * While returning to userspace, thread notices the TIF_UPROBE flag and calls
- * uprobe_notify_resume().
-@@ -1574,11 +1550,13 @@ void uprobe_notify_resume(struct pt_regs *regs)
- {
- struct uprobe_task *utask;
-
-+ clear_thread_flag(TIF_UPROBE);
-+
- utask = current->utask;
-- if (!utask || utask->state == UTASK_BP_HIT)
-- handle_swbp(regs);
-- else
-+ if (utask && utask->active_uprobe)
- handle_singlestep(utask, regs);
-+ else
-+ handle_swbp(regs);
- }
-
- /*
-@@ -1587,18 +1565,10 @@ void uprobe_notify_resume(struct pt_regs *regs)
- */
- int uprobe_pre_sstep_notifier(struct pt_regs *regs)
- {
-- struct uprobe_task *utask;
--
-- if (!current->mm || !atomic_read(&current->mm->uprobes_state.count))
-- /* task is currently not uprobed */
-+ if (!current->mm || !test_bit(MMF_HAS_UPROBES, &current->mm->flags))
- return 0;
-
-- utask = current->utask;
-- if (utask)
-- utask->state = UTASK_BP_HIT;
--
- set_thread_flag(TIF_UPROBE);
--
- return 1;
- }
-
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 2c8857e..2343c9e 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -353,6 +353,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
-
- down_write(&oldmm->mmap_sem);
- flush_cache_dup_mm(oldmm);
-+ uprobe_dup_mmap(oldmm, mm);
- /*
- * Not linked in yet - no deadlock potential:
- */
-@@ -454,9 +455,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
-
- if (retval)
- goto out;
--
-- if (file)
-- uprobe_mmap(tmp);
- }
- /* a new mm has just been created */
- arch_dup_mmap(oldmm, mm);
-@@ -839,8 +837,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
- #ifdef CONFIG_TRANSPARENT_HUGEPAGE
- mm->pmd_huge_pte = NULL;
- #endif
-- uprobe_reset_state(mm);
--
- if (!mm_init(mm, tsk))
- goto fail_nomem;
-
-diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index a232bb5..764fcd1 100644
---- a/kernel/ptrace.c
-+++ b/kernel/ptrace.c
-@@ -33,6 +33,12 @@ static int ptrace_trapping_sleep_fn(void *flags)
- }
-
- /*
-+ * This is declared in linux/regset.h and defined in machine-dependent
-+ * code. We put the export here to ensure no machine forgets it.
-+ */
-+EXPORT_SYMBOL_GPL(task_user_regset_view);
-+
-+/*
- * ptrace a task: make the debugger its new parent and
- * move it to the ptrace list.
- *
-_______________________________________________
-kernel mailing list
-kernel@lists.fedoraproject.org
-https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/freed-ora/current/f18/vt-Drop-K_OFF-for-VC_MUTE.patch b/freed-ora/current/f18/vt-Drop-K_OFF-for-VC_MUTE.patch
index ab85411cb..e9bc4fffa 100644
--- a/freed-ora/current/f18/vt-Drop-K_OFF-for-VC_MUTE.patch
+++ b/freed-ora/current/f18/vt-Drop-K_OFF-for-VC_MUTE.patch
@@ -64,7 +64,7 @@ Signed-off-by: Adam Jackson <ajax@redhat.com>
drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
include/linux/kbd_kern.h | 6 +++---
include/linux/vt_kern.h | 2 ++
- include/linux/kd.h | 5 +++++
+ include/uapi/linux/kd.h | 5 +++++
5 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
@@ -222,10 +222,10 @@ index 50ae7d0..a886915 100644
extern int vt_do_kdgkbmode(int console);
extern int vt_do_kdgkbmeta(int console);
extern void vt_reset_unicode(int console);
-diff --git a/include/linux/kd.h b/include/linux/kd.h
+diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
index 87b7cc4..c3de63c 100644
---- a/include/linux/kd.h
-+++ b/include/linux/kd.h
+--- a/include/uapi/linux/kd.h
++++ b/include/uapi/linux/kd.h
@@ -81,6 +81,7 @@ struct unimapinit {
#define K_XLATE 0x01
#define K_MEDIUMRAW 0x02
OpenPOWER on IntegriCloud