Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2009-12-07 11:04:23 +0100
committerMichal Marek <mmarek@suse.cz>2009-12-07 11:04:23 +0100
commit6fa961a804730bf831a627deb2b7c2c7dd054ac0 (patch)
tree7a3bd721c0d8a9dc435f65bf3e807c3a58416bbb
parent7fffe74f9dea4051f405f4240399ccd74eca471f (diff)
parente2da1090d20c603b301659f977ed4ed21a5a3884 (diff)
Merge branch 'master' into SLE11-SP1
-rw-r--r--config.conf1
-rw-r--r--config/i386/debug4
-rw-r--r--config/i386/default4
-rw-r--r--config/i386/desktop4
-rw-r--r--config/i386/pae4
-rw-r--r--config/i386/trace4
-rw-r--r--config/i386/vmi4
-rw-r--r--config/i386/xen4
-rw-r--r--config/ia64/debug4
-rw-r--r--config/ia64/default4
-rw-r--r--config/ia64/trace4
-rw-r--r--config/ppc/default4
-rw-r--r--config/ppc/ppc644
-rw-r--r--config/ppc/ps31
-rw-r--r--config/ppc64/debug4
-rw-r--r--config/ppc64/default4
-rw-r--r--config/ppc64/ppc644
-rw-r--r--config/ppc64/trace3979
-rw-r--r--config/x86_64/debug4
-rw-r--r--config/x86_64/default4
-rw-r--r--config/x86_64/desktop4
-rw-r--r--config/x86_64/trace4
-rw-r--r--config/x86_64/xen4
-rw-r--r--kernel-source.changes83
-rw-r--r--needs_update111
-rw-r--r--patches.apparmor/apparmor-allow-truncation-of-deleted-files51
-rw-r--r--patches.apparmor/apparmor-correct-mapping-of-file-permissions31
-rw-r--r--patches.apparmor/apparmor-ensure-apparmor-enabled-parmater-is-off-if-apparmor-fails-to-initialize39
-rw-r--r--patches.apparmor/apparmor-explicitly-include-header-files-to-allow-apparmor-to-build-on-powerpc42
-rw-r--r--patches.apparmor/apparmor-fix-argument-size-missmatch-on-64-bit-builds54
-rw-r--r--patches.apparmor/apparmor-fix-auditing-of-domain-transitions-to-include-target-profile-information34
-rw-r--r--patches.apparmor/apparmor-fix-build-failure-on-ia6428
-rw-r--r--patches.apparmor/apparmor-fix-c99-violation35
-rw-r--r--patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling36
-rw-r--r--patches.apparmor/apparmor-fix-change_profile-failing-lpn40193156
-rw-r--r--patches.apparmor/apparmor-fix-change_profile-failure76
-rw-r--r--patches.apparmor/apparmor-fix-determination-of-forced-audit-messages68
-rw-r--r--patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly142
-rw-r--r--patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used49
-rw-r--r--patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack52
-rw-r--r--patches.apparmor/apparmor-fix-mapping-of-pux-to-new-internal-permission-format32
-rw-r--r--patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths48
-rw-r--r--patches.apparmor/apparmor-fix-null-pointer-dereference-oops-in-profile-attachment31
-rw-r--r--patches.apparmor/apparmor-fix-oops-after-profile-removal64
-rw-r--r--patches.apparmor/apparmor-fix-oops-in-auditing-of-the-policy-interface-offset39
-rw-r--r--patches.apparmor/apparmor-fix-oops-in-profile-listing-and-display-full-list76
-rw-r--r--patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace67
-rw-r--r--patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds44
-rw-r--r--patches.apparmor/apparmor-fix-operator-precidence-issue-in-as_path_link29
-rw-r--r--patches.apparmor/apparmor-fix-profile-attachment-for-regexp-based-profile-names124
-rw-r--r--patches.apparmor/apparmor-fix-profile-namespace-removal33
-rw-r--r--patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops57
-rw-r--r--patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use35
-rw-r--r--patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths92
-rw-r--r--patches.apparmor/apparmor-missing-unlock23
-rw-r--r--patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem96
-rw-r--r--patches.apparmor/apparmor-return-the-correct-error-codes-on-profile-addition-removal57
-rw-r--r--patches.apparmor/apparmor-revert-reporting-of-create-to-write-permission36
-rw-r--r--patches.apparmor/apparmor-security-module7303
-rw-r--r--patches.apparmor/apparmor-turn-auditing-of-ptrace-on29
-rw-r--r--patches.arch/s390-03-qeth-hs-traffic-analyzer.patch802
-rw-r--r--patches.arch/s390-message-catalog.diff585
-rw-r--r--patches.drivers/lpfc-add-raywire-id33
-rw-r--r--patches.drivers/qla2xxx-8.03.01-k7-update684
-rw-r--r--patches.suse/SoN-29-fix-swap_sync_page-race25
-rw-r--r--patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch1744
-rw-r--r--series.conf47
-rw-r--r--supported.conf63
68 files changed, 17026 insertions, 320 deletions
diff --git a/config.conf b/config.conf
index e4cb806413..3406c170ea 100644
--- a/config.conf
+++ b/config.conf
@@ -49,6 +49,7 @@
+ppc64 ppc64/default
# G5 pSeries
+ppc64 ppc64/ppc64
++ppc64 -syms ppc64/trace
+ppc64 -syms ppc64/debug
# maybe the kernels above were patched to death?
+ppc64 ppc64/vanilla
diff --git a/config/i386/debug b/config/i386/debug
index 2e8b0a2010..07da296715 100644
--- a/config/i386/debug
+++ b/config/i386/debug
@@ -4133,6 +4133,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/default b/config/i386/default
index d1f93e5f72..3efcf5cfd3 100644
--- a/config/i386/default
+++ b/config/i386/default
@@ -4104,6 +4104,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/desktop b/config/i386/desktop
index e5f1ba1c2e..7932cd0294 100644
--- a/config/i386/desktop
+++ b/config/i386/desktop
@@ -3928,6 +3928,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/pae b/config/i386/pae
index e438369226..a7ed7489a4 100644
--- a/config/i386/pae
+++ b/config/i386/pae
@@ -3944,6 +3944,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/trace b/config/i386/trace
index 79a7f7657e..bf5c32b941 100644
--- a/config/i386/trace
+++ b/config/i386/trace
@@ -3944,6 +3944,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/vmi b/config/i386/vmi
index bd7b73c967..08b11248e1 100644
--- a/config/i386/vmi
+++ b/config/i386/vmi
@@ -3944,6 +3944,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/i386/xen b/config/i386/xen
index fbfa3182bc..e05cde2955 100644
--- a/config/i386/xen
+++ b/config/i386/xen
@@ -3783,6 +3783,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ia64/debug b/config/ia64/debug
index 913e250481..eff2dd7db4 100644
--- a/config/ia64/debug
+++ b/config/ia64/debug
@@ -3410,6 +3410,10 @@ CONFIG_USB_BERRY_CHARGE=m
# CONFIG_USB_LED is not set
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ia64/default b/config/ia64/default
index 734066453a..5158f33ca2 100644
--- a/config/ia64/default
+++ b/config/ia64/default
@@ -3391,6 +3391,10 @@ CONFIG_USB_BERRY_CHARGE=m
# CONFIG_USB_LED is not set
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ia64/trace b/config/ia64/trace
index ca41bc2ea8..6471831bb6 100644
--- a/config/ia64/trace
+++ b/config/ia64/trace
@@ -3397,6 +3397,10 @@ CONFIG_USB_BERRY_CHARGE=m
# CONFIG_USB_LED is not set
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc/default b/config/ppc/default
index 2f1ed85ad8..f4ea67c71c 100644
--- a/config/ppc/default
+++ b/config/ppc/default
@@ -3245,6 +3245,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc/ppc64 b/config/ppc/ppc64
index e6bdcb1b4f..4a50c80b61 100644
--- a/config/ppc/ppc64
+++ b/config/ppc/ppc64
@@ -3197,6 +3197,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc/ps3 b/config/ppc/ps3
index 2c099d5435..8a506f0680 100644
--- a/config/ppc/ps3
+++ b/config/ppc/ps3
@@ -940,6 +940,7 @@ CONFIG_USB_SEVSEG=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
diff --git a/config/ppc64/debug b/config/ppc64/debug
index 6838ff8404..70370fef98 100644
--- a/config/ppc64/debug
+++ b/config/ppc64/debug
@@ -3141,6 +3141,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc64/default b/config/ppc64/default
index 6343b99b89..23f7ab2434 100644
--- a/config/ppc64/default
+++ b/config/ppc64/default
@@ -3129,6 +3129,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc64/ppc64 b/config/ppc64/ppc64
index 1b03543549..ad7225e6f0 100644
--- a/config/ppc64/ppc64
+++ b/config/ppc64/ppc64
@@ -3197,6 +3197,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/ppc64/trace b/config/ppc64/trace
new file mode 100644
index 0000000000..11f9d196e8
--- /dev/null
+++ b/config/ppc64/trace
@@ -0,0 +1,3979 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_PPC64=y
+
+#
+# Processor support
+#
+CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
+CONFIG_PPC_BOOK3S=y
+CONFIG_POWER4_ONLY=y
+CONFIG_POWER4=y
+CONFIG_TUNE_CELL=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_VSX=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_64=y
+CONFIG_PPC_MM_SLICES=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=1024
+CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_ARCH_HAS_ILOG2_U64=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_HIBERNATE_64=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+CONFIG_PPC_DCR_MMIO=y
+CONFIG_PPC_DCR=y
+CONFIG_PPC_OF_PLATFORM_PCI=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_SUSE_KERNEL=y
+# CONFIG_ENTERPRISE_SUPPORT is not set
+CONFIG_SPLIT_PACKAGE=y
+# CONFIG_KERNEL_DESKTOP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-ppc64"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_USER_SCHED is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_DEFAULT_VM_DIRTY_RATIO=40
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+CONFIG_SLOW_WORK_DEBUG=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_STOP_MACHINE=y
+CONFIG_UTRACE=y
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+CONFIG_PPC_MSI_BITMAP=y
+
+#
+# Platform support
+#
+CONFIG_PPC_PSERIES=y
+CONFIG_PPC_SPLPAR=y
+CONFIG_EEH=y
+CONFIG_PSERIES_MSI=y
+CONFIG_SCANLOG=m
+CONFIG_LPARCFG=y
+CONFIG_PPC_SMLPAR=y
+CONFIG_CMM=y
+CONFIG_DTL=y
+# CONFIG_PPC_ISERIES is not set
+CONFIG_PPC_PMAC=y
+CONFIG_PPC_PMAC64=y
+CONFIG_PPC_MAPLE=y
+# CONFIG_PPC_PASEMI is not set
+CONFIG_PPC_PS3=y
+
+#
+# PS3 Platform Options
+#
+CONFIG_PS3_ADVANCED=y
+CONFIG_PS3_HTAB_SIZE=20
+# CONFIG_PS3_DYNAMIC_DMA is not set
+CONFIG_PS3_VUART=y
+CONFIG_PS3_PS3AV=y
+CONFIG_PS3_SYS_MANAGER=y
+CONFIG_PS3_STORAGE=m
+CONFIG_PS3_DISK=m
+CONFIG_PS3_ROM=m
+CONFIG_PS3_FLASH=m
+CONFIG_PS3_VRAM=m
+CONFIG_PS3_LPM=m
+CONFIG_PPC_CELL=y
+CONFIG_PPC_CELL_COMMON=y
+CONFIG_PPC_CELL_NATIVE=y
+CONFIG_PPC_IBM_CELL_BLADE=y
+# CONFIG_PPC_CELLEB is not set
+CONFIG_PPC_CELL_QPACE=y
+CONFIG_AXON_MSI=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=m
+CONFIG_SPU_BASE=y
+CONFIG_CBE_RAS=y
+CONFIG_PPC_IBM_CELL_RESETBUTTON=y
+CONFIG_PPC_IBM_CELL_POWERBUTTON=m
+CONFIG_CBE_THERM=m
+CONFIG_CBE_CPUFREQ=m
+CONFIG_CBE_CPUFREQ_PMI_ENABLE=y
+CONFIG_CBE_CPUFREQ_PMI=m
+CONFIG_PPC_PMI=m
+CONFIG_CBE_CPUFREQ_SPU_GOVERNOR=m
+CONFIG_OPROFILE_CELL=y
+# CONFIG_PQ2ADS is not set
+CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+CONFIG_UDBG_RTAS_CONSOLE=y
+CONFIG_XICS=y
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_U3_DART=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=y
+CONFIG_MMIO_NVRAM=y
+CONFIG_MPIC_U3_HT_IRQS=y
+CONFIG_IBMVIO=y
+CONFIG_IBMEBUS=y
+# CONFIG_PPC_MPC106 is not set
+CONFIG_PPC_970_NAP=y
+CONFIG_PPC_INDIRECT_IO=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPU Frequency drivers
+#
+CONFIG_CPU_FREQ_PMAC64=y
+CONFIG_AXON_RAM=m
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_SIMPLE_GPIO=y
+
+#
+# Kernel options
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
+CONFIG_IOMMU_VMERGE=y
+CONFIG_IOMMU_HELPER=y
+# CONFIG_SWIOTLB is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYP_DUMP=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=8
+CONFIG_MAX_ACTIVE_REGIONS=256
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+# CONFIG_SPARSEMEM_VMEMMAP is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
+CONFIG_PPC_HAS_HASH_64K=y
+# CONFIG_PPC_4K_PAGES is not set
+# CONFIG_PPC_16K_PAGES is not set
+CONFIG_PPC_64K_PAGES=y
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_PPC_SUBPAGE_PROT=y
+CONFIG_SCHED_SMT=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+CONFIG_ARCH_WANTS_FREEZER_CONTROL=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+CONFIG_PCIEAER_INJECT=m
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEBUG is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_PCI_STUB=y
+CONFIG_PCI_IOV=y
+# CONFIG_PCCARD is not set
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+CONFIG_HOTPLUG_PCI_RPA=y
+CONFIG_HOTPLUG_PCI_RPA_DLPAR=y
+# CONFIG_HAS_RAPIDIO is not set
+CONFIG_RELOCATABLE=y
+CONFIG_PAGE_OFFSET=0xc000000000000000
+CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+# CONFIG_DEFAULT_BIC is not set
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CONNTRACK_SLP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_IPV6 is not set
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_DCCP=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+# CONFIG_NET_DCCPPROBE is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+CONFIG_SCTP_HMAC_NONE=y
+# CONFIG_SCTP_HMAC_SHA1 is not set
+# CONFIG_SCTP_HMAC_MD5 is not set
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+# CONFIG_RDS_DEBUG is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_EDSA=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_IPX_INTERN=y
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_PHONET=m
+CONFIG_IEEE802154=m
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+CONFIG_DCB=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_DEV=m
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_SJA1000=m
+CONFIG_CAN_SJA1000_PLATFORM=m
+CONFIG_CAN_SJA1000_OF_PLATFORM=m
+CONFIG_CAN_EMS_PCI=m
+CONFIG_CAN_KVASER_PCI=m
+
+#
+# CAN USB interfaces
+#
+CONFIG_CAN_EMS_USB=m
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIUART is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_AF_RXRPC=m
+# CONFIG_AF_RXRPC_DEBUG is not set
+CONFIG_RXKAD=m
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+CONFIG_LIB80211_CRYPT_WEP=m
+CONFIG_LIB80211_CRYPT_CCMP=m
+CONFIG_LIB80211_CRYPT_TKIP=m
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_MAC80211_DEBUGFS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_WIMAX=m
+CONFIG_WIMAX_DEBUG_LEVEL=8
+CONFIG_RFKILL=m
+CONFIG_RFKILL_LEDS=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_NET_9P=m
+CONFIG_NET_9P_VIRTIO=m
+CONFIG_NET_9P_RDMA=m
+# CONFIG_NET_9P_DEBUG is not set
+CONFIG_NETVM=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_TESTS=m
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# 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_MTD_OOPS 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_PHYSMAP=m
+# CONFIG_MTD_PHYSMAP_COMPAT 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_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+CONFIG_MTD_SST25L=m
+# 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_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+CONFIG_MTD_LPDDR=m
+CONFIG_MTD_QINFO_PROBE=m
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_OF_SPI=y
+CONFIG_OF_MDIO=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=m
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=123456
+CONFIG_BLK_DEV_XIP=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+CONFIG_CDROM_PKTCDVD_WCACHE=y
+CONFIG_ATA_OVER_ETH=m
+CONFIG_CIPHER_TWOFISH=m
+CONFIG_VIRTIO_BLK=m
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_PHANTOM=m
+# CONFIG_SGI_IOC4 is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+CONFIG_ICS932S401=m
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_HP_ILO=m
+# CONFIG_ISL29003 is not set
+CONFIG_C2PORT=m
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=m
+CONFIG_EEPROM_AT25=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_MAX6875=m
+CONFIG_EEPROM_93CX6=m
+CONFIG_CB710_CORE=m
+# CONFIG_CB710_DEBUG is not set
+CONFIG_CB710_DEBUG_ASSUMPTIONS=y
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=m
+CONFIG_IDE_GD_ATA=y
+CONFIG_IDE_GD_ATAPI=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_IT8172=m
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_FC_TGT_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_SAS_HOST_SMP=y
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_LOWLEVEL=y
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_AIC94XX=m
+CONFIG_AIC94XX_DEBUG=y
+CONFIG_SCSI_MVSAS=m
+# CONFIG_SCSI_MVSAS_DEBUG is not set
+CONFIG_SCSI_ARCMSR=m
+CONFIG_SCSI_ARCMSR_AER=y
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_MPT2SAS=m
+CONFIG_SCSI_MPT2SAS_MAX_SGE=128
+# CONFIG_SCSI_MPT2SAS_LOGGING is not set
+# CONFIG_SCSI_HPTIOP is not set
+CONFIG_LIBFC=m
+CONFIG_LIBFCOE=m
+CONFIG_FCOE=m
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+CONFIG_SCSI_IBMVSCSI=m
+CONFIG_SCSI_IBMVSCSIS=m
+CONFIG_SCSI_IBMVFC=m
+CONFIG_SCSI_IBMVFC_TRACE=y
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+CONFIG_SCSI_STEX=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+CONFIG_SCSI_IPR=m
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_PMCRAID=m
+CONFIG_SCSI_SRP=m
+CONFIG_SCSI_BFA_FC=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_SCSI_OSD_DPRINT_SENSE=1
+# CONFIG_SCSI_OSD_DEBUG is not set
+CONFIG_ATA=m
+CONFIG_ATA_NONSTANDARD=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_SIL24=m
+CONFIG_ATA_SFF=y
+CONFIG_SATA_SVW=m
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+CONFIG_PATA_AMD=m
+# CONFIG_PATA_ARTOP is not set
+CONFIG_PATA_ATP867X=m
+# CONFIG_PATA_ATIIXP is not set
+CONFIG_PATA_CMD640_PCI=m
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+CONFIG_PATA_MARVELL=m
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+CONFIG_PATA_RDC=m
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+CONFIG_PATA_PDC2027X=m
+CONFIG_PATA_SIL680=m
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+CONFIG_PATA_WINBOND=m
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_SCH=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=m
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_RAID=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_RAID45=m
+CONFIG_DM_UEVENT=y
+CONFIG_FUSION=y
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+CONFIG_IEEE1394=m
+CONFIG_IEEE1394_OHCI1394=m
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_DV1394=m
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_I2O is not set
+CONFIG_MACINTOSH_DRIVERS=y
+CONFIG_ADB=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_SMU=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_THERM_PM72=y
+CONFIG_WINDFARM=y
+CONFIG_WINDFARM_PM81=y
+CONFIG_WINDFARM_PM91=y
+CONFIG_WINDFARM_PM112=y
+CONFIG_WINDFARM_PM121=y
+# CONFIG_PMAC_RACKMETER is not set
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_NATIONAL_PHY=m
+CONFIG_STE10XP=m
+CONFIG_LSI_ET1011C_PHY=m
+CONFIG_FIXED_PHY=y
+CONFIG_MDIO_BITBANG=m
+CONFIG_MDIO_GPIO=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+CONFIG_ENC28J60=m
+# CONFIG_ENC28J60_WRITEVERIFY is not set
+CONFIG_ETHOC=m
+CONFIG_DNET=m
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=m
+CONFIG_TULIP_MWI=y
+CONFIG_TULIP_MMIO=y
+CONFIG_TULIP_NAPI=y
+CONFIG_TULIP_NAPI_HW_MITIGATION=y
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+# CONFIG_HP100 is not set
+CONFIG_IBMVETH=m
+# CONFIG_IBM_NEW_EMAC is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+CONFIG_E100=m
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+CONFIG_R6040=m
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+CONFIG_SMSC9420=m
+# CONFIG_SUNDANCE is not set
+CONFIG_TLAN=m
+CONFIG_KS8842=m
+CONFIG_KS8851=m
+CONFIG_KS8851_MLL=m
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_ATL2=m
+CONFIG_NETDEV_1000=y
+CONFIG_ACENIC=m
+CONFIG_ACENIC_OMIT_TIGON_I=y
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+CONFIG_E1000E=m
+CONFIG_IP1000=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=m
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+# CONFIG_SKGE is not set
+CONFIG_SKY2=m
+# CONFIG_SKY2_DEBUG is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_CNIC=m
+CONFIG_SPIDER_NET=m
+CONFIG_GELIC_NET=m
+CONFIG_GELIC_WIRELESS=y
+# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set
+CONFIG_QLA3XXX=m
+CONFIG_ATL1=m
+CONFIG_ATL1E=m
+CONFIG_ATL1C=y
+CONFIG_JME=m
+CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T1_1G=y
+CONFIG_CHELSIO_T3_DEPENDS=y
+CONFIG_CHELSIO_T3=m
+CONFIG_EHEA=m
+CONFIG_ENIC=m
+CONFIG_IXGBE=m
+CONFIG_IXGBE_DCB=y
+CONFIG_IXGB=m
+CONFIG_S2IO=m
+CONFIG_VXGE=m
+# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
+CONFIG_NIU=m
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
+CONFIG_MLX4_DEBUG=y
+CONFIG_TEHUTI=m
+CONFIG_BNX2X=m
+CONFIG_QLGE=m
+CONFIG_SFC=m
+CONFIG_SFC_MTD=y
+CONFIG_BE2NET=m
+CONFIG_TR=y
+CONFIG_IBMOL=m
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+CONFIG_WLAN=y
+CONFIG_WLAN_PRE80211=y
+# CONFIG_STRIP is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SPI=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_LIBERTAS_THINFIRM_USB=m
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+CONFIG_AT76C50X_USB=m
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_RTL8180=m
+CONFIG_RTL8187=m
+CONFIG_RTL8187_LEDS=y
+CONFIG_ADM8211=m
+CONFIG_MAC80211_HWSIM=m
+CONFIG_MWL8K=m
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+CONFIG_P54_PCI=m
+CONFIG_P54_SPI=m
+CONFIG_P54_LEDS=y
+CONFIG_ATH_COMMON=m
+CONFIG_ATH5K=m
+# CONFIG_ATH5K_DEBUG is not set
+CONFIG_ATH9K=m
+# CONFIG_ATH9K_DEBUG is not set
+CONFIG_AR9170_USB=m
+CONFIG_AR9170_LEDS=y
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_LIBIPW=m
+# CONFIG_LIBIPW_DEBUG is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLWIFI_LEDS=y
+CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
+# CONFIG_IWLWIFI_DEBUG is not set
+CONFIG_IWLAGN=m
+CONFIG_IWL4965=y
+CONFIG_IWL5000=y
+CONFIG_IWL3945=m
+CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
+# CONFIG_HOSTAP is not set
+CONFIG_B43=m
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+CONFIG_B43_PHY_LP=y
+CONFIG_B43_LEDS=y
+CONFIG_B43_HWRNG=y
+# CONFIG_B43_DEBUG is not set
+CONFIG_B43LEGACY=m
+CONFIG_B43LEGACY_PCI_AUTOSELECT=y
+CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
+CONFIG_B43LEGACY_LEDS=y
+CONFIG_B43LEGACY_HWRNG=y
+# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_B43LEGACY_DMA=y
+CONFIG_B43LEGACY_PIO=y
+CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
+# CONFIG_B43LEGACY_DMA_MODE is not set
+# CONFIG_B43LEGACY_PIO_MODE is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_RT2X00=m
+CONFIG_RT2400PCI=m
+CONFIG_RT2500PCI=m
+CONFIG_RT61PCI=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2X00_LIB_PCI=m
+CONFIG_RT2X00_LIB_USB=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_HT=y
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+# CONFIG_RT2X00_LIB_DEBUGFS is not set
+# CONFIG_RT2X00_DEBUG is not set
+CONFIG_HERMES=m
+CONFIG_HERMES_CACHE_FW_ON_INIT=y
+CONFIG_APPLE_AIRPORT=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_WL12XX=m
+CONFIG_WL1251=m
+CONFIG_WL1251_SPI=m
+CONFIG_WL1271=m
+
+#
+# WiMAX Wireless Broadband devices
+#
+CONFIG_WIMAX_I2400M=m
+
+#
+# Enable MMC support to see WiMAX SDIO drivers
+#
+CONFIG_WIMAX_I2400M_USB=m
+CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_HSO=m
+CONFIG_USB_NET_INT51X1=m
+CONFIG_USB_CDC_PHONET=m
+# CONFIG_WAN is not set
+CONFIG_IEEE802154_DRIVERS=m
+CONFIG_IEEE802154_FAKEHARD=m
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOL2TP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+CONFIG_VIRTIO_NET=m
+CONFIG_ISDN=y
+CONFIG_ISDN_I4L=m
+CONFIG_MISDN=m
+CONFIG_MISDN_DSP=m
+CONFIG_MISDN_L1OIP=m
+
+#
+# mISDN hardware drivers
+#
+CONFIG_MISDN_HFCPCI=m
+CONFIG_MISDN_HFCMULTI=m
+CONFIG_MISDN_HFCUSB=m
+CONFIG_MISDN_AVMFRITZ=m
+CONFIG_MISDN_SPEEDFAX=m
+CONFIG_MISDN_INFINEON=m
+CONFIG_MISDN_W6692=m
+CONFIG_MISDN_NETJET=m
+CONFIG_MISDN_IPAC=m
+CONFIG_MISDN_ISAR=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+CONFIG_ISDN_PPP_BSDCOMP=m
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_DEBUG=y
+
+#
+# HiSax PCMCIA card service modules
+#
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+
+#
+# Active cards
+#
+CONFIG_HYSDN=m
+# CONFIG_HYSDN_CAPI is not set
+CONFIG_ISDN_HDLC=m
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_CAPI_TRACE=y
+# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+CONFIG_GIGASET_M101=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ADP5588=m
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_QT2160=m
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_MATRIX=m
+CONFIG_KEYBOARD_LM8323=m
+CONFIG_KEYBOARD_MAX7359=m
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_KEYBOARD_OPENCORES=m
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_TWL4030=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_PS2_SENTELIC=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_BCM5974=m
+# CONFIG_MOUSE_VSXXXAA is not set
+CONFIG_MOUSE_GPIO=m
+CONFIG_MOUSE_SYNAPTICS_I2C=m
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_JOYSTICK_WALKERA0701=m
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=m
+CONFIG_TABLET_USB_AIPTEK=m
+CONFIG_TABLET_USB_GTCO=m
+CONFIG_TABLET_USB_KBTAB=m
+CONFIG_TABLET_USB_WACOM=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_AD7877=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_DA9034=m
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_TOUCHSCREEN_FUJITSU=m
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+CONFIG_TOUCHSCREEN_ELOUSB=m
+CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_MCS5000=m
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+CONFIG_TOUCHSCREEN_INEXIO=m
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_UCB1400=m
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
+CONFIG_TOUCHSCREEN_USB_EGALAX=y
+CONFIG_TOUCHSCREEN_USB_PANJIT=y
+CONFIG_TOUCHSCREEN_USB_3M=y
+CONFIG_TOUCHSCREEN_USB_ITM=y
+CONFIG_TOUCHSCREEN_USB_ETURBO=y
+CONFIG_TOUCHSCREEN_USB_GUNZE=y
+CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
+CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
+CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
+CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
+CONFIG_TOUCHSCREEN_USB_GOTOP=y
+CONFIG_TOUCHSCREEN_USB_JASTEC=y
+CONFIG_TOUCHSCREEN_USB_E2I=y
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_TSC2007=m
+CONFIG_TOUCHSCREEN_PCAP=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_ATI_REMOTE=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_CM109=m
+CONFIG_INPUT_TWL4030_PWRBUTTON=m
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+CONFIG_INPUT_PCAP=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_XILINX_XPS_PS2=m
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_FM801 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_NOZOMI=m
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_CONSOLE_POLL=y
+CONFIG_SERIAL_PMACZILOG=y
+# CONFIG_SERIAL_PMACZILOG_TTYS is not set
+CONFIG_SERIAL_PMACZILOG_CONSOLE=y
+CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
+CONFIG_SERIAL_OF_PLATFORM=m
+CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_IRQ=y
+CONFIG_HVC_CONSOLE=y
+CONFIG_HVC_RTAS=y
+# CONFIG_HVC_UDBG is not set
+CONFIG_VIRTIO_CONSOLE=m
+CONFIG_HVCS=m
+CONFIG_IBM_BSR=m
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_PANIC_EVENT=y
+# CONFIG_IPMI_PANIC_STRING is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=4096
+# CONFIG_HANGCHECK_TIMER is not set
+CONFIG_TCG_TPM=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_DEVPORT=y
+CONFIG_CRASHER=m
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# Mac SMBus host controller drivers
+#
+CONFIG_I2C_POWERMAC=y
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_OCORES=m
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+CONFIG_I2C_TINY_USB=m
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_STUB=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=m
+CONFIG_SENSORS_TSL2550=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_BUTTERFLY=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_LM70_LLP=m
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_TLE62X0=m
+
+#
+# PPS support
+#
+CONFIG_PPS=m
+# CONFIG_PPS_DEBUG is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_XILINX=y
+
+#
+# I2C GPIO expanders:
+#
+CONFIG_GPIO_MAX732X=m
+CONFIG_GPIO_PCA953X=m
+CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_TWL4030=m
+
+#
+# PCI GPIO expanders:
+#
+CONFIG_GPIO_LANGWELL=y
+
+#
+# SPI GPIO expanders:
+#
+CONFIG_GPIO_MAX7301=m
+CONFIG_GPIO_MCP23S08=m
+CONFIG_GPIO_MC33880=m
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_GPIO_UCB1400=y
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_MATROX is not set
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_GPIO=m
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+CONFIG_W1_SLAVE_DS2431=m
+# CONFIG_W1_SLAVE_DS2433 is not set
+CONFIG_W1_SLAVE_DS2760=m
+CONFIG_W1_SLAVE_BQ27000=m
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_PDA_POWER=m
+CONFIG_BATTERY_DS2760=m
+CONFIG_BATTERY_DS2782=m
+CONFIG_BATTERY_BQ27x00=m
+CONFIG_BATTERY_DA9030=m
+CONFIG_BATTERY_MAX17040=m
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+CONFIG_SENSORS_AD7414=m
+CONFIG_SENSORS_AD7418=m
+CONFIG_SENSORS_ADCXX=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ADT7462=m
+CONFIG_SENSORS_ADT7470=m
+CONFIG_SENSORS_ADT7473=m
+CONFIG_SENSORS_ADT7475=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_I5K_AMB=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_F71882FG=m
+CONFIG_SENSORS_F75375S=m
+CONFIG_SENSORS_G760A=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IBMAEM=m
+CONFIG_SENSORS_IBMPEX=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM70=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_LM93=m
+CONFIG_SENSORS_LTC4215=m
+CONFIG_SENSORS_LTC4245=m
+CONFIG_SENSORS_LM95241=m
+CONFIG_SENSORS_MAX1111=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SHT15=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_DME1737=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_ADS7828=m
+CONFIG_SENSORS_THMC50=m
+CONFIG_SENSORS_TMP401=m
+CONFIG_SENSORS_TMP421=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83L786NG=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_LIS3_SPI=m
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_TWL4030_WATCHDOG=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+CONFIG_SSB_B43_PCI_BRIDGE=y
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=m
+# CONFIG_MFD_SM501 is not set
+CONFIG_HTC_PASIC3=m
+CONFIG_UCB1400_CORE=m
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_MFD_TMIO is not set
+CONFIG_PMIC_DA903X=y
+CONFIG_MFD_WM8400=m
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+CONFIG_MFD_MC13783=m
+CONFIG_AB3100_CORE=m
+CONFIG_AB3100_OTP=m
+CONFIG_EZX_PCAP=y
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=m
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_MT2131=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_MEDIA_TUNER_MXL5007T=m
+CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=m
+CONFIG_VIDEOBUF_VMALLOC=m
+CONFIG_VIDEOBUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=m
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_M52790=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_VP27SMPX=m
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_MT9V011=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA717X=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+CONFIG_VIDEO_VIVI=m
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+# CONFIG_VIDEO_W9966 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+CONFIG_VIDEO_CX23885=m
+CONFIG_VIDEO_AU0828=m
+CONFIG_VIDEO_IVTV=m
+CONFIG_VIDEO_FB_IVTV=m
+CONFIG_VIDEO_CX18=m
+CONFIG_VIDEO_SAA7164=m
+CONFIG_VIDEO_CAFE_CCIC=m
+CONFIG_SOC_CAMERA=m
+CONFIG_SOC_CAMERA_MT9M001=m
+CONFIG_SOC_CAMERA_MT9M111=m
+CONFIG_SOC_CAMERA_MT9T031=m
+CONFIG_SOC_CAMERA_MT9V022=m
+CONFIG_SOC_CAMERA_TW9910=m
+CONFIG_SOC_CAMERA_PLATFORM=m
+CONFIG_SOC_CAMERA_OV772X=m
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
+CONFIG_USB_GL860=m
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
+CONFIG_USB_GSPCA_JEILINJ=m
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_PAC207=m
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_STK014=m
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_ZC3XX=m
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_EM28XX_ALSA=m
+CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_VIDEO_CX231XX=m
+CONFIG_VIDEO_CX231XX_ALSA=m
+CONFIG_VIDEO_CX231XX_DVB=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
+CONFIG_USB_ZR364XX=m
+CONFIG_USB_STKWEBCAM=m
+CONFIG_USB_S2255=m
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+CONFIG_I2C_SI4713=m
+CONFIG_RADIO_SI4713=m
+CONFIG_USB_DSBR=m
+CONFIG_RADIO_SI470X=y
+CONFIG_USB_SI470X=m
+CONFIG_I2C_SI470X=m
+CONFIG_USB_MR800=m
+CONFIG_RADIO_TEA5764=m
+CONFIG_DVB_MAX_ADAPTERS=8
+CONFIG_DVB_DYNAMIC_MINORS=y
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_TTPCI_EEPROM=m
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET_CORE=m
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+CONFIG_DVB_USB_DW2102=m
+CONFIG_DVB_USB_CINERGY_T2=m
+CONFIG_DVB_USB_ANYSEE=m
+CONFIG_DVB_USB_DTV5100=m
+CONFIG_DVB_USB_AF9015=m
+CONFIG_DVB_USB_CE6230=m
+CONFIG_DVB_USB_FRIIO=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_SMS_SIANO_MDTV=m
+
+#
+# Siano module components
+#
+CONFIG_SMS_USB_DRV=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported SDMC DM1105 Adapters
+#
+CONFIG_DVB_DM1105=m
+
+#
+# Supported FireWire (IEEE 1394) Adapters
+#
+CONFIG_DVB_FIREDTV=m
+CONFIG_DVB_FIREDTV_IEEE1394=y
+CONFIG_DVB_FIREDTV_INPUT=y
+
+#
+# Supported Earthsoft PT1 Adapters
+#
+CONFIG_DVB_PT1=m
+
+#
+# Supported DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+CONFIG_DVB_STB0899=m
+CONFIG_DVB_STB6100=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_ZL10039=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_STV0288=m
+CONFIG_DVB_STB6000=m
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_STV6110=m
+CONFIG_DVB_STV0900=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_TDA8261=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TUNER_CX24113=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+CONFIG_DVB_CX24116=m
+CONFIG_DVB_SI21XX=m
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+CONFIG_DVB_AF9013=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+CONFIG_DVB_DIB8000=m
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DVB_LGS8GL5=m
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
+CONFIG_VGA_ARB=y
+CONFIG_DRM=m
+CONFIG_DRM_KMS_HELPER=m
+CONFIG_DRM_TTM=m
+# CONFIG_DRM_TDFX is not set
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
+CONFIG_VGASTATE=y
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_SVGALIB=m
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_UVESA=m
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=y
+CONFIG_FB_NVIDIA_I2C=y
+# CONFIG_FB_NVIDIA_DEBUG is not set
+CONFIG_FB_NVIDIA_BACKLIGHT=y
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+CONFIG_FB_VT8623=m
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_ARK=m
+CONFIG_FB_PM3=m
+CONFIG_FB_CARMINE=m
+CONFIG_FB_CARMINE_DRAM_EVAL=y
+# CONFIG_CARMINE_DRAM_CUSTOM is not set
+CONFIG_FB_TMIO=m
+CONFIG_FB_TMIO_ACCELL=y
+CONFIG_FB_IBM_GXT4500=y
+CONFIG_FB_PS3=y
+CONFIG_FB_PS3_DEFAULT_SIZE_M=9
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FB_METRONOME=m
+CONFIG_FB_MB862XX=m
+CONFIG_FB_MB862XX_PCI_GDC=y
+CONFIG_FB_BROADSHEET=m
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_LMS283GF05=m
+CONFIG_LCD_LTV350QV=m
+CONFIG_LCD_ILI9320=m
+CONFIG_LCD_TDO24M=m
+CONFIG_LCD_VGG2432A4=m
+CONFIG_LCD_PLATFORM=m
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=m
+CONFIG_BACKLIGHT_DA903X=m
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=m
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_FB_LOGO_EXTRA=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Bootsplash configuration
+#
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_PCM_XRUN_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_RAWMIDI_SEQ=m
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_MTS64=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_PORTMAN2X4=m
+CONFIG_SND_AC97_POWER_SAVE=y
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+CONFIG_SND_AW2=m
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+CONFIG_SND_OXYGEN_LIB=m
+CONFIG_SND_OXYGEN=m
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_CTXFI=m
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+CONFIG_SND_INDIGOIOX=m
+CONFIG_SND_INDIGODJX=m
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+CONFIG_SND_HIFIER=m
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+CONFIG_SND_LX6464ES=m
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+CONFIG_SND_VIRTUOSO=m
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_PPC=y
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+CONFIG_SND_PS3=m
+CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
+
+#
+# ALSA PPC devices
+#
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+CONFIG_LOGITECH_FF=y
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_ZEROPLUS=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=m
+CONFIG_USB_WUSB=m
+CONFIG_USB_WUSB_CBAF=m
+# CONFIG_USB_WUSB_CBAF_DEBUG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_C67X00_HCD=m
+CONFIG_USB_XHCI_HCD=m
+# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+CONFIG_USB_OXU210HP_HCD=m
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_ISP1760_HCD=m
+CONFIG_USB_ISP1362_HCD=m
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_U132_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_WHCI_HCD=m
+CONFIG_USB_HWA_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_ONETOUCH=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_IUU=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_MOTOROLA=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_QUALCOMM=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_SIEMENS_MPI=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_SYMBOL=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_OPTICON=m
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_BERRY_CHARGE=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+CONFIG_USB_ISIGHTFW=m
+CONFIG_USB_VST=m
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_UWB=m
+CONFIG_UWB_HWA=m
+CONFIG_UWB_WHCI=m
+CONFIG_UWB_WLP=m
+CONFIG_UWB_I1480U=m
+CONFIG_UWB_I1480U_WLP=m
+# CONFIG_MMC is not set
+CONFIG_MEMSTICK=m
+# CONFIG_MEMSTICK_DEBUG is not set
+
+#
+# MemoryStick drivers
+#
+# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
+CONFIG_MSPRO_BLOCK=m
+
+#
+# MemoryStick Host Controller Drivers
+#
+CONFIG_MEMSTICK_TIFM_MS=m
+CONFIG_MEMSTICK_JMICRON_38X=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_PCA9532=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+CONFIG_LEDS_GPIO_OF=y
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_DA903X=m
+CONFIG_LEDS_DAC124S085=m
+CONFIG_LEDS_BD2802=m
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_USER_MEM=y
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPATH=m
+CONFIG_INFINIBAND_EHCA=m
+CONFIG_INFINIBAND_AMSO1100=m
+# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
+CONFIG_INFINIBAND_CXGB3=m
+# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_INFINIBAND_NES=m
+# CONFIG_INFINIBAND_NES_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_CM=y
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_CELL=m
+CONFIG_EDAC_AMD8131=m
+CONFIG_EDAC_AMD8111=m
+CONFIG_EDAC_CPC925=m
+# CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_AUXDISPLAY=y
+# CONFIG_KS0108 is not set
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_UIO_SMX=m
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+
+#
+# TI VLYNQ
+#
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+CONFIG_ET131X=m
+# CONFIG_ET131X_DEBUG is not set
+# CONFIG_VIDEO_GO7007 is not set
+CONFIG_VIDEO_CX25821=m
+CONFIG_VIDEO_CX25821_ALSA=m
+CONFIG_USB_IP_COMMON=m
+CONFIG_USB_IP_VHCI_HCD=m
+CONFIG_USB_IP_HOST=m
+CONFIG_W35UND=m
+# CONFIG_PRISM2_USB is not set
+CONFIG_ECHO=m
+CONFIG_POCH=m
+# CONFIG_OTUS is not set
+# CONFIG_COMEDI is not set
+CONFIG_ASUS_OLED=m
+CONFIG_PANEL=m
+CONFIG_PANEL_PARPORT=0
+CONFIG_PANEL_PROFILE=5
+# CONFIG_PANEL_CHANGE_MESSAGE is not set
+CONFIG_ALTERA_PCIE_CHDMA=m
+CONFIG_RTL8187SE=m
+CONFIG_RTL8192SU=m
+CONFIG_RTL8192E=m
+CONFIG_INPUT_MIMIO=m
+CONFIG_TRANZPORT=m
+
+#
+# Android
+#
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+CONFIG_INPUT_GPIO=m
+CONFIG_DST=m
+# CONFIG_DST_DEBUG is not set
+CONFIG_POHMELFS=m
+# CONFIG_POHMELFS_DEBUG is not set
+CONFIG_POHMELFS_CRYPTO=y
+CONFIG_B3DFG=m
+CONFIG_IDE_PHISON=m
+CONFIG_PLAN9AUTH=m
+CONFIG_LINE6_USB=m
+# CONFIG_DRM_RADEON_KMS is not set
+CONFIG_USB_SERIAL_QUATECH2=m
+CONFIG_USB_SERIAL_QUATECH_USB2=m
+CONFIG_VT6655=m
+CONFIG_VT6656=m
+CONFIG_FB_UDL=m
+CONFIG_VME_BUS=m
+
+#
+# VME Bridge Drivers
+#
+CONFIG_VME_CA91CX42=m
+
+#
+# VME Device Drivers
+#
+CONFIG_VME_USER=m
+
+#
+# RAR Register Driver
+#
+CONFIG_RAR_REGISTER=m
+CONFIG_DX_SEP=m
+CONFIG_IIO=m
+CONFIG_IIO_RING_BUFFER=y
+CONFIG_IIO_SW_RING=m
+CONFIG_IIO_TRIGGER=y
+
+#
+# Accelerometers
+#
+CONFIG_KXSD9=m
+CONFIG_LIS3L02DQ=m
+CONFIG_SCA3000=m
+
+#
+# Analog to digital convertors
+#
+CONFIG_MAX1363=m
+
+#
+# Light sensors
+#
+CONFIG_TSL2561=m
+
+#
+# Triggers - standalone
+#
+CONFIG_IIO_GPIO_TRIGGER=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_DEFAULTS_TO_BARRIERS_ENABLED=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_NFS4ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+CONFIG_JBD2_DEBUG=y
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_DEFAULTS_TO_BARRIERS_ENABLED=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+CONFIG_JFS_STATISTICS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FS_NFS4ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_DMAPI=m
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+# CONFIG_XFS_DEBUG is not set
+CONFIG_GFS2_FS=m
+# CONFIG_GFS2_FS_LOCKING_DLM is not set
+CONFIG_OCFS2_FS=m
+CONFIG_OCFS2_FS_O2CB=m
+CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+CONFIG_OCFS2_FS_STATS=y
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+# CONFIG_OCFS2_DEBUG_FS is not set
+CONFIG_OCFS2_FS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_DMAPI=m
+# CONFIG_DMAPI_DEBUG is not set
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=m
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+CONFIG_FSCACHE_OBJECT_LIST=y
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=m
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+CONFIG_ROMFS_BACKED_BY_BOTH=y
+CONFIG_ROMFS_ON_BLOCK=y
+CONFIG_ROMFS_ON_MTD=y
+# CONFIG_SYSV_FS is not set
+CONFIG_UFS_FS=m
+CONFIG_UFS_FS_WRITE=y
+# CONFIG_UFS_DEBUG is not set
+CONFIG_EXOFS_FS=m
+# CONFIG_EXOFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_SUNRPC_XPRT_RDMA=m
+CONFIG_SUNRPC_SWAP=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_EXPERIMENTAL=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+# CONFIG_9P_FSCACHE is not set
+# CONFIG_NOVFS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_DLM_DEBUG=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=0
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+CONFIG_DEBUG_BLOCK_EXT_DEVT=y
+CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+CONFIG_LKDTM=m
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+# CONFIG_FAIL_MAKE_REQUEST is not set
+CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+CONFIG_RING_BUFFER_BENCHMARK=m
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_KGDB=y
+CONFIG_KGDB_SERIAL_CONSOLE=m
+# CONFIG_KGDB_TESTS is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_HCALL_STATS is not set
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+CONFIG_XMON=y
+# CONFIG_XMON_DEFAULT is not set
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITYFS=y
+CONFIG_SECURITY_DEFAULT="apparmor"
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+CONFIG_SECURITY_PATH=y
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_SECURITY_APPARMOR=y
+CONFIG_SECURITY_APPARMOR_NETWORK=y
+CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_APPARMOR_DISABLE=y
+CONFIG_KEYS_COMPAT=y
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
+# CONFIG_PPC_CLOCK is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_VIRTIO=m
+CONFIG_VIRTIO_RING=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
diff --git a/config/x86_64/debug b/config/x86_64/debug
index 260be78015..5bbc0afed6 100644
--- a/config/x86_64/debug
+++ b/config/x86_64/debug
@@ -3878,6 +3878,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/x86_64/default b/config/x86_64/default
index 000b2a92f6..4df93c63aa 100644
--- a/config/x86_64/default
+++ b/config/x86_64/default
@@ -3869,6 +3869,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/x86_64/desktop b/config/x86_64/desktop
index 5bc47fa655..25694b2494 100644
--- a/config/x86_64/desktop
+++ b/config/x86_64/desktop
@@ -3853,6 +3853,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/x86_64/trace b/config/x86_64/trace
index c58a706e68..52b76614e9 100644
--- a/config/x86_64/trace
+++ b/config/x86_64/trace
@@ -3866,6 +3866,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/config/x86_64/xen b/config/x86_64/xen
index 8f71144658..4c9aa4936e 100644
--- a/config/x86_64/xen
+++ b/config/x86_64/xen
@@ -3726,6 +3726,10 @@ CONFIG_USB_BERRY_CHARGE=m
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
CONFIG_USB_APPLEDISPLAY=m
diff --git a/kernel-source.changes b/kernel-source.changes
index 47162b06b2..abe4d965bc 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -1,4 +1,87 @@
-------------------------------------------------------------------
+Mon Dec 7 10:57:41 CET 2009 - hare@suse.de
+
+- patches.drivers/lpfc-add-raywire-id: Add missing PCI-ID to lpfc.
+
+-------------------------------------------------------------------
+Sat Dec 5 01:39:16 CET 2009 - tonyj@suse.de
+
+- config.conf: add trace flavor for ppc64 (fate# 307051)
+- Update config files.
+
+-------------------------------------------------------------------
+Fri Dec 4 21:24:27 CET 2009 - jeffm@suse.com
+
+- Split apparmor.diff out into separate patches to align more
+ closely with the upstream AppArmor 2.4 repo.
+- patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling:
+ AppArmor: Fix cap audit_caching preemption disabling.
+- patches.apparmor/apparmor-fix-change_profile-failing-lpn401931:
+ AppArmor: Fix change_profile failing lpn401931.
+- patches.apparmor/apparmor-fix-change_profile-failure: AppArmor:
+ Fix change_profile failure.
+- patches.apparmor/apparmor-fix-determination-of-forced-audit-messages:
+ AppArmor: Fix determination of forced AUDIT messages..
+- patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly:
+ AppArmor: fix failure to audit change_hat correctly.
+- patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used:
+ AppArmor: Fix file auditing when quiet is used.
+- patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack:
+ AppArmor: Fix leak when profile transition table fails unpack.
+- patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths:
+ AppArmor: Fix mediation of created paths that look like
+ "deleted" paths.
+- patches.apparmor/apparmor-fix-oops-after-profile-removal:
+ AppArmor: Fix oops after profile removal.
+- patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace:
+ AppArmor: Fix oops when auditing the addition of profile
+ namespace.
+- patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds:
+ AppArmor: Fix Oops when in apparmor_bprm_set_creds.
+- patches.apparmor/apparmor-fix-profile-namespace-removal:
+ AppArmor: Fix profile namespace removal..
+- patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops:
+ AppArmor: Fix refcounting bug causing leak of creds and oops.
+- patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths:
+ AppArmor: Fully close race condition for deleted paths.
+- patches.apparmor/apparmor-missing-unlock: AppArmor: Add missing
+ unlock to next_profile.
+- patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem:
+ AppArmor: Policy load and replacement can fail to alloc mem.
+- patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use:
+ AppArmor: Fix security_ops->task_setrlimit API use.
+
+-------------------------------------------------------------------
+Fri Dec 4 17:58:54 CET 2009 - gregkh@suse.de
+
+- Update config files.
+- patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch:
+ Revert "USB: remove phidget drivers from kernel tree.".
+
+-------------------------------------------------------------------
+Fri Dec 4 16:12:43 CET 2009 - jjolly@suse.de
+
+- patches.arch/s390-message-catalog.diff: Updated patch
+ (bnc#549193,FATE#306999,LTC#57210).
+
+-------------------------------------------------------------------
+Fri Dec 4 16:08:50 CET 2009 - mmarek@suse.cz
+
+- supported.conf: Update wireless drivers.
+
+-------------------------------------------------------------------
+Fri Dec 4 15:57:48 CET 2009 - jjolly@suse.de
+
+- patches.arch/s390-03-qeth-hs-traffic-analyzer.patch: qeth:
+ HiperSockets Network Traffic Analyzer (bnc#560674).
+
+-------------------------------------------------------------------
+Fri Dec 4 15:28:10 CET 2009 - hare@suse.de
+
+- patches.drivers/qla2xxx-8.03.01-k7-update: qla2xxx driver
+ update to 8.03.01-k7 (bnc#560415).
+
+-------------------------------------------------------------------
Fri Dec 4 14:35:02 CET 2009 - mmarek@suse.cz
- rpm/package-descriptions: Add description for kernel-vmi.
diff --git a/needs_update b/needs_update
index f3858327a8..3ce793b87c 100644
--- a/needs_update
+++ b/needs_update
@@ -265,7 +265,6 @@ List of patches to forward-port or drop.
+hare patches.suse/genhd-disk-ro-uevents
+hare patches.suse/rq-based-multipath
+hare patches.suse/scsi-check-removed-device-for-offline
-+hmacht patches.arch/acpi-bay-remove-useless-code.patch
+hmacht patches.arch/acpi-dock-don-t-eval-_sta-on-every-show_docked-sysfs-read.patch
+hmacht patches.arch/acpi-dock-Fix-duplicate-notification-handler-register.patch
+hmacht patches.arch/acpi-dock-_LCK-support-for-dock.patch
@@ -293,117 +292,7 @@ List of patches to forward-port or drop.
+jblunck patches.trace/tracepoints-use-table-size-macro.patch
+jblunck patches.trace/tracepoints.patch
+jbohac patches.suse/netfilter-ipv4options
-+jeffm patches.apparmor/add-path_permission.diff
-+jeffm patches.apparmor/add-security_path_permission
-+jeffm patches.apparmor/apparmor-2.6.25.diff
-+jeffm patches.apparmor/apparmor-audit.diff
-+jeffm patches.apparmor/apparmor-network.diff
-+jeffm patches.apparmor/apparmor-path_permission
-+jeffm patches.apparmor/apparmor-ptrace-2.6.27.diff
-+jeffm patches.apparmor/apparmor-rlimits.diff
-+jeffm patches.apparmor/d_namespace_path.diff
-+jeffm patches.apparmor/do_path_lookup-nameidata.diff
-+jeffm patches.apparmor/export-security_inode_permission-for-aufs
-+jeffm patches.apparmor/file-handle-ops.diff
-+jeffm patches.apparmor/fix-complain.diff
-+jeffm patches.apparmor/fix-deleted-leak.diff
-+jeffm patches.apparmor/fix-security-param.diff
-+jeffm patches.apparmor/fork-tracking.diff
-+jeffm patches.apparmor/fsetattr-reintro-ATTR_FILE.diff
-+jeffm patches.apparmor/fsetattr-restore-ia_file.diff
-+jeffm patches.apparmor/fsetattr.diff
-+jeffm patches.apparmor/remove_suid.diff
-+jeffm patches.apparmor/security-create.diff
-+jeffm patches.apparmor/security-getxattr.diff
-+jeffm patches.apparmor/security-link.diff
-+jeffm patches.apparmor/security-listxattr.diff
-+jeffm patches.apparmor/security-mkdir.diff
-+jeffm patches.apparmor/security-mknod.diff
-+jeffm patches.apparmor/security-readlink.diff
-+jeffm patches.apparmor/security-removexattr.diff
-+jeffm patches.apparmor/security-rename.diff
-+jeffm patches.apparmor/security-rmdir.diff
-+jeffm patches.apparmor/security-setattr.diff
-+jeffm patches.apparmor/security-setxattr.diff
-+jeffm patches.apparmor/security-symlink.diff
-+jeffm patches.apparmor/security-unlink.diff
-+jeffm patches.apparmor/security-xattr-file.diff
-+jeffm patches.apparmor/sysctl-pathname.diff
-+jeffm patches.apparmor/vfs-getxattr.diff
-+jeffm patches.apparmor/vfs-link.diff
-+jeffm patches.apparmor/vfs-listxattr.diff
-+jeffm patches.apparmor/vfs-mkdir.diff
-+jeffm patches.apparmor/vfs-mknod.diff
-+jeffm patches.apparmor/vfs-notify_change.diff
-+jeffm patches.apparmor/vfs-removexattr.diff
-+jeffm patches.apparmor/vfs-rename.diff
-+jeffm patches.apparmor/vfs-rmdir.diff
-+jeffm patches.apparmor/vfs-setxattr.diff
-+jeffm patches.apparmor/vfs-symlink.diff
-+jeffm patches.apparmor/vfs-unlink.diff
-+jeffm patches.arch/acpi-bay-remove-from-makefile
-+jeffm patches.arch/thinkpad_acpi-hotkey-notify-fix
-+jeffm patches.drivers/otus-usb_complete_t-fixups
-+jeffm patches.drivers/rtl8187se-fix-iw_handler-api-usage
-+jeffm patches.drivers/w35-ieee80211_ops-api-fixups
-+jeffm patches.fixes/fix-nr_uninterruptible-accounting-of-frozen-tasks
-+jeffm patches.fixes/hfs-corrupt-extent-tree-mount-oops-fix
-+jeffm patches.fixes/hpilo-open-close-fix
+jeffm patches.fixes/initialize-dev-power-entry
-+jeffm patches.fixes/iwlagn-debug-build-fix
-+jeffm patches.fixes/kdb-Commited_AS-fix
-+jeffm patches.fixes/kdb-bb_all-fixes
-+jeffm patches.fixes/kdb-fix-stack-overflow.patch
-+jeffm patches.fixes/kdb-kdump.diff
-+jeffm patches.fixes/kdb-oops-panic.diff
-+jeffm patches.fixes/no-sys_uv-on-non-uv-systems
-+jeffm patches.fixes/reiserfs-commit-ids-unsigned-ints
-+jeffm patches.fixes/reiserfs-debug-1036
-+jeffm patches.fixes/reiserfs-error-buffer-locking
-+jeffm patches.fixes/reiserfs-prealloc-fix
-+jeffm patches.fixes/reiserfs-varargs-fix
-+jeffm patches.fixes/sn-irq-affinity
-+jeffm patches.fixes/uv_zalias_support
-+jeffm patches.fixes/video-vesa-bad-mode
-+jeffm patches.rpmify/8250_pci-constify-quirk-setup
-+jeffm patches.suse/SoN-20-netvm-reserve-inet.patch-fix
-+jeffm patches.suse/kdb-resolve-uv-conflict.diff
-+jeffm patches.suse/kdb-serial-8250
-+jeffm patches.suse/novfs-gregorian-day-fix
-+jeffm patches.suse/novfs-patch-2.6.27
-+jeffm patches.suse/reiserfs-add-reiserfs_error.diff
-+jeffm patches.suse/reiserfs-buffer-info-for-balance.diff
-+jeffm patches.suse/reiserfs-clean-up-xattrs
-+jeffm patches.suse/reiserfs-cleanup-path-funcs.diff
-+jeffm patches.suse/reiserfs-consistent-messages.diff
-+jeffm patches.suse/reiserfs-eliminate-per-super-xattr-lock.diff
-+jeffm patches.suse/reiserfs-inode-init
-+jeffm patches.suse/reiserfs-journaled-xattrs.diff
-+jeffm patches.suse/reiserfs-kill-xattr-readdir.diff
-+jeffm patches.suse/reiserfs-make-per-inode-xattr-locking-more-fine-grained.diff
-+jeffm patches.suse/reiserfs-mount-count
-+jeffm patches.suse/reiserfs-rearrange-journal-abort.diff
-+jeffm patches.suse/reiserfs-reiserfs-warning.diff
-+jeffm patches.suse/reiserfs-reiserfs_info.diff
-+jeffm patches.suse/reiserfs-reiserfs_panic.diff
-+jeffm patches.suse/reiserfs-remove-i_has_xattr_dir.diff
-+jeffm patches.suse/reiserfs-remove-link-detection.diff
-+jeffm patches.suse/reiserfs-remove-xinode
-+jeffm patches.suse/reiserfs-rename-._.diff
-+jeffm patches.suse/reiserfs-rename-p_._.diff
-+jeffm patches.suse/reiserfs-rename-p_s_bh.diff
-+jeffm patches.suse/reiserfs-rename-p_s_inode.diff
-+jeffm patches.suse/reiserfs-rename-p_s_sb.diff
-+jeffm patches.suse/reiserfs-rename-p_s_tb.diff
-+jeffm patches.suse/reiserfs-selinux.diff
-+jeffm patches.suse/reiserfs-simplify-buffer-info.diff
-+jeffm patches.suse/reiserfs-simplify-xattr-internal-file-lookups-opens.diff
-+jeffm patches.suse/reiserfs-strip-whitespace.diff
-+jeffm patches.suse/reiserfs-use-generic-xattr-handlers.diff
-+jeffm patches.suse/reiserfs-use-reiserfs_error.diff
-+jeffm patches.suse/reiserfs-xattr-S_PRIVATE
-+jeffm patches.suse/reiserfs-xattr-get-page
-+jeffm patches.suse/reiserfs_warning-reentrant
+jjolly patches.arch/ppc-axon-missing-msi-workaround-5.diff
+jjolly patches.arch/s390-01-02-dcss-64-v2.patch
+jjolly patches.arch/s390-01-04-fcpperf-1.patch
diff --git a/patches.apparmor/apparmor-allow-truncation-of-deleted-files b/patches.apparmor/apparmor-allow-truncation-of-deleted-files
new file mode 100644
index 0000000000..851c779fce
--- /dev/null
+++ b/patches.apparmor/apparmor-allow-truncation-of-deleted-files
@@ -0,0 +1,51 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 06:53:18 +0000 (-0800)
+Subject: AppArmor: Allow truncation of deleted files
+Git-commit: dae3fe8b3f624c5dd48716899dd45bd9a76320a9
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: AppArmor disallows truncate of deleted files.
+
+BugLink: http://bugs.launchpad.net/bugs/451375
+
+AppArmor forces a change in application behavior that while ugly is
+long standing and thus can break existing applications without any
+recourse except to disable apparmor mediation of the application.
+
+The bug/change of behavior is as follows:
+The application opens a file at /some/path, it then unlinks the
+file and continues to hold a reference to the file through fd.
+The application then tries to truncate the file but the
+security_path_truncate doesn't identify if the path comes from
+a file or not. So we can't distinguisth between trunc("/some/path")
+and trunc(fd). Since the path no longer exists and is not
+visible AppArmor denies the access, but standard semantics are to
+allow the truncate of the deleted file.
+
+Change AppArmor deleted file mediation to allow allow consideration
+of the deleted path name.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/path.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/security/apparmor/path.c b/security/apparmor/path.c
+index 85897e0..2c14e1d 100644
+--- a/security/apparmor/path.c
++++ b/security/apparmor/path.c
+@@ -121,6 +121,10 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ * strip it.
+ */
+ buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
++ } else if (d_unhashed(path->dentry) && (buf + buflen) - res > 11 &&
++ strcmp(buf + buflen - 11, " (deleted)") == 0) {
++ /* For now allow mediation of deleted paths */
++ buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
+ } else if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) {
+ error = -ENOENT;
+ #if 0
+
diff --git a/patches.apparmor/apparmor-correct-mapping-of-file-permissions b/patches.apparmor/apparmor-correct-mapping-of-file-permissions
new file mode 100644
index 0000000000..46896444c9
--- /dev/null
+++ b/patches.apparmor/apparmor-correct-mapping-of-file-permissions
@@ -0,0 +1,31 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Fri, 10 Jul 2009 09:29:50 +0000 (-0700)
+Subject: AppArmor: Correct mapping of file permissions.
+Git-commit: 0fbb67a37fc861aa10d9072f315b0e6674be2456
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Correct mapping of file permissions.
+
+File permissions opened with an exec permission should be mapped to
+the 'm' permission (mapped executable), not the 'x' permission (control
+of execve transition).
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/include/file.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/apparmor/include/file.h
++++ b/security/apparmor/include/file.h
+@@ -200,7 +200,7 @@ static inline void aa_free_file_rules(st
+ aa_free_domain_entries(&rules->trans);
+ }
+
+-#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) >> 5) & 0x1))
++#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
+
+ /* from namei.c */
+ #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
diff --git a/patches.apparmor/apparmor-ensure-apparmor-enabled-parmater-is-off-if-apparmor-fails-to-initialize b/patches.apparmor/apparmor-ensure-apparmor-enabled-parmater-is-off-if-apparmor-fails-to-initialize
new file mode 100644
index 0000000000..03a57094d7
--- /dev/null
+++ b/patches.apparmor/apparmor-ensure-apparmor-enabled-parmater-is-off-if-apparmor-fails-to-initialize
@@ -0,0 +1,39 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Thu, 16 Jul 2009 15:36:43 +0000 (-0700)
+Subject: AppArmor: ensure apparmor enabled parmater is off if AppArmor fails to initialize.
+Git-commit: c68fe02f4a1a9daf53effdef1971a5ae2436d8b0
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: ensure apparmor enabled parmater is off if AppArmor fails to initialize.
+
+The /sys/modules/apparmor/parameters/enabled parameter was wrongly reporting
+that AppArmor was enabled when it had failed to initialized. It should
+report that apparmor is disabled when AppArmor fails to initialize for any
+reason.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/lsm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -983,6 +983,7 @@ static int __init apparmor_init(void)
+
+ if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
+ info_message("AppArmor disabled by boot time parameter\n");
++ apparmor_enabled = 0;
+ return 0;
+ }
+
+@@ -1031,6 +1032,7 @@ alloc_out:
+ destroy_apparmorfs();
+
+ /*createfs_out:*/
++ apparmor_enabled = 0;
+ return error;
+
+ }
diff --git a/patches.apparmor/apparmor-explicitly-include-header-files-to-allow-apparmor-to-build-on-powerpc b/patches.apparmor/apparmor-explicitly-include-header-files-to-allow-apparmor-to-build-on-powerpc
new file mode 100644
index 0000000000..1d4360e58e
--- /dev/null
+++ b/patches.apparmor/apparmor-explicitly-include-header-files-to-allow-apparmor-to-build-on-powerpc
@@ -0,0 +1,42 @@
+From themuso@ubuntu.com Tue Nov 17 11:13:49 2009
+From: Luke Yelavich <themuso@ubuntu.com>
+Date: Sun, 12 Jul 2009 05:53:37 +0000 (+1000)
+Subject: AppArmor: Explicitly include header files to allow apparmor to build on powerpc
+Git-commit: 3cfaf52bf1c251f5b88230392e841cc4f9f16a21
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Explicitly include header files to allow apparmor to build on powerpc
+
+Include linux/personality.h for ubuntu/apparmor/domain.c and include linux/err.h
+for ubuntu/apparmor/sid.c. Tested on X86 and X86_64 as well, with no adverse
+affects.
+
+Signed-off-by: Luke Yelavich <themuso@ubuntu.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/domain.c | 1 +
+ security/apparmor/sid.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -18,6 +18,7 @@
+ #include <linux/mount.h>
+ #include <linux/syscalls.h>
+ #include <linux/tracehook.h>
++#include <linux/personality.h>
+
+ #include "include/audit.h"
+ #include "include/apparmorfs.h"
+--- a/security/apparmor/sid.c
++++ b/security/apparmor/sid.c
+@@ -28,6 +28,7 @@
+ */
+
+ #include <linux/spinlock.h>
++#include <linux/err.h>
+
+ #include "include/sid.h"
+
diff --git a/patches.apparmor/apparmor-fix-argument-size-missmatch-on-64-bit-builds b/patches.apparmor/apparmor-fix-argument-size-missmatch-on-64-bit-builds
new file mode 100644
index 0000000000..71afca4188
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-argument-size-missmatch-on-64-bit-builds
@@ -0,0 +1,54 @@
+From apw@canonical.com Tue Nov 17 11:13:49 2009
+From: Andy Whitcroft <apw@canonical.com>
+Date: Tue, 21 Jul 2009 11:16:07 +0000 (+0100)
+Subject: AppArmor: fix argument size missmatch on 64 bit builds
+Git-commit: fa557cce4bfa8f71b0c3c7546151e0edabf7456a
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix argument size missmatch on 64 bit builds
+
+When building AppArmor on 64 bit we see a warning as below:
+
+ .../apparmor/policy_interface.c: In function ‘audit_cb’:
+ .../apparmor/policy_interface.c:101: warning: format ‘%d’ expects type
+ ‘int’, but argument 3 has type ‘long int’
+
+This is triggered by the log format below. We are printing the
+difference
+between two pointers which is potentially a long on 64bit.
+
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ [...]
+ if (sa->base.error && sa->e)
+ audit_log_format(ab, " offset=%d", sa->e->pos - sa->e->start);
+ }
+
+Convert this delta to a long for printing.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/policy_interface.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -92,13 +92,14 @@ static void aa_audit_init(struct aa_audi
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct aa_audit_iface *sa = va;
++ long len = sa->e->pos - sa->e->start;
+
+ if (sa->name)
+ audit_log_format(ab, " name=%s", sa->name);
+ if (sa->name2)
+ audit_log_format(ab, " namespace=%s", sa->name2);
+ if (sa->base.error && sa->e)
+- audit_log_format(ab, " offset=%d", sa->e->pos - sa->e->start);
++ audit_log_format(ab, " offset=%ld", len);
+ }
+
+ static int aa_audit_iface(struct aa_audit_iface *sa)
diff --git a/patches.apparmor/apparmor-fix-auditing-of-domain-transitions-to-include-target-profile-information b/patches.apparmor/apparmor-fix-auditing-of-domain-transitions-to-include-target-profile-information
new file mode 100644
index 0000000000..81d3fe7f83
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-auditing-of-domain-transitions-to-include-target-profile-information
@@ -0,0 +1,34 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Fri, 17 Jul 2009 15:51:23 +0000 (-0700)
+Subject: AppArmor: fix auditing of domain transitions to include target profile information
+Git-commit: 75da64947c8ca56439c1b9145962ce515fc178ff
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix auditing of domain transitions to include target profile information
+
+Domain transitions were only reporting the target executable name. The
+target profile can differ when doing named transitions and it needs
+to be reported.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/domain.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -335,6 +335,11 @@ int apparmor_bprm_set_creds(struct linux
+ bprm->unsafe |= AA_SECURE_X_NEEDED;
+
+ apply:
++ sa.name2 = new_profile->fqname;
++ /* When switching namespace ensure its part of audit message */
++ if (new_profile->ns != profile->ns)
++ sa.name3 = new_profile->ns->base.name;
++
+ /* when transitioning profiles clear unsafe personality bits */
+ bprm->per_clear |= PER_CLEAR_ON_SETID;
+
diff --git a/patches.apparmor/apparmor-fix-build-failure-on-ia64 b/patches.apparmor/apparmor-fix-build-failure-on-ia64
new file mode 100644
index 0000000000..d3cd7f01f1
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-build-failure-on-ia64
@@ -0,0 +1,28 @@
+From jeffm@suse.de Tue Nov 17 11:13:49 2009
+From: Jeff Mahoney <jeffm@suse.de>
+Date: Fri, 17 Jul 2009 16:44:23 +0000 (-0700)
+Subject: AppArmor: fix build failure on ia64
+Git-commit: f33ea46ede948ed04f91c273ecf85c4b54d1299c
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix build failure on ia64
+
+fix a build failure on ia64, where including types.h and spinlock.h don't pull in linux/err.h and linux/errno.h
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.de>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+---
+ security/apparmor/sid.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/security/apparmor/sid.c
++++ b/security/apparmor/sid.c
+@@ -28,6 +28,7 @@
+ */
+
+ #include <linux/spinlock.h>
++#include <linux/errno.h>
+ #include <linux/err.h>
+
+ #include "include/sid.h"
diff --git a/patches.apparmor/apparmor-fix-c99-violation b/patches.apparmor/apparmor-fix-c99-violation
new file mode 100644
index 0000000000..e841c7d9a3
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-c99-violation
@@ -0,0 +1,35 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Fri, 17 Jul 2009 16:21:12 +0000 (-0700)
+Subject: AppArmor: fix C99 violation
+Git-commit: 071c722a14e00e5c9bcd5516017a6f4889075e13
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix C99 violation
+
+fix a build warning from a C99 violation (mixing code and declarations)
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.de>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+---
+ security/apparmor/lsm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -183,11 +183,13 @@ static int common_perm_rm(const char *op
+ struct dentry *dentry, u16 mask)
+ {
+ struct inode *inode = dentry->d_inode;
++ struct path_cond cond = {};
+
+ if (!dir->mnt || !inode || !mediated_filesystem(inode))
+ return 0;
+
+- struct path_cond cond = { inode->i_uid, inode->i_mode };
++ cond.uid = inode->i_uid;
++ cond.mode = inode->i_mode;
+
+ return common_perm_dentry(op, dir, dentry, mask, &cond);
+ }
diff --git a/patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling b/patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling
new file mode 100644
index 0000000000..45b9653472
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling
@@ -0,0 +1,36 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:09:04 +0000 (-0800)
+Subject: AppArmor: Fix cap audit_caching preemption disabling
+Git-commit: 10180dca43970cd1bebf88248c1ad63ab7521c7a
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix cap audit_caching preemption disabling
+
+BugLink: http://bugs.launchpad.net/bugs/479102
+
+The auditing code of capabilities, has a simple cache to reduce capability
+messages flooding the audit logs. Checking and updating the cache
+disables kernel preemption. One potential exit path does not properly
+put the per cpu var, thus not reenabling preemption.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/capability.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
+index 65b91cf..5bb2eca 100644
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -72,6 +72,7 @@ static int aa_audit_caps(struct aa_profile *profile, struct aa_audit_caps *sa)
+ /* Do simple duplicate message elimination */
+ ent = &get_cpu_var(audit_cache);
+ if (sa->base.task == ent->task && cap_raised(ent->caps, sa->cap)) {
++ put_cpu_var(audit_cache);
+ if (PROFILE_COMPLAIN(profile))
+ return 0;
+ return sa->base.error;
+
diff --git a/patches.apparmor/apparmor-fix-change_profile-failing-lpn401931 b/patches.apparmor/apparmor-fix-change_profile-failing-lpn401931
new file mode 100644
index 0000000000..b8787f74b7
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-change_profile-failing-lpn401931
@@ -0,0 +1,56 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Thu, 23 Jul 2009 16:54:51 +0000 (-0700)
+Subject: AppArmor: Fix change_profile failing lpn401931
+Git-commit: db344220ea9cfabde6d37dbe1cf6e2f9731b84cf
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix change_profile failing lpn401931
+
+Fix change_profile so that it doesn't return -EINVAL when only fqname
+is defined. Also fix the oops, when ns_name is defined and the permission
+check is done.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/domain.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -90,8 +90,11 @@ static struct file_perms change_profile_
+ perms.allowed = AA_MAY_CHANGE_PROFILE;
+ perms.xindex = perms.dindex = 0;
+ perms.audit = perms.quiet = perms.kill = 0;
+- *rstate = 0;
++ if (rstate)
++ *rstate = 0;
+ return perms;
++ } else if (!profile->file.dfa) {
++ return nullperms;
+ } else if ((ns == profile->ns)) {
+ /* try matching against rules with out namespace prependend */
+ perms = aa_str_perms(profile->file.dfa, DFA_START, name, &cond,
+@@ -101,9 +104,6 @@ static struct file_perms change_profile_
+ }
+
+ /* try matching with namespace name and then profile */
+- if (!profile->file.dfa)
+- return nullperms;
+-
+ state = aa_dfa_match(profile->file.dfa, DFA_START, ns->base.name);
+ state = aa_dfa_null_transition(profile->file.dfa, state);
+ return aa_str_perms(profile->file.dfa, state, name, &cond, rstate);
+@@ -619,9 +619,8 @@ int aa_change_profile(const char *ns_nam
+ struct aa_profile *profile, *target = NULL;
+ struct aa_namespace *ns = NULL;
+ struct aa_audit_file sa;
+- char *name = NULL;
+
+- if (!name && !ns_name)
++ if (!fqname && !ns_name)
+ return -EINVAL;
+
+ memset(&sa, 0, sizeof(sa));
diff --git a/patches.apparmor/apparmor-fix-change_profile-failure b/patches.apparmor/apparmor-fix-change_profile-failure
new file mode 100644
index 0000000000..51c2201856
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-change_profile-failure
@@ -0,0 +1,76 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Wed, 26 Aug 2009 20:57:37 +0000 (-0700)
+Subject: AppArmor: Fix change_profile failure
+Git-commit: 0189ce8a96793ead8eb77d60e22d9166630b6c84
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix change_profile failure
+
+BugLink: http://bugs.launchpad.net/bugs/401931
+
+Change_profile requests were failing due to the permission being
+incorrectly mapped. Further more the permission failure was not
+generating audit messages.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/domain.c | 8 ++++----
+ security/apparmor/file.c | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -630,6 +630,7 @@ int aa_change_profile(const char *ns_nam
+ return -EINVAL;
+
+ memset(&sa, 0, sizeof(sa));
++ sa.request = AA_MAY_CHANGE_PROFILE;
+ sa.base.gfp_mask = GFP_KERNEL;
+ if (onexec)
+ sa.base.operation = "change_onexec";
+@@ -638,11 +639,9 @@ int aa_change_profile(const char *ns_nam
+
+ cred = aa_current_policy(&profile);
+ cxt = cred->security;
+- ns = aa_get_namespace(cxt->sys.profile->ns);
+
+ if (ns_name) {
+ sa.name2 = ns_name;
+- aa_put_namespace(ns);
+ ns = aa_find_namespace(ns_name);
+ if (!ns) {
+ /* we don't create new namespace in complain mode */
+@@ -650,8 +649,10 @@ int aa_change_profile(const char *ns_nam
+ sa.base.error = -ENOENT;
+ goto audit;
+ }
+- } else
++ } else {
++ ns = aa_get_namespace(cxt->sys.profile->ns);
+ sa.name2 = ns->base.name;
++ }
+
+ /* if the name was not specified, use the name of the current profile */
+ if (!fqname) {
+@@ -663,7 +664,6 @@ int aa_change_profile(const char *ns_nam
+ sa.name = fqname;
+
+ sa.perms = change_profile_perms(profile, ns, fqname, NULL);
+-
+ if (!(sa.perms.allowed & AA_MAY_CHANGE_PROFILE)) {
+ sa.base.error = -EACCES;
+ goto audit;
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -192,7 +192,7 @@ struct file_perms aa_compute_perms(struc
+ perms.allowed |= AA_LINK_SUBSET;
+
+ /* change_profile wasn't determined by ownership in old mapping */
+- if (ACCEPT_TABLE2(dfa)[state] & 0x80000000)
++ if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
+ perms.allowed |= AA_MAY_CHANGE_PROFILE;
+
+ return perms;
diff --git a/patches.apparmor/apparmor-fix-determination-of-forced-audit-messages b/patches.apparmor/apparmor-fix-determination-of-forced-audit-messages
new file mode 100644
index 0000000000..e9855dc5e7
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-determination-of-forced-audit-messages
@@ -0,0 +1,68 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Thu, 23 Jul 2009 17:24:45 +0000 (-0700)
+Subject: AppArmor: Fix determination of forced AUDIT messages.
+Git-commit: 8ee7a29dc712f2fc9ad477ec32324a75e2b920cf
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix determination of forced AUDIT messages.
+
+This fixes a bug where some classes of messages are being forced audited
+when they shouldn't be.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/audit.c | 6 ++++--
+ security/apparmor/capability.c | 1 +
+ security/apparmor/file.c | 1 +
+ security/apparmor/net.c | 1 +
+ 4 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/security/apparmor/audit.c
++++ b/security/apparmor/audit.c
+@@ -114,9 +114,11 @@ int aa_audit(int type, struct aa_profile
+ audit_cxt = g_apparmor_logsyscall ? current->audit_context : NULL;
+
+ if (type == AUDIT_APPARMOR_AUTO) {
+- if (likely(!sa->error))
++ if (likely(!sa->error)) {
++ if (PROFILE_AUDIT_MODE(profile) != AUDIT_ALL)
++ return 0;
+ type = AUDIT_APPARMOR_AUDIT;
+- else if (PROFILE_COMPLAIN(profile))
++ } else if (PROFILE_COMPLAIN(profile))
+ type = AUDIT_APPARMOR_ALLOWED;
+ else
+ type = AUDIT_APPARMOR_DENIED;
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -58,6 +58,7 @@ static int aa_audit_caps(struct aa_profi
+ if (likely((PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) &&
+ !cap_raised(profile->caps.audit, sa->cap)))
+ return 0;
++ type = AUDIT_APPARMOR_AUDIT;
+ } else if (PROFILE_KILL(profile) ||
+ cap_raised(profile->caps.kill, sa->cap)) {
+ type = AUDIT_APPARMOR_KILL;
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -137,6 +137,7 @@ int aa_audit_file(struct aa_profile *pro
+
+ if (likely(!sa->request))
+ return 0;
++ type = AUDIT_APPARMOR_AUDIT;
+ } else {
+ /* quiet auditing of specific known rejects */
+ u16 mask = sa->perms.quiet;
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -74,6 +74,7 @@ static int aa_audit_net(struct aa_profil
+ if (likely((PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) &&
+ !(1 << sa->type & audit_mask)))
+ return 0;
++ type = AUDIT_APPARMOR_AUDIT;
+ } else {
+ u16 quiet_mask = profile->net.quiet[sa->family];
+ u16 kill_mask = 0;
diff --git a/patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly b/patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly
new file mode 100644
index 0000000000..ca297ec0f2
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly
@@ -0,0 +1,142 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 3 Nov 2009 19:18:14 +0000 (-0800)
+Subject: AppArmor: fix failure to audit change_hat correctly
+Git-commit: 505784955a55972a76c9984535dc0c1b31f7e0ab
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix failure to audit change_hat correctly
+
+BugLink: http://bugs.launchpad.net/bugs/462824
+
+When the change_hat api is used AppArmor fails to log failures and
+learning events correctly. The name being report when a hatname
+is specified is incorrect, and in the complain (learning) case
+the message is surpressed as the error code is reset when setting
+the current hat.
+
+This means failures are not getting properly reported, and the tools
+can not be used to profile change_hat behavior.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/domain.c | 61 ++++++++++++++++++++++++---------------------
+ 1 file changed, 33 insertions(+), 28 deletions(-)
+
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index 464f236..cdf9d00 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -525,15 +525,16 @@ int aa_change_hat(const char *hat_name, u64 token, int permtest)
+ struct aa_task_context *cxt;
+ struct aa_profile *profile, *previous_profile, *hat = NULL;
+ struct aa_audit_file sa;
++ char *name = NULL;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.base.gfp_mask = GFP_KERNEL;
+ sa.base.operation = "change_hat";
++ sa.request = AA_MAY_CHANGEHAT;
+
+ cred = aa_current_policy(&profile);
+ cxt = cred->security;
+ previous_profile = cxt->sys.previous;
+- token = cxt->sys.token;
+
+ if (!profile) {
+ sa.base.info = "unconfined";
+@@ -542,32 +543,36 @@ int aa_change_hat(const char *hat_name, u64 token, int permtest)
+ }
+
+ if (hat_name) {
+- if (previous_profile)
+- sa.name = previous_profile->fqname;
+- else
+- sa.name = profile->fqname;
+-
++ struct aa_profile *root;
++ root = PROFILE_IS_HAT(profile) ? profile->parent : profile;
+ sa.name2 = profile->ns->base.name;
+
+- if (PROFILE_IS_HAT(profile))
+- hat = aa_find_child(profile->parent, hat_name);
+- else
+- hat = aa_find_child(profile, hat_name);
++ hat = aa_find_child(root, hat_name);
+ if (!hat) {
++ if (permtest || !PROFILE_COMPLAIN(root))
++ /* probing is an expected unfortunate behavior
++ * of the change_hat api is traditionally quiet
++ */
++ goto out;
++
++ name = new_compound_name(root->fqname, hat_name);
++
++ sa.name = name;
+ sa.base.info = "hat not found";
+ sa.base.error = -ENOENT;
+- if (permtest || !PROFILE_COMPLAIN(profile))
+- goto audit;
+ hat = aa_alloc_null_profile(profile, 1);
+ if (!hat) {
+ sa.base.info = "failed null profile create";
+ sa.base.error = -ENOMEM;
+ goto audit;
+ }
+- } else if (!PROFILE_IS_HAT(hat)) {
+- sa.base.info = "target not hat";
+- sa.base.error = -EPERM;
+- goto audit;
++ } else {
++ sa.name = hat->fqname;
++ if (!PROFILE_IS_HAT(hat)) {
++ sa.base.info = "target not hat";
++ sa.base.error = -EPERM;
++ goto audit;
++ }
+ }
+
+ sa.base.error = aa_may_change_ptraced_domain(current, hat);
+@@ -579,27 +584,27 @@ int aa_change_hat(const char *hat_name, u64 token, int permtest)
+
+ if (!permtest) {
+ sa.base.error = aa_set_current_hat(hat, token);
+- if (sa.base.error == -EACCES) {
+- (void)send_sig_info(SIGKILL, NULL, current);
+- sa.base.error = aa_audit(AUDIT_APPARMOR_KILL,
+- profile, &sa.base,
+- file_audit_cb);
+- goto out;
+- }
++ if (sa.base.error == -EACCES)
++ sa.perms.kill = AA_MAY_CHANGEHAT;
++ else if (name && !sa.base.error)
++ /* reset error for learning of new hats */
++ sa.base.error = -ENOENT;
+ }
+- } else if (previous_profile)
++ } else if (previous_profile) {
++ sa.name = previous_profile->fqname;
+ sa.base.error = aa_restore_previous_profile(token);
+- /* else
+- ignore restores when there is no saved profile
+- */
++ sa.perms.kill = AA_MAY_CHANGEHAT;
++ } else
++ /* ignore restores when there is no saved profile */
++ goto out;
+
+ audit:
+ if (!permtest)
+ sa.base.error = aa_audit_file(profile, &sa);
+
+-
+ out:
+ aa_put_profile(hat);
++ kfree(name);
+
+ return sa.base.error;
+ }
+
diff --git a/patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used b/patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used
new file mode 100644
index 0000000000..8c1761657c
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used
@@ -0,0 +1,49 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Mon, 2 Nov 2009 14:04:01 +0000 (-0800)
+Subject: AppArmor: Fix file auditing when quiet is used
+Git-commit: 0a844e068d06adf0bd62e82302c24d0bf953209f
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix file auditing when quiet is used
+
+Fix file auditing so that if a reject occurs and all denied permissions
+are quieted that no logging is done.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/file.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 16d2f56..f27bae6 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -139,18 +139,17 @@ int aa_audit_file(struct aa_profile *profile, struct aa_audit_file *sa)
+ return 0;
+ type = AUDIT_APPARMOR_AUDIT;
+ } else {
+- /* quiet auditing of specific known rejects */
+- u16 mask = sa->perms.quiet;
+- u16 denied = sa->request & ~sa->perms.allowed;
++ /* only report permissions that were denied */
++ sa->request = sa->request & ~sa->perms.allowed;
+
+- if (denied & sa->perms.kill)
++ if (sa->request & sa->perms.kill)
+ type = AUDIT_APPARMOR_KILL;
+
+- /* assumes quiet and kill do not overlap */
+- if ((denied & mask) &&
++ /* quiet known rejects, assumes quiet and kill do not overlap */
++ if ((sa->request & sa->perms.quiet) &&
+ PROFILE_AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+ PROFILE_AUDIT_MODE(profile) != AUDIT_ALL)
+- sa->request &= ~mask;
++ sa->request &= ~sa->perms.quiet;
+
+ if (!sa->request)
+ return PROFILE_COMPLAIN(profile) ? 0 : sa->base.error;
+
diff --git a/patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack b/patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack
new file mode 100644
index 0000000000..071b4aaaf4
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack
@@ -0,0 +1,52 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:23:31 +0000 (-0800)
+Subject: AppArmor: Fix leak when profile transition table fails unpack
+Git-commit: 65ed2e80434928de94d7ada01a6ab17d3cf3458b
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+Fix leak when profile transition table fails unpack
+
+Priority: low, only should occur on corrupted policy tables, which shouldn't
+ generally happen.
+
+Fix a leak of the transition table strings when the profile transition
+table unpack fails.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/policy_interface.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/security/apparmor/policy_interface.c b/security/apparmor/policy_interface.c
+index 68e87cd..7609354 100644
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -376,6 +376,7 @@ static int aa_unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
+ if (!profile->file.trans.table)
+ goto fail;
+
++ profile->file.trans.size = size;
+ for (i = 0; i < size; i++) {
+ char *tmp;
+ if (!aa_is_dynstring(e, &tmp, NULL))
+@@ -389,11 +390,15 @@ static int aa_unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
+ goto fail;
+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
+ goto fail;
+- profile->file.trans.size = size;
+ }
+ return 1;
+
+ fail:
++ if (profile->file.trans.table) {
++ int i;
++ for (i = 0; i < profile->file.trans.size; i++)
++ kfree(profile->file.trans.table[i]);
++ }
+ e->pos = pos;
+ return 0;
+ }
+
diff --git a/patches.apparmor/apparmor-fix-mapping-of-pux-to-new-internal-permission-format b/patches.apparmor/apparmor-fix-mapping-of-pux-to-new-internal-permission-format
new file mode 100644
index 0000000000..67188086cf
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-mapping-of-pux-to-new-internal-permission-format
@@ -0,0 +1,32 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Wed, 26 Aug 2009 21:04:32 +0000 (-0700)
+Subject: AppArmor: Fix mapping of pux to new internal permission format
+Git-commit: 936afb68ec447026a201ff7210d6d15dace0c4b3
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix mapping of pux to new internal permission format
+
+BugLink: http://bugs.launchpad.net/bugs/419222
+
+The mapping of pux (exec profile or unconfined) from old permission format
+to the new internal format is missing so that pux does not work.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/include/file.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/security/apparmor/include/file.h
++++ b/security/apparmor/include/file.h
+@@ -110,6 +110,8 @@ static inline u16 dfa_map_xindex(u16 mas
+ index |= AA_X_UNSAFE;
+ if (mask & 0x200)
+ index |= AA_X_INHERIT;
++ if (mask & 0x80)
++ index |= AA_X_UNCONFINED;
+
+ if (old_index == 1) {
+ index |= AA_X_UNCONFINED;
diff --git a/patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths b/patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths
new file mode 100644
index 0000000000..7dfbfad520
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths
@@ -0,0 +1,48 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 3 Nov 2009 19:15:55 +0000 (-0800)
+Subject: AppArmor: Fix mediation of created paths that look like "deleted" paths
+Git-commit: d3ed63523f31c0c88335ad2da246f98a153d6080
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix mediation of created paths that look like "deleted" paths
+
+Under some filesystems (that provide their own dentry instantiation)
+the allocated dentry can be flag as unhashed (same as a deleted dentry)
+until the d_inode is allocated. Because of the location of the
+security_path hooks AppArmor (and __d_path) sees the requested
+path as deleted, and fails to allow the creation of the file/node,
+as it is not covered by deleted file delegation.
+Detect path dentries without allocated d_inodes and treat them
+as regular file paths.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/path.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/security/apparmor/path.c b/security/apparmor/path.c
+index 21f3e67..85897e0 100644
+--- a/security/apparmor/path.c
++++ b/security/apparmor/path.c
+@@ -110,6 +110,17 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ if (IS_ERR(res)) {
+ error = PTR_ERR(res);
+ *name = buf;
++ } else if (d_unhashed(path->dentry) && !path->dentry->d_inode) {
++ /* On some filesystems, newly allocated dentries appear
++ * to the security_path hooks as a deleted
++ * dentry except without an inode allocated.
++ *
++ * Remove the appended deleted text and return as a
++ * string for normal mediation. The (deleted) string
++ * is guarenteed to be added in this case, so just
++ * strip it.
++ */
++ buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
+ } else if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) {
+ error = -ENOENT;
+ #if 0
+
diff --git a/patches.apparmor/apparmor-fix-null-pointer-dereference-oops-in-profile-attachment b/patches.apparmor/apparmor-fix-null-pointer-dereference-oops-in-profile-attachment
new file mode 100644
index 0000000000..0c8b60f1c4
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-null-pointer-dereference-oops-in-profile-attachment
@@ -0,0 +1,31 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 21 Jul 2009 09:52:44 +0000 (-0700)
+Subject: AppArmor: Fix NULL pointer dereference oops in profile attachment.
+Git-commit: a7e0ec31e0d98c3559b36f8a7eba5237cb61dc33
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix NULL pointer dereference oops in profile attachment.
+
+When doing attachment of a new_profile to an unconfined process the
+filtered profile is null and should not be dereferenced to get
+the namespace.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -337,7 +337,7 @@ int apparmor_bprm_set_creds(struct linux
+ apply:
+ sa.name2 = new_profile->fqname;
+ /* When switching namespace ensure its part of audit message */
+- if (new_profile->ns != profile->ns)
++ if (new_profile->ns != ns)
+ sa.name3 = new_profile->ns->base.name;
+
+ /* when transitioning profiles clear unsafe personality bits */
diff --git a/patches.apparmor/apparmor-fix-oops-after-profile-removal b/patches.apparmor/apparmor-fix-oops-after-profile-removal
new file mode 100644
index 0000000000..6b197887a6
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-oops-after-profile-removal
@@ -0,0 +1,64 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:01:53 +0000 (-0800)
+Subject: AppArmor: Fix oops after profile removal
+Git-commit: 2dcff6eb51fffae61811a05c1c63cf7960f416e0
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix oops after profile removal
+
+BugLink: http://bugs.launchpad.net/bugs/475619
+
+This bug can cause a null pointer dereference kernel oops. This will occur
+any time children profiles are attached to running processes. This can occur
+when change_hat, children profiles or profile learning is used.
+
+Note: this fix is a smaller fix than what is done upstream, as the upstream
+ fix reworks the replacement code, to remove all vestiges of the
+ old method of using ERR_PTR during removal.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/policy.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index b709c30..e2bc9e5 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -322,7 +322,7 @@ void __aa_remove_profile(struct aa_profile *profile,
+ if (replacement)
+ profile->replacedby = aa_get_profile(replacement);
+ else
+- profile->replacedby = ERR_PTR(-EINVAL);
++ profile->replacedby = aa_get_profile(profile->ns->unconfined);
+ list_del_init(&profile->base.list);
+ if (!(profile->flags & PFLAG_NO_LIST_REF))
+ aa_put_profile(profile);
+@@ -541,7 +541,7 @@ void free_aa_profile(struct aa_profile *profile)
+ aa_free_sid(profile->sid);
+ aa_match_free(profile->xmatch);
+
+- if (profile->replacedby && !PTR_ERR(profile->replacedby))
++ if (profile->replacedby)
+ aa_put_profile(profile->replacedby);
+
+ memset(profile, 0, sizeof(profile));
+@@ -715,13 +715,7 @@ struct aa_profile *aa_sys_find_attach(struct aa_policy_common *base,
+ struct aa_profile *aa_profile_newest(struct aa_profile *profile)
+ {
+ if (unlikely(profile && profile->replacedby)) {
+- for (;profile->replacedby; profile = profile->replacedby) {
+- if (IS_ERR(profile->replacedby)) {
+- /* profile has been removed */
+- profile = NULL;
+- break;
+- }
+- }
++ for (;profile->replacedby; profile = profile->replacedby) ;
+ }
+
+ return profile;
+
diff --git a/patches.apparmor/apparmor-fix-oops-in-auditing-of-the-policy-interface-offset b/patches.apparmor/apparmor-fix-oops-in-auditing-of-the-policy-interface-offset
new file mode 100644
index 0000000000..77cde25043
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-oops-in-auditing-of-the-policy-interface-offset
@@ -0,0 +1,39 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Thu, 23 Jul 2009 17:58:43 +0000 (-0700)
+Subject: AppArmor: Fix oops in auditing of the policy interface offset
+Git-commit: d3531cf696017fb410eeacd7655a85969901faab
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix oops in auditing of the policy interface offset
+
+The audit_cb for policy_interface was unconditionally dereferencing
+the interface aa_ext struct.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/policy_interface.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -92,14 +92,15 @@ static void aa_audit_init(struct aa_audi
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct aa_audit_iface *sa = va;
+- long len = sa->e->pos - sa->e->start;
+
+ if (sa->name)
+ audit_log_format(ab, " name=%s", sa->name);
+ if (sa->name2)
+ audit_log_format(ab, " namespace=%s", sa->name2);
+- if (sa->base.error && sa->e)
++ if (sa->base.error && sa->e) {
++ long len = sa->e->pos - sa->e->start;
+ audit_log_format(ab, " offset=%ld", len);
++ }
+ }
+
+ static int aa_audit_iface(struct aa_audit_iface *sa)
diff --git a/patches.apparmor/apparmor-fix-oops-in-profile-listing-and-display-full-list b/patches.apparmor/apparmor-fix-oops-in-profile-listing-and-display-full-list
new file mode 100644
index 0000000000..69038d69f6
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-oops-in-profile-listing-and-display-full-list
@@ -0,0 +1,76 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:49 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Wed, 26 Aug 2009 21:04:17 +0000 (-0700)
+Subject: AppArmor: Fix OOPS in profile listing, and display full list
+Git-commit: 76a750c89ed2a89efa9fcd240526e6a06b61c559
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix OOPS in profile listing, and display full list
+
+BugLink: http://bugs.launchpad.net/bugs/408454
+
+As affects lp #408473
+
+Listing of profiles was broken so that only the first subprofile/hat would
+be displayed, and in certain profile tree arrangements cause an oops. Fix
+the listing so that all subprofiles and their subprofiles will be displayed.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/apparmorfs.c | 34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -74,34 +74,30 @@ out:
+
+ static struct aa_profile *next_profile(struct aa_profile *profile)
+ {
+- struct aa_profile *next = profile;
+- struct aa_namespace *ns;
++ struct aa_profile *parent;
++ struct aa_namespace *ns = profile->ns;
+
+- if (!list_empty(&profile->base.profiles)) {
+- list_for_each_entry(next, &profile->base.profiles, base.list)
+- return next;
+- }
++ if (!list_empty(&profile->base.profiles))
++ return list_first_entry(&profile->base.profiles,
++ struct aa_profile, base.list);
+
+- while (profile->parent) {
+- next = profile->parent;
+- list_for_each_entry_continue(next,
+- &profile->parent->base.profiles,
++ parent = profile->parent;
++ while (parent) {
++ list_for_each_entry_continue(profile, &parent->base.profiles,
+ base.list)
+- return next;
+- profile = profile->parent;
++ return profile;
++ profile = parent;
++ parent = parent->parent;
+ }
+
+- next = profile;
+- list_for_each_entry_continue(next, &profile->ns->base.profiles,
+- base.list)
+- return next;
++ list_for_each_entry_continue(profile, &ns->base.profiles, base.list)
++ return profile;
+
+- ns = profile->ns;
+ read_unlock(&ns->base.lock);
+ list_for_each_entry_continue(ns, &ns_list, base.list) {
+ read_lock(&ns->base.lock);
+- list_for_each_entry(profile, &ns->base.profiles, base.list)
+- return profile;
++ return list_first_entry(&ns->base.profiles, struct aa_profile,
++ base.list);
+ read_unlock(&ns->base.lock);
+ }
+ return NULL;
diff --git a/patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace b/patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace
new file mode 100644
index 0000000000..52d6244549
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace
@@ -0,0 +1,67 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 15 Sep 2009 10:12:17 +0000 (-0700)
+Subject: AppArmor: Fix oops when auditing the addition of profile namespace
+Git-commit: 1904739da9a248a341b90560dae94159b4b3cc94
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix oops when auditing the addition of profile namespace
+
+The name of the namespace is no longer dynamically allocated as part of
+the profile unpacking, so it should not be freed. Also the when a
+new namespace is created the ref count is wrong as a ref count is needed
+for the list, as well as the returned pointer.
+Part of lp #408454
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/policy.c | 2 +-
+ security/apparmor/policy_interface.c | 4 ----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -292,7 +292,7 @@ struct aa_namespace *aa_prepare_namespac
+ ns = __aa_find_namespace(&ns_list, name);
+ if (!ns) {
+ list_add(&new_ns->base.list, &ns_list);
+- ns = new_ns;
++ ns = aa_get_namespace(new_ns);
+ } else {
+ /* raced so free the new one */
+ free_aa_namespace(new_ns);
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -658,7 +658,6 @@ ssize_t aa_interface_add_profiles(void *
+
+ aa_audit_iface(&sa);
+ aa_put_namespace(ns);
+- kfree(e.ns_name);
+ return size;
+
+ fail2:
+@@ -668,7 +667,6 @@ fail:
+ error = aa_audit_iface(&sa);
+ aa_put_namespace(ns);
+ aa_put_profile(profile);
+- kfree(e.ns_name);
+ return error;
+ }
+
+@@ -771,7 +769,6 @@ ssize_t aa_interface_replace_profiles(vo
+ aa_audit_iface(&sa);
+ aa_put_namespace(ns);
+ aa_put_profile(old_profile);
+- kfree(e.ns_name);
+ return size;
+
+ fail2:
+@@ -781,7 +778,6 @@ fail:
+ aa_put_namespace(ns);
+ aa_put_profile(old_profile);
+ aa_put_profile(new_profile);
+- kfree(e.ns_name);
+ return error;
+ }
+
diff --git a/patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds b/patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds
new file mode 100644
index 0000000000..30317c4dcf
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds
@@ -0,0 +1,44 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:05:58 +0000 (-0800)
+Subject: AppArmor: Fix Oops when in apparmor_bprm_set_creds
+Git-commit: f5217539d5f2dcc100a8e470f0ec407ae4bbaca3
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix Oops when in apparmor_bprm_set_creds
+
+BugLink: http://bugs.launchpad.net/bugs/437258
+
+This can cause an oops at 000068. This will happen to all processes confined
+or unconfined when name resolution fails at exec. This can happen in a couple
+different cases, applications like psxe, and mugen munge the process during
+their decrompress and set up links so that a valid name does not exist. The
+other way that this can happen is executing code from a path that has been
+lazily unmounted. This can occur with nfs and automounters, or any mount
+point that gets unmounted with lazy unmount allowed.
+
+If name resolution fails due on exec and a profile is not defined
+then AppArmor will cause an oops due to a broken conditional leading to
+dereferencing a profile pointer that is null.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index cdf9d00..b091fd9 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -248,7 +248,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
+ sa.base.error = aa_get_name(&bprm->file->f_path, 0, &buffer,
+ (char **) &sa.name);
+ if (sa.base.error) {
+- if (profile || profile->flags & PFLAG_IX_ON_NAME_ERROR)
++ if (!profile || profile->flags & PFLAG_IX_ON_NAME_ERROR)
+ sa.base.error = 0;
+ sa.base.info = "Exec failed name resolution";
+ sa.name = bprm->filename;
+
diff --git a/patches.apparmor/apparmor-fix-operator-precidence-issue-in-as_path_link b/patches.apparmor/apparmor-fix-operator-precidence-issue-in-as_path_link
new file mode 100644
index 0000000000..3631dc60d8
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-operator-precidence-issue-in-as_path_link
@@ -0,0 +1,29 @@
+From apw@canonical.com Tue Nov 17 11:13:50 2009
+From: Andy Whitcroft <apw@canonical.com>
+Date: Fri, 10 Jul 2009 14:51:41 +0000 (+0100)
+Subject: AppArmor: fix operator precidence issue in as_path_link
+Git-commit: 14af2d3f28b70768e8b804cb2a09637ab555ed79
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: fix operator precidence issue in as_path_link
+
+Looks like a previous attempt to fix the operator precidence missed.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -310,7 +310,7 @@ int aa_path_link(struct aa_profile *prof
+ sa.perms.quiet &= AA_MAY_LINK;
+ sa.perms.kill &= AA_MAY_LINK;
+
+- if ((!sa.perms.allowed & AA_MAY_LINK)) {
++ if (!(sa.perms.allowed & AA_MAY_LINK)) {
+ sa.base.error = -EACCES;
+ goto audit;
+ }
diff --git a/patches.apparmor/apparmor-fix-profile-attachment-for-regexp-based-profile-names b/patches.apparmor/apparmor-fix-profile-attachment-for-regexp-based-profile-names
new file mode 100644
index 0000000000..0d80023675
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-profile-attachment-for-regexp-based-profile-names
@@ -0,0 +1,124 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Wed, 26 Aug 2009 21:33:48 +0000 (-0700)
+Subject: AppArmor: Fix profile attachment for regexp based profile names
+Git-commit: 65b8e01962b45fecf622e01096a588fce29e973f
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix profile attachment for regexp based profile names
+
+BugLink: http://bugs.launchpad.net/bugs/419308
+
+Part a & b
+Fix profile attachment for profiles that specify an xmatch dfa. Just testing
+if the state > DFA_START is not sufficient to determine if the state is an
+accepting state, as there are transition states that are not accept states.
+Instead test for the MAY_EXEC permission which is set for valid matches.
+
+Part c & d of lp #419308:
+The attachment semantics for px, cx are currently wrong. They do correct
+attachment for profiles with names that are exact matches but the
+attachment fails for profiles names that contain regular expressions.
+
+eg. Given the following profiles
+
+/bin/** { } and /bin/foo { }
+
+an unconfined process correctly attaches to either profile but for a
+confined process with x transition rules.
+ /bin/foo px, # correctly attaches
+ /bin/bar px, # does not attach to /bin/** as it should.
+
+Use the system attachment function, instead of searching for the profile.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ security/apparmor/domain.c | 10 ++++++++--
+ security/apparmor/include/policy.h | 2 +-
+ security/apparmor/policy.c | 16 +++++++++-------
+ 3 files changed, 18 insertions(+), 10 deletions(-)
+
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -157,7 +157,12 @@ static struct aa_profile *x_to_profile(s
+ /* fail exec unless ix || ux fallback - handled by caller */
+ return ERR_PTR(-EACCES);
+ case AA_X_NAME:
+- break;
++ if (xindex & AA_X_CHILD)
++ new_profile = aa_sys_find_attach(&profile->base, name);
++ else
++ new_profile = aa_sys_find_attach(&ns->base, name);
++
++ goto out;
+ case AA_X_TABLE:
+ if (index > profile->file.trans.size) {
+ AA_ERROR("Invalid named transition\n");
+@@ -203,6 +208,7 @@ static struct aa_profile *x_to_profile(s
+ aa_put_namespace(new_ns);
+ }
+
++out:
+ if (!new_profile)
+ return ERR_PTR(-ENOENT);
+
+@@ -251,7 +257,7 @@ int apparmor_bprm_set_creds(struct linux
+
+ if (!profile) {
+ /* unconfined task - attach profile if one matches */
+- new_profile = aa_sys_find_attach(ns, sa.name);
++ new_profile = aa_sys_find_attach(&ns->base, sa.name);
+ if (!new_profile)
+ goto cleanup;
+ goto apply;
+--- a/security/apparmor/include/policy.h
++++ b/security/apparmor/include/policy.h
+@@ -249,7 +249,7 @@ struct aa_profile *aa_find_profile_by_fq
+ const char *name);
+ struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
+ struct aa_profile *aa_profile_newest(struct aa_profile *profile);
+-struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns,
++struct aa_profile *aa_sys_find_attach(struct aa_policy_common *base,
+ const char *name);
+ void __aa_add_profile(struct aa_policy_common *common,
+ struct aa_profile *profile);
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -670,8 +670,9 @@ static struct aa_profile *__aa_attach_ma
+ if (profile->xmatch && profile->xmatch_len > len) {
+ unsigned int state = aa_dfa_match(profile->xmatch,
+ DFA_START, name);
+- /* any accepting state means a valid match */
+- if (state > DFA_START) {
++ u16 perm = dfa_user_allow(profile->xmatch, state);
++ /* any accepting state means a valid match. */
++ if (perm & MAY_EXEC) {
+ candidate = profile;
+ len = profile->xmatch_len;
+ }
+@@ -685,16 +686,17 @@ static struct aa_profile *__aa_attach_ma
+
+ /**
+ * aa_sys_find_attach - do attachment search for sys unconfined processes
+- * @ns: the namespace to search
++ * @base: the base to search
+ * name: the executable name to match against
+ */
+-struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns, const char *name)
++struct aa_profile *aa_sys_find_attach(struct aa_policy_common *base,
++ const char *name)
+ {
+ struct aa_profile *profile;
+
+- read_lock(&ns->base.lock);
+- profile = aa_get_profile(__aa_attach_match(name, &ns->base.profiles));
+- read_unlock(&ns->base.lock);
++ read_lock(&base->lock);
++ profile = aa_get_profile(__aa_attach_match(name, &base->profiles));
++ read_unlock(&base->lock);
+
+ return profile;
+ }
diff --git a/patches.apparmor/apparmor-fix-profile-namespace-removal b/patches.apparmor/apparmor-fix-profile-namespace-removal
new file mode 100644
index 0000000000..925e51491a
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-profile-namespace-removal
@@ -0,0 +1,33 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 15 Sep 2009 10:10:55 +0000 (-0700)
+Subject: AppArmor: Fix profile namespace removal.
+Git-commit: f63a3351411c9008147132ac7bb88b835c92fc4a
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix profile namespace removal.
+
+Reenable the removal of profile namespaces, and fix the default namespace
+case so that the default namespace is not accidentally removed.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ security/apparmor/policy_interface.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -822,7 +822,10 @@ ssize_t aa_interface_remove_profiles(cha
+ write_lock(&ns->base.lock);
+ if (!name) {
+ /* remove namespace */
+- // __aa_remove_namespace(ns);
++ if (ns == default_namespace)
++ __aa_profile_list_release(&ns->base.profiles);
++ else
++ __aa_remove_namespace(ns);
+ } else {
+ /* remove profile */
+ profile = __aa_find_profile_by_fqname(ns, name);
diff --git a/patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops b/patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops
new file mode 100644
index 0000000000..c1fc63f418
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops
@@ -0,0 +1,57 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:11:59 +0000 (-0800)
+Subject: AppArmor: Fix refcounting bug causing leak of creds and oops
+Git-commit: ec785e5388eeb615f89cb386ad07099119050984
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Fix refcounting bug causing leak of creds and oops
+
+BugLink: http://bugs.launchpad.net/bugs/479115
+BugLink: http://bugs.launchpad.net/bugs/480112
+
+One true bug 480112 thats fix introduced another bug. Both fixes are
+combined here into a single patch.
+
+1. AppArmor when doing ptrace check for domain changes, fails to drop
+the ref count on the task creds when it is unconfined.
+
+The original fix to #2 introduced this bug by returning early
+instead of doing put_cred.
+
+2. As reported by Tetsuo Handa on kernel-team mailing list:
+
+In aa_may_change_ptraced_domain, if (!tracer) cred == NULL, and
+put_cred(cred) will oops. This will only happen on exec if the task
+is marked as LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP, so should
+only happen to ptraced tasks that are confined.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/domain.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index b091fd9..497176f 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -64,11 +64,13 @@ static int aa_may_change_ptraced_domain(struct task_struct *task,
+ cred = aa_get_task_policy(tracer, &tracerp);
+ rcu_read_unlock();
+
+- if (!tracerp)
+- return error;
++ if (!tracer || !tracerp)
++ goto out;
+
+ error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
+- put_cred(cred);
++out:
++ if (cred)
++ put_cred(cred);
+
+ return error;
+ }
+
diff --git a/patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use b/patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use
new file mode 100644
index 0000000000..a845a8c271
--- /dev/null
+++ b/patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use
@@ -0,0 +1,35 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: AppArmor: Fix security_ops->task_setrlimit API use
+
+ Linux 2.6.32 changed the task_setrlimit security_operation to
+ take a task_struct. This patch adds the argument to AppArmor's
+ implementation and uses it to allow the call if it isn't actually
+ changing anything.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/lsm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -547,15 +547,16 @@ static int apparmor_setprocattr(struct t
+ return error;
+ }
+
+-static int apparmor_task_setrlimit(unsigned int resource,
++static int apparmor_task_setrlimit(struct task_struct *task,
++ unsigned int resource,
+ struct rlimit *new_rlim)
+ {
++ struct rlimit *old_rlim = task->signal->rlim + resource;
+ struct aa_profile *profile = aa_current_profile_wupd();
+ int error = 0;
+
+- if (profile) {
++ if (profile && old_rlim->rlim_max != new_rlim->rlim_max)
+ error = aa_task_setrlimit(profile, resource, new_rlim);
+- }
+
+ return error;
+ }
diff --git a/patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths b/patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths
new file mode 100644
index 0000000000..49f353388a
--- /dev/null
+++ b/patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths
@@ -0,0 +1,92 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Tue, 17 Nov 2009 07:33:47 +0000 (-0800)
+Subject: AppArmor: Fully close race condition for deleted paths
+Git-commit: 3dc2836574f209e7de447c1451f0c1c326cacadf
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+Fully close race condition for deleted paths
+
+The previous patch allowing stripping of deleted didn't close off the
+race condition, which can occur under the following circumstances.
+
+1. The undeleted path must end in " (deleted).
+2. d_namespace_path and unlink race such that when __d_path is
+ called the path is not deleted, but the test for deleted after
+ __d_path sees the path as deleted.
+
+ This results in d_namespace path stripping off the trailing
+ " (deleted) which is a valid part of the path and not, the
+ string appended by d_path.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/path.c | 31 ++++++++++++++++++++++---------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/security/apparmor/path.c b/security/apparmor/path.c
+index 2c14e1d..a48b5f4 100644
+--- a/security/apparmor/path.c
++++ b/security/apparmor/path.c
+@@ -88,6 +88,7 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ {
+ struct path root, tmp, ns_root = { };
+ char *res;
++ int deleted;
+ int error = 0;
+
+ read_lock(&current->fs->lock);
+@@ -101,8 +102,12 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ ns_root.dentry = dget(ns_root.mnt->mnt_root);
+ spin_unlock(&vfsmount_lock);
+ spin_lock(&dcache_lock);
+- tmp = ns_root;
+- res = __d_path(path, &tmp, buf, buflen);
++
++ do {
++ tmp = ns_root;
++ deleted = d_unlinked(path->dentry);
++ res = __d_path(path, &tmp, buf, buflen);
++ } while (deleted != d_unlinked(path->dentry));
+
+ *name = res;
+ /* handle error conditions - and still allow a partial path to
+@@ -110,8 +115,21 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ if (IS_ERR(res)) {
+ error = PTR_ERR(res);
+ *name = buf;
+- } else if (d_unhashed(path->dentry) && !path->dentry->d_inode) {
+- /* On some filesystems, newly allocated dentries appear
++ } else if (deleted) {
++ /* The stripping of (deleted) is a hack that could be removed
++ * with an updated __d_path
++ */
++
++ /* Currently 2 cases fall into here. Fixing the mediation
++ * of deleted files for things like trunc.
++ * And the newly allocated dentry case. The first case
++ * means we strip deleted for everything so the new
++ * dentry test case is commented out below.
++ */
++ buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
++
++ /* if (!path->dentry->d_inode) {
++ * On some filesystems, newly allocated dentries appear
+ * to the security_path hooks as a deleted
+ * dentry except without an inode allocated.
+ *
+@@ -120,11 +138,6 @@ int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
+ * is guarenteed to be added in this case, so just
+ * strip it.
+ */
+- buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
+- } else if (d_unhashed(path->dentry) && (buf + buflen) - res > 11 &&
+- strcmp(buf + buflen - 11, " (deleted)") == 0) {
+- /* For now allow mediation of deleted paths */
+- buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */
+ } else if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) {
+ error = -ENOENT;
+ #if 0
+
diff --git a/patches.apparmor/apparmor-missing-unlock b/patches.apparmor/apparmor-missing-unlock
new file mode 100644
index 0000000000..bf9d98ca34
--- /dev/null
+++ b/patches.apparmor/apparmor-missing-unlock
@@ -0,0 +1,23 @@
+From 18103692ab79535aec583cd0b933e3c2d2bf9c16 Mon Sep 17 00:00:00 2001
+From: John Johansen <john.johansen@canonical.com>
+Date: Mon, 9 Nov 2009 23:40:49 -0800
+Subject: AppArmor: Add missing unlock to next_profile
+
+ There is a missing read_unlock in the while loop in next_profile.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/apparmorfs.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -98,7 +98,6 @@ static struct aa_profile *next_profile(s
+ read_lock(&ns->base.lock);
+ return list_first_entry(&ns->base.profiles, struct aa_profile,
+ base.list);
+- read_unlock(&ns->base.lock);
+ }
+ return NULL;
+ }
diff --git a/patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem b/patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem
new file mode 100644
index 0000000000..6a7833d0b6
--- /dev/null
+++ b/patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem
@@ -0,0 +1,96 @@
+From john.johansen@canonical.com Tue Nov 17 12:03:14 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Sat, 31 Oct 2009 07:29:14 +0000 (-0700)
+Subject: AppArmor: Policy load and replacement can fail to alloc mem
+Git-commit: 1ab7b3e6235ae47dfc5ba403c4bc3a664b6f8d8e
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Policy load and replacement can fail to alloc mem
+
+BugLink: http://bugs.launchpad.net/bugs/458299
+
+AppArmor dfas can under some circumstances be rather large reaching
+allocations of greater than 128K for a single table. While this is
+not common this can result in memory allocation asking for page allocations
+with an order of 5 or more, which will fail if memory has become fragemented.
+
+This can cause replacement of profiles to fail. Since profile
+setup and replacement is a rare event try falling back to vmalloc if kmalloc
+fails.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ security/apparmor/match.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index a22d106..1a50309 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -12,9 +12,11 @@
+ * License.
+ */
+
++#include <linux/errno.h>
+ #include <linux/kernel.h>
++#include <linux/mm.h>
+ #include <linux/slab.h>
+-#include <linux/errno.h>
++#include <linux/vmalloc.h>
+
+ /* TODO: remove !!!! */
+ // #include <linux/fs.h>
+@@ -23,6 +25,14 @@
+ #include "include/match.h"
+ #include "include/file.h"
+
++static void free_table(struct table_header *table)
++{
++ if (is_vmalloc_addr(table))
++ vfree(table);
++ else
++ kfree(table);
++}
++
+ static struct table_header *unpack_table(void *blob, size_t bsize)
+ {
+ struct table_header *table = NULL;
+@@ -46,6 +56,8 @@ static struct table_header *unpack_table(void *blob, size_t bsize)
+ goto out;
+
+ table = kmalloc(tsize, GFP_KERNEL);
++ if (!table)
++ table = vmalloc(tsize);
+ if (table) {
+ *table = th;
+ if (th.td_flags == YYTD_DATA8)
+@@ -110,7 +122,7 @@ int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
+ goto fail;
+ break;
+ default:
+- kfree(table);
++ free_table(table);
+ goto fail;
+ }
+
+@@ -122,7 +134,7 @@ int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
+
+ fail:
+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
+- kfree(dfa->tables[i]);
++ free_table(dfa->tables[i]);
+ dfa->tables[i] = NULL;
+ }
+ return error;
+@@ -207,7 +219,7 @@ void aa_match_free(struct aa_dfa *dfa)
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
+- kfree(dfa->tables[i]);
++ free_table(dfa->tables[i]);
+ }
+ kfree(dfa);
+ }
+
diff --git a/patches.apparmor/apparmor-return-the-correct-error-codes-on-profile-addition-removal b/patches.apparmor/apparmor-return-the-correct-error-codes-on-profile-addition-removal
new file mode 100644
index 0000000000..072633d07a
--- /dev/null
+++ b/patches.apparmor/apparmor-return-the-correct-error-codes-on-profile-addition-removal
@@ -0,0 +1,57 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Wed, 26 Aug 2009 20:50:21 +0000 (-0700)
+Subject: AppArmor: Return the correct error codes on profile addition/removal
+Git-commit: 34cc2391cf122ca80627ac7f81d51a88801e3024
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Return the correct error codes on profile addition/removal
+
+BugLink: http://bugs.launchpad.net/bugs/408473
+
+Part of lp #408473
+A failed profile addition would alway fail with EEXIST which is incorrect
+for when the parent doesn't exist and a hat is being added. This can
+result in the initscipts not correctly handling hat addition.
+
+Failed profile removal was returning a wrong value that could result
+in user space spinning trying to remove a profile that doesn't exist.
+When combined with hats now being removed with their parent, an attempt
+to removal a hat after its parent always fails. Since the init script
+builds up a removal list that includes hats before doing actual removal,
+if the hat is "removed" after its parent the init script will die,
+spinning on hat removal.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ security/apparmor/policy_interface.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/security/apparmor/policy_interface.c
++++ b/security/apparmor/policy_interface.c
+@@ -647,6 +647,7 @@ ssize_t aa_interface_add_profiles(void *
+ if (__aa_find_profile(&common->profiles, profile->base.name)) {
+ /* A profile with this name exists already. */
+ sa.base.info = "profile already exists";
++ sa.base.error = -EEXIST;
+ goto fail2;
+ }
+ profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
+@@ -662,7 +663,6 @@ ssize_t aa_interface_add_profiles(void *
+
+ fail2:
+ write_unlock(&ns->base.lock);
+- sa.base.error = -EEXIST;
+
+ fail:
+ error = aa_audit_iface(&sa);
+@@ -848,5 +848,5 @@ fail_ns_lock:
+ fail_ns_list_lock:
+ write_unlock(&ns_list_lock);
+ aa_audit_iface(&sa);
+- return 0; //-ENOENT;
++ return -ENOENT;
+ }
diff --git a/patches.apparmor/apparmor-revert-reporting-of-create-to-write-permission b/patches.apparmor/apparmor-revert-reporting-of-create-to-write-permission
new file mode 100644
index 0000000000..306a751adc
--- /dev/null
+++ b/patches.apparmor/apparmor-revert-reporting-of-create-to-write-permission
@@ -0,0 +1,36 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Mon, 20 Jul 2009 07:20:36 +0000 (-0700)
+Subject: AppArmor: revert reporting of create to write permission.
+Git-commit: 5258c0234f53bcf1fc9b2f548835b11535b58135
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: revert reporting of create to write permission.
+
+The reporting of create separate from write permission breaks the tools
+currently. Revert to Jaunty semantic of create reporting the write
+permission.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ security/apparmor/file.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -31,11 +31,9 @@ static void aa_audit_file_sub_mask(struc
+
+ if (mask & AA_EXEC_MMAP)
+ *m++ = 'm';
+- if (mask & AA_MAY_CREATE)
+- *m++ = 'c';
+ if (mask & MAY_READ)
+ *m++ = 'r';
+- if (mask & MAY_WRITE)
++ if (mask & (MAY_WRITE | AA_MAY_CREATE))
+ *m++ = 'w';
+ else if (mask & MAY_APPEND)
+ *m++ = 'a';
diff --git a/patches.apparmor/apparmor-security-module b/patches.apparmor/apparmor-security-module
new file mode 100644
index 0000000000..95572b826d
--- /dev/null
+++ b/patches.apparmor/apparmor-security-module
@@ -0,0 +1,7303 @@
+From: John Johansen <john.johansen@canonical.com>
+Date: Mon, 14 Sep 2009 23:54:45 +0000 (-0700)
+Subject: AppArmor security module
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+Git-commit: 7f6c37ebb481bd6353e50b5f8f37c10a2aa58bcf
+
+AppArmor security module
+
+Initial commit of the 2.6.31 based AppArmor implementation.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ include/linux/audit.h | 10
+ security/Kconfig | 1
+ security/Makefile | 2
+ security/apparmor/Kconfig | 53 +
+ security/apparmor/Makefile | 24
+ security/apparmor/apparmorfs.c | 395 ++++++++++
+ security/apparmor/audit.c | 151 +++
+ security/apparmor/capability.c | 121 +++
+ security/apparmor/context.c | 209 +++++
+ security/apparmor/domain.c | 693 +++++++++++++++++
+ security/apparmor/file.c | 427 ++++++++++
+ security/apparmor/include/apparmor.h | 65 +
+ security/apparmor/include/apparmorfs.h | 24
+ security/apparmor/include/audit.h | 59 +
+ security/apparmor/include/capability.h | 45 +
+ security/apparmor/include/context.h | 153 +++
+ security/apparmor/include/domain.h | 37
+ security/apparmor/include/file.h | 227 +++++
+ security/apparmor/include/ipc.h | 28
+ security/apparmor/include/match.h | 105 ++
+ security/apparmor/include/net.h | 40 +
+ security/apparmor/include/path.h | 24
+ security/apparmor/include/policy.h | 301 +++++++
+ security/apparmor/include/policy_interface.h | 22
+ security/apparmor/include/procattr.h | 26
+ security/apparmor/include/resource.h | 46 +
+ security/apparmor/include/sid.h | 46 +
+ security/apparmor/ipc.c | 106 ++
+ security/apparmor/lib.c | 100 ++
+ security/apparmor/lsm.c | 1059 +++++++++++++++++++++++++++
+ security/apparmor/match.c | 293 +++++++
+ security/apparmor/net.c | 146 +++
+ security/apparmor/path.c | 155 +++
+ security/apparmor/policy.c | 727 ++++++++++++++++++
+ security/apparmor/policy_interface.c | 850 +++++++++++++++++++++
+ security/apparmor/procattr.c | 117 ++
+ security/apparmor/resource.c | 104 ++
+ security/apparmor/sid.c | 111 ++
+ 38 files changed, 7101 insertions(+), 1 deletion(-)
+
+--- a/include/linux/audit.h
++++ b/include/linux/audit.h
+@@ -33,7 +33,7 @@
+ * 1200 - 1299 messages internal to the audit daemon
+ * 1300 - 1399 audit event messages
+ * 1400 - 1499 SE Linux use
+- * 1500 - 1599 kernel LSPP events
++ * 1500 - 1599 AppArmor use
+ * 1600 - 1699 kernel crypto events
+ * 1700 - 1799 kernel anomaly records
+ * 1800 - 1899 kernel integrity events
+@@ -122,6 +122,14 @@
+ #define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
+ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
+
++#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */
++#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */
++#define AUDIT_APPARMOR_DENIED 1503
++#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */
++#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */
++#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */
++#define AUDIT_APPARMOR_KILL 1507 /* AppArmor killing processes */
++
+ #define AUDIT_FIRST_KERN_ANOM_MSG 1700
+ #define AUDIT_LAST_KERN_ANOM_MSG 1799
+ #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -171,6 +171,7 @@ config LSM_MMAP_MIN_ADDR
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+ source security/tomoyo/Kconfig
++source security/apparmor/Kconfig
+
+ source security/integrity/ima/Kconfig
+
+--- a/security/Makefile
++++ b/security/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_KEYS) += keys/
+ subdir-$(CONFIG_SECURITY_SELINUX) += selinux
+ subdir-$(CONFIG_SECURITY_SMACK) += smack
+ subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
++subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
+
+ # always enable default capabilities
+ obj-y += commoncap.o min_addr.o
+@@ -18,6 +19,7 @@ obj-$(CONFIG_SECURITY_SELINUX) += selin
+ obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
+ obj-$(CONFIG_AUDIT) += lsm_audit.o
+ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
++obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
+ obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
+ obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
+
+--- /dev/null
++++ b/security/apparmor/Kconfig
+@@ -0,0 +1,53 @@
++config SECURITY_APPARMOR
++ bool "AppArmor support"
++ depends on SECURITY && SECURITY_NETWORK && NET && INET
++ select AUDIT
++ select SECURITY_PATH
++ select SECURITYFS
++ default n
++ help
++ This enables the AppArmor security module.
++ Required userspace tools (if they are not included in your
++ distribution) and further information may be found at
++ <http://forge.novell.com/modules/xfmod/project/?apparmor>
++
++ If you are unsure how to answer this question, answer N.
++
++config SECURITY_APPARMOR_NETWORK
++ bool "AppArmor network support"
++ depends on SECURITY_APPARMOR
++ default n
++ help
++ This enables AppArmor to mediate applications network use.
++ This will enable the SECURITY_NETWORK hooks.
++
++config SECURITY_APPARMOR_BOOTPARAM_VALUE
++ int "AppArmor boot parameter default value"
++ depends on SECURITY_APPARMOR
++ range 0 1
++ default 1
++ help
++ This option sets the default value for the kernel parameter
++ 'apparmor', which allows AppArmor to be enabled or disabled
++ at boot. If this option is set to 0 (zero), the AppArmor
++ kernel parameter will default to 0, disabling AppArmor at
++ bootup. If this option is set to 1 (one), the AppArmor
++ kernel parameter will default to 1, enabling AppArmor at
++ bootup.
++
++ If you are unsure how to answer this question, answer 1.
++
++config SECURITY_APPARMOR_DISABLE
++ bool "AppArmor runtime disable"
++ depends on SECURITY_APPARMOR
++ default n
++ help
++ This option enables writing to a apparmorfs node 'disable', which
++ allows AppArmor to be disabled at runtime prior to the policy load.
++ AppArmor will then remain disabled until the next boot.
++ This option is similar to the apparmor.enabled=0 boot parameter,
++ but is to support runtime disabling of AppArmor, e.g. from
++ /sbin/init, for portability across platforms where boot
++ parameters are difficult to employ.
++
++ If you are unsure how to answer this question, answer N.
+--- /dev/null
++++ b/security/apparmor/Makefile
+@@ -0,0 +1,24 @@
++# Makefile for AppArmor Linux Security Module
++#
++obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
++
++apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
++ path.o domain.o policy.o policy_interface.o procattr.o lsm.o \
++ resource.o sid.o file.o
++
++apparmor-$(CONFIG_SECURITY_APPARMOR_NETWORK) += net.o
++
++clean-files: capability_names.h af_names.h
++
++quiet_cmd_make-caps = GEN $@
++cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ; sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
++
++quiet_cmd_make-af = GEN $@
++cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ; sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
++
++$(obj)/capability.o : $(obj)/capability_names.h
++$(obj)/net.o : $(obj)/af_names.h
++$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
++ $(call cmd,make-caps)
++$(obj)/af_names.h : $(srctree)/include/linux/socket.h
++ $(call cmd,make-af)
+--- /dev/null
++++ b/security/apparmor/apparmorfs.c
+@@ -0,0 +1,395 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor /proc/<pid>/attr interface functions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/security.h>
++#include <linux/vmalloc.h>
++#include <linux/module.h>
++#include <linux/seq_file.h>
++#include <linux/uaccess.h>
++#include <linux/namei.h>
++
++#include "include/apparmor.h"
++#include "include/audit.h"
++#include "include/context.h"
++#include "include/policy.h"
++#include "include/policy_interface.h"
++
++static char *aa_simple_write_to_buffer(const char __user *userbuf,
++ size_t alloc_size, size_t copy_size,
++ loff_t *pos, const char *operation)
++{
++ const struct cred *cred;
++ struct aa_profile *profile;
++ char *data;
++
++ if (*pos != 0) {
++ /* only writes from pos 0, that is complete writes */
++ data = ERR_PTR(-ESPIPE);
++ goto out;
++ }
++
++ /*
++ * Don't allow confined processes to load/replace/remove profiles.
++ * No sane person would add rules allowing this to a profile
++ * but we enforce the restriction anyways.
++ */
++ cred = aa_current_policy(&profile);
++ if (profile) {
++ struct aa_audit sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.operation = operation;
++ sa.gfp_mask = GFP_KERNEL;
++ sa.error = -EACCES;
++ data = ERR_PTR(aa_audit(AUDIT_APPARMOR_DENIED, profile, &sa,
++ NULL));
++ goto out;
++ }
++
++ data = vmalloc(alloc_size);
++ if (data == NULL) {
++ data = ERR_PTR(-ENOMEM);
++ goto out;
++ }
++
++ if (copy_from_user(data, userbuf, copy_size)) {
++ vfree(data);
++ data = ERR_PTR(-EFAULT);
++ goto out;
++ }
++
++out:
++ return data;
++}
++
++static struct aa_profile *next_profile(struct aa_profile *profile)
++{
++ struct aa_profile *next = profile;
++ struct aa_namespace *ns;
++
++ if (!list_empty(&profile->base.profiles)) {
++ list_for_each_entry(next, &profile->base.profiles, base.list)
++ return next;
++ }
++
++ while (profile->parent) {
++ next = profile->parent;
++ list_for_each_entry_continue(next,
++ &profile->parent->base.profiles,
++ base.list)
++ return next;
++ profile = profile->parent;
++ }
++
++ next = profile;
++ list_for_each_entry_continue(next, &profile->ns->base.profiles,
++ base.list)
++ return next;
++
++ ns = profile->ns;
++ read_unlock(&ns->base.lock);
++ list_for_each_entry_continue(ns, &ns_list, base.list) {
++ read_lock(&ns->base.lock);
++ list_for_each_entry(profile, &ns->base.profiles, base.list)
++ return profile;
++ read_unlock(&ns->base.lock);
++ }
++ return NULL;
++}
++
++static void *p_start(struct seq_file *f, loff_t *pos)
++ __acquires(ns_list_lock)
++{
++ struct aa_namespace *ns;
++ loff_t l = *pos;
++
++ read_lock(&ns_list_lock);
++ if (!list_empty(&ns_list)) {
++ struct aa_profile *profile = NULL;
++ ns = list_first_entry(&ns_list, typeof(*ns), base.list);
++ read_lock(&ns->base.lock);
++ if (!list_empty(&ns->base.profiles)) {
++ profile = list_first_entry(&ns->base.profiles,
++ typeof(*profile), base.list);
++ for ( ; profile && l > 0; l--)
++ profile = next_profile(profile);
++ return profile;
++ } else
++ read_unlock(&ns->base.lock);
++ }
++ return NULL;
++}
++
++static void *p_next(struct seq_file *f, void *p, loff_t *pos)
++{
++ struct aa_profile *profile = (struct aa_profile *) p;
++
++ (*pos)++;
++ profile = next_profile(profile);
++
++ return profile;
++}
++
++static void p_stop(struct seq_file *f, void *p)
++ __releases(ns_list_lock)
++{
++ struct aa_profile *profile = (struct aa_profile *) p;
++
++ if (profile)
++ read_unlock(&profile->ns->base.lock);
++ read_unlock(&ns_list_lock);
++}
++
++static void print_name(struct seq_file *f, struct aa_profile *profile)
++{
++ if (profile->parent) {
++ print_name(f, profile->parent);
++ seq_printf(f, "//");
++ }
++ seq_printf(f, "%s", profile->base.name);
++}
++
++static int seq_show_profile(struct seq_file *f, void *p)
++{
++ struct aa_profile *profile = (struct aa_profile *)p;
++
++ if (profile->ns != default_namespace)
++ seq_printf(f, ":%s:", profile->ns->base.name);
++ print_name(f, profile);
++ seq_printf(f, " (%s)\n",
++ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
++
++ return 0;
++}
++
++/* Used in apparmorfs.c */
++static struct seq_operations apparmorfs_profiles_op = {
++ .start = p_start,
++ .next = p_next,
++ .stop = p_stop,
++ .show = seq_show_profile,
++};
++
++static int aa_profiles_open(struct inode *inode, struct file *file)
++{
++ return seq_open(file, &apparmorfs_profiles_op);
++}
++
++
++static int aa_profiles_release(struct inode *inode, struct file *file)
++{
++ return seq_release(inode, file);
++}
++
++static struct file_operations apparmorfs_profiles_fops = {
++ .open = aa_profiles_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = aa_profiles_release,
++};
++
++/* apparmor/matching */
++static ssize_t aa_matching_read(struct file *file, char __user *buf,
++ size_t size, loff_t *ppos)
++{
++ const char *matching = "pattern=aadfa audit perms=crwxamlk/ user::other";
++
++ return simple_read_from_buffer(buf, size, ppos, matching,
++ strlen(matching));
++}
++
++static struct file_operations apparmorfs_matching_fops = {
++ .read = aa_matching_read,
++};
++
++/* apparmor/features */
++static ssize_t aa_features_read(struct file *file, char __user *buf,
++ size_t size, loff_t *ppos)
++{
++ const char *features = "file=3.1 capability=2.0 network=1.0 "
++ "change_hat=1.5 change_profile=1.1 "
++ "aanamespaces=1.1 rlimit=1.1";
++
++ return simple_read_from_buffer(buf, size, ppos, features,
++ strlen(features));
++}
++
++static struct file_operations apparmorfs_features_fops = {
++ .read = aa_features_read,
++};
++
++/* apparmor/.load */
++static ssize_t aa_profile_load(struct file *f, const char __user *buf,
++ size_t size, loff_t *pos)
++{
++ char *data;
++ ssize_t error;
++
++ data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load");
++
++ error = PTR_ERR(data);
++ if (!IS_ERR(data)) {
++ error = aa_interface_add_profiles(data, size);
++ vfree(data);
++ }
++
++ return error;
++}
++
++
++static struct file_operations apparmorfs_profile_load = {
++ .write = aa_profile_load
++};
++
++/* apparmor/.replace */
++static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
++ size_t size, loff_t *pos)
++{
++ char *data;
++ ssize_t error;
++
++ data = aa_simple_write_to_buffer(buf, size, size, pos,
++ "profile_replace");
++ error = PTR_ERR(data);
++ if (!IS_ERR(data)) {
++ error = aa_interface_replace_profiles(data, size);
++ vfree(data);
++ }
++
++ return error;
++}
++
++
++static struct file_operations apparmorfs_profile_replace = {
++ .write = aa_profile_replace
++};
++
++/* apparmor/.remove */
++static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
++ size_t size, loff_t *pos)
++{
++ char *data;
++ ssize_t error;
++
++ /*
++ * aa_remove_profile needs a null terminated string so 1 extra
++ * byte is allocated and the copied data is null terminated.
++ */
++ data = aa_simple_write_to_buffer(buf, size + 1, size, pos,
++ "profile_remove");
++
++ error = PTR_ERR(data);
++ if (!IS_ERR(data)) {
++ data[size] = 0;
++ error = aa_interface_remove_profiles(data, size);
++ vfree(data);
++ }
++
++ return error;
++}
++
++static struct file_operations apparmorfs_profile_remove = {
++ .write = aa_profile_remove
++};
++
++static struct dentry *apparmorfs_dentry;
++struct dentry *apparmorfs_null;
++struct vfsmount *apparmorfs_mnt;
++
++static void aafs_remove(const char *name)
++{
++ struct dentry *dentry;
++
++ dentry = lookup_one_len(name, apparmorfs_dentry, strlen(name));
++ if (!IS_ERR(dentry)) {
++ securityfs_remove(dentry);
++ dput(dentry);
++ }
++}
++
++static int aafs_create(const char *name, int mask, struct file_operations *fops)
++{
++ struct dentry *dentry;
++
++ dentry = securityfs_create_file(name, S_IFREG | mask, apparmorfs_dentry,
++ NULL, fops);
++
++ return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
++}
++
++void destroy_apparmorfs(void)
++{
++ if (apparmorfs_dentry) {
++ aafs_remove(".remove");
++ aafs_remove(".replace");
++ aafs_remove(".load");
++ aafs_remove("matching");
++ aafs_remove("features");
++ aafs_remove("profiles");
++ securityfs_remove(apparmorfs_dentry);
++ apparmorfs_dentry = NULL;
++ }
++}
++
++int create_apparmorfs(void)
++{
++ int error;
++
++ if (!apparmor_initialized)
++ return 0;
++
++ if (apparmorfs_dentry) {
++ AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
++ return -EEXIST;
++ }
++
++ apparmorfs_dentry = securityfs_create_dir("apparmor", NULL);
++ if (IS_ERR(apparmorfs_dentry)) {
++ error = PTR_ERR(apparmorfs_dentry);
++ apparmorfs_dentry = NULL;
++ goto error;
++ }
++ error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops);
++ if (error)
++ goto error;
++ error = aafs_create("matching", 0444, &apparmorfs_matching_fops);
++ if (error)
++ goto error;
++ error = aafs_create("features", 0444, &apparmorfs_features_fops);
++ if (error)
++ goto error;
++ error = aafs_create(".load", 0640, &apparmorfs_profile_load);
++ if (error)
++ goto error;
++ error = aafs_create(".replace", 0640, &apparmorfs_profile_replace);
++ if (error)
++ goto error;
++ error = aafs_create(".remove", 0640, &apparmorfs_profile_remove);
++ if (error)
++ goto error;
++
++ /* TODO: add support for apparmorfs_null and apparmorfs_mnt */
++
++ /* Report that AppArmor fs is enabled */
++ info_message("AppArmor Filesystem Enabled");
++ return 0;
++
++error:
++ destroy_apparmorfs();
++ AA_ERROR("Error creating AppArmor securityfs\n");
++ apparmor_disable();
++ return error;
++}
++
++fs_initcall(create_apparmorfs);
++
+--- /dev/null
++++ b/security/apparmor/audit.c
+@@ -0,0 +1,151 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor auditing functions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/audit.h>
++#include <linux/socket.h>
++
++#include "include/apparmor.h"
++#include "include/audit.h"
++#include "include/policy.h"
++
++const char *audit_mode_names[] = {
++ "normal",
++ "quiet_denied",
++ "quiet"
++ "noquiet",
++ "all"
++};
++
++static char* aa_audit_type[] = {
++ "APPARMOR_AUDIT",
++ "APPARMOR_ALLOWED",
++ "APPARMOR_DENIED",
++ "APPARMOR_HINT",
++ "APPARMOR_STATUS",
++ "APPARMOR_ERROR",
++ "APPARMOR_KILLED"
++};
++
++/*
++ * TODO:
++ * user auditing - netlink interface
++ * system control of whether user audit messages go to system log
++ */
++static int aa_audit_base(int type, struct aa_profile *profile,
++ struct aa_audit *sa, struct audit_context *audit_cxt,
++ void(*cb)(struct audit_buffer *, void *))
++{
++ struct audit_buffer *ab = NULL;
++
++ if (profile && PROFILE_KILL(profile) && type == AUDIT_APPARMOR_DENIED)
++ type = AUDIT_APPARMOR_KILL;
++
++ ab = audit_log_start(audit_cxt, sa->gfp_mask, type);
++
++ if (!ab) {
++ AA_ERROR("(%d) Unable to log event of type (%d)\n",
++ -ENOMEM, type);
++ /* don't fail operations in complain mode even if logging
++ * fails */
++ return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
++ }
++
++ if (g_apparmor_audit_header)
++ audit_log_format(ab, "type=%s ",
++ aa_audit_type[type - AUDIT_APPARMOR_AUDIT]);
++
++ if (sa->operation)
++ audit_log_format(ab, "operation=\"%s\"", sa->operation);
++
++ if (sa->info) {
++ audit_log_format(ab, " info=\"%s\"", sa->info);
++ if (sa->error)
++ audit_log_format(ab, " error=%d", sa->error);
++ }
++
++ audit_log_format(ab, " pid=%d", sa->task ?sa->task->pid : current->pid);
++
++ if (profile) {
++ pid_t pid = sa->task ? sa->task->real_parent->pid :
++ current->real_parent->pid;
++ audit_log_format(ab, " parent=%d", pid);
++ audit_log_format(ab, " profile=");
++ audit_log_untrustedstring(ab, profile->fqname);
++
++ if (profile->ns != default_namespace) {
++ audit_log_format(ab, " namespace=");
++ audit_log_untrustedstring(ab, profile->ns->base.name);
++ }
++ }
++
++ if (cb)
++ cb(ab, sa);
++
++ audit_log_end(ab);
++
++ if (type == AUDIT_APPARMOR_KILL)
++ (void)send_sig_info(SIGKILL, NULL,
++ sa->task ? sa->task : current);
++
++ return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error;
++}
++
++/**
++ * aa_audit - Log an audit event to the audit subsystem
++ * @type: audit type for the message
++ * @profile: profile to check against
++ * @sa: audit event
++ */
++int aa_audit(int type, struct aa_profile *profile, struct aa_audit *sa,
++ void(*cb)(struct audit_buffer *, void *))
++{
++ struct audit_context *audit_cxt;
++ audit_cxt = g_apparmor_logsyscall ? current->audit_context : NULL;
++
++ if (type == AUDIT_APPARMOR_AUTO) {
++ if (likely(!sa->error))
++ type = AUDIT_APPARMOR_AUDIT;
++ else if (PROFILE_COMPLAIN(profile))
++ type = AUDIT_APPARMOR_ALLOWED;
++ else
++ type = AUDIT_APPARMOR_DENIED;
++ }
++ if (PROFILE_AUDIT_MODE(profile) == AUDIT_QUIET ||
++ (type == AUDIT_APPARMOR_DENIED &&
++ PROFILE_AUDIT_MODE(profile) == AUDIT_QUIET))
++ return sa->error;
++
++ return aa_audit_base(type, profile, sa, audit_cxt, cb);
++}
++
++/**
++ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem
++ * @profile: profile to check against
++ * @gfp: memory allocation flags
++ * @msg: string describing syscall being rejected
++ */
++int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
++ const char *msg,
++ void(*cb)(struct audit_buffer *, void *))
++{
++ struct aa_audit sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.operation = "syscall";
++ sa.info = msg;
++ sa.gfp_mask = gfp;
++ sa.error = -EACCES;
++
++ return aa_audit_base(AUDIT_APPARMOR_DENIED, profile, &sa,
++ current->audit_context, NULL);
++}
+--- /dev/null
++++ b/security/apparmor/capability.c
+@@ -0,0 +1,121 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor capability mediation functions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/capability.h>
++#include <linux/errno.h>
++#include <linux/gfp.h>
++
++#include "include/apparmor.h"
++#include "include/capability.h"
++#include "include/context.h"
++#include "include/policy.h"
++#include "include/audit.h"
++
++/*
++ * Table of capability names: we generate it from capabilities.h.
++ */
++#include "capability_names.h"
++
++struct audit_cache {
++ struct task_struct *task;
++ kernel_cap_t caps;
++};
++
++static DEFINE_PER_CPU(struct audit_cache, audit_cache);
++
++struct aa_audit_caps {
++ struct aa_audit base;
++
++ int cap;
++};
++
++static void audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_caps *sa = va;
++
++ audit_log_format(ab, " name=");
++ audit_log_untrustedstring(ab, capability_names[sa->cap]);
++}
++
++static int aa_audit_caps(struct aa_profile *profile, struct aa_audit_caps *sa)
++{
++ struct audit_cache *ent;
++ int type = AUDIT_APPARMOR_AUTO;
++
++ if (likely(!sa->base.error)) {
++ /* test if auditing is being forced */
++ if (likely((PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) &&
++ !cap_raised(profile->caps.audit, sa->cap)))
++ return 0;
++ } else if (PROFILE_KILL(profile) ||
++ cap_raised(profile->caps.kill, sa->cap)) {
++ type = AUDIT_APPARMOR_KILL;
++ } else if (cap_raised(profile->caps.quiet, sa->cap) &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_NOQUIET &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) {
++ /* quiet auditing */
++ return sa->base.error;
++ }
++
++ /* Do simple duplicate message elimination */
++ ent = &get_cpu_var(audit_cache);
++ if (sa->base.task == ent->task && cap_raised(ent->caps, sa->cap)) {
++ if (PROFILE_COMPLAIN(profile))
++ return 0;
++ return sa->base.error;
++ } else {
++ ent->task = sa->base.task;
++ cap_raise(ent->caps, sa->cap);
++ }
++ put_cpu_var(audit_cache);
++
++ return aa_audit(type, profile, &sa->base, audit_cb);
++}
++
++int aa_profile_capable(struct aa_profile *profile, int cap)
++{
++ return cap_raised(profile->caps.allowed, cap) ? 0 : -EPERM;
++}
++
++/**
++ * aa_capable - test permission to use capability
++ * @task: task doing capability test against
++ * @profile: profile confining @task
++ * @cap: capability to be tested
++ * @audit: whether an audit record should be generated
++ *
++ * Look up capability in profile capability set.
++ * Returns 0 on success, or else an error code.
++ */
++int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
++ int audit)
++{
++ int error = aa_profile_capable(profile, cap);
++ struct aa_audit_caps sa;
++
++ if (!audit) {
++ if (PROFILE_COMPLAIN(profile))
++ return 0;
++ return error;
++ }
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = "capable";
++ sa.base.task = task;
++ sa.base.gfp_mask = GFP_ATOMIC;
++ sa.base.error = error;
++ sa.cap = cap;
++
++ return aa_audit_caps(profile, &sa);
++}
+--- /dev/null
++++ b/security/apparmor/context.c
+@@ -0,0 +1,209 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor functions used to manipulate object security
++ * contexts.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include "include/context.h"
++#include "include/policy.h"
++
++
++
++struct aa_task_context *aa_alloc_task_context(gfp_t flags)
++{
++ return kzalloc(sizeof(struct aa_task_context), flags);
++}
++
++void aa_free_task_context(struct aa_task_context *cxt)
++{
++ if (cxt) {
++ aa_put_profile(cxt->sys.profile);
++ aa_put_profile(cxt->sys.previous);
++ aa_put_profile(cxt->sys.onexec);
++
++ memset(cxt, 0, sizeof(*cxt));
++ kfree(cxt);
++ }
++}
++
++/*
++ * duplicate a task context, incrementing reference counts
++ */
++struct aa_task_context *aa_dup_task_context(struct aa_task_context *old_cxt,
++ gfp_t gfp)
++{
++ struct aa_task_context *cxt;
++
++ cxt = kmemdup(old_cxt, sizeof(*cxt), gfp);
++ if (!cxt)
++ return NULL;
++
++ aa_get_profile(cxt->sys.profile);
++ aa_get_profile(cxt->sys.previous);
++ aa_get_profile(cxt->sys.onexec);
++
++ return cxt;
++}
++
++/**
++ * aa_cred_policy - obtain cred's profiles
++ * @cred: cred to obtain profiles from
++ * @sys: return system profile
++ * does NOT increment reference count
++ */
++void aa_cred_policy(const struct cred *cred, struct aa_profile **sys)
++{
++ struct aa_task_context *cxt = cred->security;
++ BUG_ON(!cxt);
++ *sys = aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
++}
++
++/**
++ * aa_get_task_policy - get the cred with the task policy, and current profiles
++ * @task: task to get policy of
++ * @sys: return - pointer to system profile
++ *
++ * Only gets the cred ref count which has ref counts on the profiles returned
++ */
++struct cred *aa_get_task_policy(const struct task_struct *task,
++ struct aa_profile **sys)
++{
++ struct cred *cred = get_task_cred(task);
++ aa_cred_policy(cred, sys);
++ return cred;
++}
++
++void aa_put_task_policy(struct cred *cred)
++{
++ put_cred(cred);
++}
++
++static void replace_group(struct aa_task_cxt_group *cgrp,
++ struct aa_profile *profile)
++{
++ if (cgrp->profile == profile)
++ return;
++
++ if (!profile || (profile->flags & PFLAG_UNCONFINED) ||
++ (cgrp->profile && cgrp->profile->ns != profile->ns)) {
++ aa_put_profile(cgrp->previous);
++ aa_put_profile(cgrp->onexec);
++ cgrp->previous = NULL;
++ cgrp->onexec = NULL;
++ cgrp->token = 0;
++ }
++ aa_put_profile(cgrp->profile);
++ cgrp->profile = aa_get_profile(profile);
++}
++
++/**
++ * aa_replace_current_profiles - replace the current tasks profiles
++ * @sys: new system profile
++ *
++ * Returns: error on failure
++ */
++int aa_replace_current_profiles(struct aa_profile *sys)
++{
++ struct aa_task_context *cxt;
++ struct cred *new = prepare_creds();
++ if (!new)
++ return -ENOMEM;
++
++ cxt = new->security;
++ replace_group(&cxt->sys, sys);
++
++ commit_creds(new);
++ return 0;
++}
++
++int aa_set_current_onexec(struct aa_profile *sys)
++{
++ struct aa_task_context *cxt;
++ struct cred *new = prepare_creds();
++ if (!new)
++ return -ENOMEM;
++
++ cxt = new->security;
++ aa_put_profile(cxt->sys.onexec);
++ cxt->sys.onexec = aa_get_profile(sys);
++
++ commit_creds(new);
++ return 0;
++}
++
++/*
++ * Do the actual cred switching of a changehat
++ * profile must be valid
++ */
++int aa_set_current_hat(struct aa_profile *profile, u64 token)
++{
++ struct aa_task_context *cxt;
++ struct cred *new = prepare_creds();
++ if (!new)
++ return -ENOMEM;
++
++ cxt = new->security;
++ if (!cxt->sys.previous) {
++ cxt->sys.previous = cxt->sys.profile;
++ cxt->sys.token = token;
++ } else if (cxt->sys.token == token) {
++ aa_put_profile(cxt->sys.profile);
++ } else {
++ /* previous_profile && cxt->token != token */
++ abort_creds(new);
++ return -EACCES;
++ }
++ cxt->sys.profile = aa_get_profile(profile);
++ /* clear exec on switching context */
++ aa_put_profile(cxt->sys.onexec);
++ cxt->sys.onexec = NULL;
++
++ commit_creds(new);
++ return 0;
++}
++
++/*
++ * Attempt to return out of a hat to the previous profile
++ */
++int aa_restore_previous_profile(u64 token)
++{
++ struct aa_task_context *cxt;
++ struct cred *new = prepare_creds();
++ if (!new)
++ return -ENOMEM;
++
++ cxt = new->security;
++ if (cxt->sys.token != token) {
++ abort_creds(new);
++ return -EACCES;
++ }
++ /* ignore restores when there is no saved profile */
++ if (!cxt->sys.previous) {
++ abort_creds(new);
++ return 0;
++ }
++
++ aa_put_profile(cxt->sys.profile);
++ cxt->sys.profile = aa_profile_newest(cxt->sys.previous);
++ if (unlikely(cxt->sys.profile != cxt->sys.previous)) {
++ aa_get_profile(cxt->sys.profile);
++ aa_put_profile(cxt->sys.previous);
++ }
++ /* clear exec && prev information when restoring to previous context */
++ cxt->sys.previous = NULL;
++ cxt->sys.token = 0;
++ aa_put_profile(cxt->sys.onexec);
++ cxt->sys.onexec = NULL;
++
++ commit_creds(new);
++ return 0;
++}
+--- /dev/null
++++ b/security/apparmor/domain.c
+@@ -0,0 +1,693 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor policy attachment and domain transitions
++ *
++ * Copyright (C) 2002-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/errno.h>
++#include <linux/fdtable.h>
++#include <linux/file.h>
++#include <linux/mount.h>
++#include <linux/syscalls.h>
++#include <linux/tracehook.h>
++
++#include "include/audit.h"
++#include "include/apparmorfs.h"
++#include "include/context.h"
++#include "include/domain.h"
++#include "include/file.h"
++#include "include/ipc.h"
++#include "include/match.h"
++#include "include/path.h"
++#include "include/policy.h"
++
++/**
++ * aa_free_domain_entries - free entries in a domain table
++ * @domain: the domain table to free
++ */
++void aa_free_domain_entries(struct aa_domain *domain)
++{
++ int i;
++
++ if (!domain->table)
++ return;
++
++ for (i = 0; i < domain->size; i++)
++ kfree(domain->table[i]);
++ kfree(domain->table);
++}
++
++/*
++ * check if the task is ptraced and if so if the tracing task is allowed
++ * to trace the new domain
++ */
++static int aa_may_change_ptraced_domain(struct task_struct *task,
++ struct aa_profile *to_profile)
++{
++ struct task_struct *tracer;
++ struct cred *cred = NULL;
++ struct aa_profile *tracerp = NULL;
++ int error = 0;
++
++ rcu_read_lock();
++ tracer = tracehook_tracer_task(task);
++ if (tracer)
++ cred = aa_get_task_policy(tracer, &tracerp);
++ rcu_read_unlock();
++
++ if (!tracerp)
++ return error;
++
++ error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
++ put_cred(cred);
++
++ return error;
++}
++
++/**
++ * change_profile_perms
++ */
++static struct file_perms change_profile_perms(struct aa_profile *profile,
++ struct aa_namespace *ns,
++ const char *name,
++ unsigned int *rstate)
++{
++ struct file_perms perms;
++ struct path_cond cond = { 0, 0 };
++ unsigned int state;
++
++ if (!profile) {
++ /* unconfined */
++ perms.allowed = AA_MAY_CHANGE_PROFILE;
++ perms.xindex = perms.dindex = 0;
++ perms.audit = perms.quiet = perms.kill = 0;
++ *rstate = 0;
++ return perms;
++ } else if ((ns == profile->ns)) {
++ /* try matching against rules with out namespace prependend */
++ perms = aa_str_perms(profile->file.dfa, DFA_START, name, &cond,
++ rstate);
++ if (COMBINED_PERM_MASK(perms) & AA_MAY_CHANGE_PROFILE)
++ return perms;
++ }
++
++ /* try matching with namespace name and then profile */
++ if (!profile->file.dfa)
++ return nullperms;
++
++ state = aa_dfa_match(profile->file.dfa, DFA_START, ns->base.name);
++ state = aa_dfa_null_transition(profile->file.dfa, state);
++ return aa_str_perms(profile->file.dfa, state, name, &cond, rstate);
++}
++
++/*
++ * TODO: fix parser to detect unconfined, inherit,
++ * check for next name in list of names that is double null terminated
++ * The names list is a set of strings that \0 seperated with a double
++ * \0 terminating the list
++ * names that belong to namespaces begin with a :
++ * and are followed by a name a \0 seperated name. If the name is
++ * unspecified it is 0 length. This double \0\0 does not count as
++ * the end of the list
++ *
++ * profile\0\0 # single profile
++ * profile\0profile\0\0 # 2 profiles in list
++ * :namespace\0profile\0\0 # profile & namespace
++ * :namespace\0\0\0 # namespace without profile
++ * :namespace\0\0profile\0\0 # namespace without profile followed by profile
++*/
++static const char *next_name(int xtype, const char *name)
++{
++/* TODO: fix parser and enable
++ if (xtype == AA_X_TABLE) {
++ name = name + strlen(name) + 1;
++ if (*name != 0)
++ return name;
++ }
++*/
++ return NULL;
++}
++
++/*
++ * get target profile for xindex
++ */
++static struct aa_profile *x_to_profile(struct aa_namespace *ns,
++ struct aa_profile *profile,
++ const char *name, u16 xindex)
++
++{
++ struct aa_profile *new_profile = NULL;
++ u16 xtype = xindex & AA_X_TYPE_MASK;
++ int index = xindex & AA_X_INDEX_MASK;
++
++ if (!profile)
++ profile = ns->unconfined;
++
++ switch(xtype) {
++ case AA_X_NONE:
++ /* fail exec unless ix || ux fallback - handled by caller */
++ return ERR_PTR(-EACCES);
++ case AA_X_NAME:
++ break;
++ case AA_X_TABLE:
++ if (index > profile->file.trans.size) {
++ AA_ERROR("Invalid named transition\n");
++ return ERR_PTR(-EACCES);
++ }
++ name = profile->file.trans.table[index];
++ break;
++ }
++
++ for (; !new_profile && name; name = next_name(xtype, name)) {
++ struct aa_namespace *new_ns;
++ const char *xname = NULL;
++
++ new_ns = NULL;
++ if (xindex & AA_X_CHILD) {
++ new_profile = aa_find_child(profile, name);
++ if (new_profile)
++ return new_profile;
++ continue;
++ } else if (*name == ':') {
++ /* switching namespace */
++ const char *ns_name = name + 1;
++ name = xname = ns_name + strlen(ns_name) + 1;
++ if (!*xname)
++ /* no name so use profile name */
++ xname = profile->fqname;
++ if (*ns_name == '@') {
++ /* TODO: variable support */
++ ;
++ }
++ new_ns = aa_find_namespace(ns_name);
++ if (!new_ns)
++ continue;
++ } else if (*name == '@') {
++ /* TODO: variable support */
++
++ } else {
++ xname = name;
++ }
++
++ new_profile = aa_find_profile_by_fqname(new_ns ? new_ns : ns,
++ xname);
++ aa_put_namespace(new_ns);
++ }
++
++ if (!new_profile)
++ return ERR_PTR(-ENOENT);
++
++ return new_profile;
++}
++
++int apparmor_bprm_set_creds(struct linux_binprm *bprm)
++{
++ struct aa_task_context *cxt;
++ struct aa_profile *profile, *new_profile = NULL;
++ struct aa_namespace *ns;
++ char *buffer = NULL;
++ unsigned int state = DFA_START;
++ struct aa_audit_file sa;
++ struct path_cond cond = { bprm->file->f_path.dentry->d_inode->i_uid,
++ bprm->file->f_path.dentry->d_inode->i_mode };
++
++ sa.base.error = cap_bprm_set_creds(bprm);
++ if (sa.base.error)
++ return sa.base.error;
++
++ if (bprm->cred_prepared)
++ return 0;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = "exec";
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.request = MAY_EXEC;
++ sa.cond = &cond;
++
++ cxt = bprm->cred->security;
++ BUG_ON(!cxt);
++
++ profile = aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
++ ns = cxt->sys.profile->ns;
++
++ sa.base.error = aa_get_name(&bprm->file->f_path, 0, &buffer,
++ (char **) &sa.name);
++ if (sa.base.error) {
++ if (profile || profile->flags & PFLAG_IX_ON_NAME_ERROR)
++ sa.base.error = 0;
++ sa.base.info = "Exec failed name resolution";
++ sa.name = bprm->filename;
++ goto audit;
++ }
++
++ if (!profile) {
++ /* unconfined task - attach profile if one matches */
++ new_profile = aa_sys_find_attach(ns, sa.name);
++ if (!new_profile)
++ goto cleanup;
++ goto apply;
++ } else if (cxt->sys.onexec) {
++ /*
++ * onexec permissions are stored in a pair, rewalk the
++ * dfa to get start of the exec path match.
++ */
++ sa.perms = change_profile_perms(profile, cxt->sys.onexec->ns,
++ sa.name, &state);
++ state = aa_dfa_null_transition(profile->file.dfa, state);
++ }
++ sa.perms = aa_str_perms(profile->file.dfa, state, sa.name, &cond,
++ NULL);
++ if (cxt->sys.onexec && sa.perms.allowed & AA_MAY_ONEXEC) {
++ new_profile = cxt->sys.onexec;
++ cxt->sys.onexec = NULL;
++ sa.base.info = "change_profile onexec";
++ } else if (sa.perms.allowed & MAY_EXEC) {
++ new_profile = x_to_profile(ns, profile, sa.name,
++ sa.perms.xindex);
++ if (IS_ERR(new_profile)) {
++ if (sa.perms.xindex & AA_X_INHERIT) {
++ /* (p|c|n)ix - don't change profile */
++ sa.base.info = "ix fallback";
++ goto x_clear;
++ } else if (sa.perms.xindex & AA_X_UNCONFINED) {
++ new_profile = aa_get_profile(ns->unconfined);
++ sa.base.info = "ux fallback";
++ } else {
++ sa.base.error = PTR_ERR(new_profile);
++ if (sa.base.error == -ENOENT)
++ sa.base.info = "profile not found";
++ new_profile = NULL;
++ }
++ }
++ } else if (PROFILE_COMPLAIN(profile)) {
++ new_profile = aa_alloc_null_profile(profile, 0);
++ sa.base.error = -EACCES;
++ if (!new_profile)
++ sa.base.error = -ENOMEM;
++ sa.name2 = new_profile->fqname;
++ sa.perms.xindex |= AA_X_UNSAFE;
++ } else {
++ sa.base.error = -EACCES;
++ }
++
++ if (!new_profile)
++ goto audit;
++
++ if (profile == new_profile) {
++ aa_put_profile(new_profile);
++ goto audit;
++ }
++
++ if (bprm->unsafe & LSM_UNSAFE_SHARE) {
++ /* FIXME: currently don't mediate shared state */
++ ;
++ }
++
++ if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
++ sa.base.error = aa_may_change_ptraced_domain(current,
++ new_profile);
++ if (sa.base.error)
++ goto audit;
++ }
++
++ /* Determine if secure exec is needed.
++ * Can be at this point for the following reasons:
++ * 1. unconfined switching to confined
++ * 2. confined switching to different confinement
++ * 3. confined switching to unconfined
++ *
++ * Cases 2 and 3 are marked as requiring secure exec
++ * (unless policy specified "unsafe exec")
++ *
++ * bprm->unsafe is used to cache the AA_X_UNSAFE permission
++ * to avoid having to recompute in secureexec
++ */
++ if (!(sa.perms.xindex & AA_X_UNSAFE))
++ bprm->unsafe |= AA_SECURE_X_NEEDED;
++
++apply:
++ /* when transitioning profiles clear unsafe personality bits */
++ bprm->per_clear |= PER_CLEAR_ON_SETID;
++
++ aa_put_profile(cxt->sys.profile);
++ cxt->sys.profile = new_profile;
++
++x_clear:
++ aa_put_profile(cxt->sys.previous);
++ aa_put_profile(cxt->sys.onexec);
++ cxt->sys.previous = NULL;
++ cxt->sys.onexec = NULL;
++ cxt->sys.token = 0;
++
++audit:
++ sa.base.error = aa_audit_file(profile, &sa);
++
++cleanup:
++ kfree(buffer);
++
++ return sa.base.error;
++}
++
++int apparmor_bprm_secureexec(struct linux_binprm *bprm)
++{
++ int ret = cap_bprm_secureexec(bprm);
++
++ /* the decision to use secure exec is computed in set_creds
++ * and stored in bprm->unsafe. The AppArmor X_UNSAFE flag is
++ * indicates don't
++ */
++ if (!ret && (bprm->unsafe & AA_SECURE_X_NEEDED))
++ ret = 1;
++
++ return ret;
++}
++
++
++static int aa_revalidate_perm(struct aa_profile *profile, struct file *file,
++ char *buffer, int size)
++{
++ umode_t mode = file->f_path.dentry->d_inode->i_mode;
++ char *name;
++ int error;
++
++ error = aa_get_name_to_buffer(&file->f_path, S_ISDIR(mode), buffer,
++ size, &name);
++ return aa_file_common_perm(profile, "file_inherit", file,
++ aa_map_file_to_perms(file), name,
++ error);
++}
++
++static void revalidate_file(struct aa_profile *profile, struct file *file,
++ unsigned long i, char *buffer, int size,
++ struct cred *cred)
++{
++ if (aa_revalidate_perm(profile, file, buffer, size)) {
++ struct file *devnull = NULL;
++ int fd = get_unused_fd();
++ sys_close(i);
++ if (fd != i) {
++ if (fd >= 0)
++ put_unused_fd(fd);
++ return;
++ }
++ if (devnull) {
++ get_file(devnull);
++ } else if (apparmorfs_null) {
++ devnull = dentry_open(dget(apparmorfs_null),
++ mntget(apparmorfs_mnt),
++ O_RDWR, cred);
++ if (IS_ERR(devnull)) {
++ devnull = NULL;
++ put_unused_fd(fd);
++ return;
++ }
++ } else {
++ /* apparmorfs_null not setup */
++ put_unused_fd(fd);
++ return;
++ }
++ fd_install(fd, devnull);
++ }
++}
++
++/*
++ * derived from security/selinux/hooks.c: flush_unauthorized_files &&
++ * fs/exec.c:flush_old_files
++ */
++static int revalidate_files(struct aa_profile *profile,
++ struct files_struct *files, gfp_t gfp,
++ struct cred *cred)
++{
++ struct file *file;
++ struct fdtable *fdt;
++ long j = -1;
++ char *buffer = kmalloc(g_apparmor_path_max, gfp);
++ if (!buffer)
++ return -ENOMEM;
++
++ spin_lock(&files->file_lock);
++ for (;;) {
++ unsigned long set, i;
++
++ j++;
++ i = j * __NFDBITS;
++ fdt = files_fdtable(files);
++ if (i >= fdt->max_fds)
++ break;
++ set = fdt->open_fds->fds_bits[j];
++ if (!set)
++ continue;
++ spin_unlock(&files->file_lock);
++ for ( ; set ; i++,set >>= 1) {
++ if (set & 1) {
++ file = fget(i);
++ if (!file)
++ continue;
++ revalidate_file(profile, file, i, buffer,
++ g_apparmor_path_max, cred);
++ fput(file);
++ }
++ }
++ spin_lock(&files->file_lock);
++ }
++ spin_unlock(&files->file_lock);
++ kfree(buffer);
++ return 0;
++}
++
++int apparmor_bprm_committing_creds(struct linux_binprm *bprm)
++{
++ struct aa_profile *profile;
++ struct cred *cred = aa_get_task_policy(current, &profile);
++ struct aa_task_context *new_cxt = bprm->cred->security;
++ int error;
++
++ if ((new_cxt->sys.profile == profile) ||
++ (new_cxt->sys.profile->flags & PFLAG_UNCONFINED)) {
++ put_cred(cred);
++ return 0;
++ }
++ put_cred(cred);
++
++ error = revalidate_files(new_cxt->sys.profile, current->files,
++ GFP_KERNEL, bprm->cred);
++ if (error)
++ return error;
++
++ current->pdeath_signal = 0;
++
++ /* reset soft limits and set hard limits for the new profile */
++ __aa_transition_rlimits(profile, new_cxt->sys.profile);
++ return 0;
++}
++
++void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
++{
++ /* TODO: cleanup signals - ipc mediation */
++ return;
++}
++
++/**
++ * aa_change_hat - change hat to/from subprofile
++ * @hat_name: hat to change to
++ * @token: magic value to validate the hat change
++ * @permtest: true if this is just a permission test
++ *
++ * Change to new @hat_name, and store the @hat_magic in the current task
++ * context. If the new @hat_name is %NULL and the @token matches that
++ * stored in the current task context and is not 0, return to the top level
++ * profile.
++ * Returns %0 on success, error otherwise.
++ */
++int aa_change_hat(const char *hat_name, u64 token, int permtest)
++{
++ const struct cred *cred;
++ struct aa_task_context *cxt;
++ struct aa_profile *profile, *previous_profile, *hat = NULL;
++ struct aa_audit_file sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.base.operation = "change_hat";
++
++ cred = aa_current_policy(&profile);
++ cxt = cred->security;
++ previous_profile = cxt->sys.previous;
++ token = cxt->sys.token;
++
++ if (!profile) {
++ sa.base.info = "unconfined";
++ sa.base.error = -EPERM;
++ goto audit;
++ }
++
++ if (hat_name) {
++ if (previous_profile)
++ sa.name = previous_profile->fqname;
++ else
++ sa.name = profile->fqname;
++
++ sa.name2 = profile->ns->base.name;
++
++ if (PROFILE_IS_HAT(profile))
++ hat = aa_find_child(profile->parent, hat_name);
++ else
++ hat = aa_find_child(profile, hat_name);
++ if (!hat) {
++ sa.base.info = "hat not found";
++ sa.base.error = -ENOENT;
++ if (permtest || !PROFILE_COMPLAIN(profile))
++ goto audit;
++ hat = aa_alloc_null_profile(profile, 1);
++ if (!hat) {
++ sa.base.info = "failed null profile create";
++ sa.base.error = -ENOMEM;
++ goto audit;
++ }
++ } else if (!PROFILE_IS_HAT(hat)) {
++ sa.base.info = "target not hat";
++ sa.base.error = -EPERM;
++ goto audit;
++ }
++
++ sa.base.error = aa_may_change_ptraced_domain(current, hat);
++ if (sa.base.error) {
++ sa.base.info = "ptraced";
++ sa.base.error = -EPERM;
++ goto audit;
++ }
++
++ if (!permtest) {
++ sa.base.error = aa_set_current_hat(hat, token);
++ if (sa.base.error == -EACCES) {
++ (void)send_sig_info(SIGKILL, NULL, current);
++ sa.base.error = aa_audit(AUDIT_APPARMOR_KILL,
++ profile, &sa.base,
++ file_audit_cb);
++ goto out;
++ }
++ }
++ } else if (previous_profile)
++ sa.base.error = aa_restore_previous_profile(token);
++ /* else
++ ignore restores when there is no saved profile
++ */
++
++audit:
++ if (!permtest)
++ sa.base.error = aa_audit_file(profile, &sa);
++
++
++out:
++ aa_put_profile(hat);
++
++ return sa.base.error;
++}
++
++/**
++ * aa_change_profile - perform a one-way profile transition
++ * @ns_name: name of the profile namespace to change to
++ * @fqname: name of profile to change to
++ * @onexec: whether this transition is to take place immediately or at exec
++ * @permtest: true if this is just a permission test
++ *
++ * Change to new profile @name. Unlike with hats, there is no way
++ * to change back. If @onexec then the transition is delayed until
++ * the next exec.
++ *
++ * Returns %0 on success, error otherwise.
++ */
++int aa_change_profile(const char *ns_name, const char *fqname, int onexec,
++ int permtest)
++{
++ const struct cred *cred;
++ struct aa_task_context *cxt;
++ struct aa_profile *profile, *target = NULL;
++ struct aa_namespace *ns = NULL;
++ struct aa_audit_file sa;
++ char *name = NULL;
++
++ if (!name && !ns_name)
++ return -EINVAL;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.gfp_mask = GFP_KERNEL;
++ if (onexec)
++ sa.base.operation = "change_onexec";
++ else
++ sa.base.operation = "change_profile";
++
++ cred = aa_current_policy(&profile);
++ cxt = cred->security;
++ ns = aa_get_namespace(cxt->sys.profile->ns);
++
++ if (ns_name) {
++ sa.name2 = ns_name;
++ aa_put_namespace(ns);
++ ns = aa_find_namespace(ns_name);
++ if (!ns) {
++ /* we don't create new namespace in complain mode */
++ sa.base.info = "namespace not found";
++ sa.base.error = -ENOENT;
++ goto audit;
++ }
++ } else
++ sa.name2 = ns->base.name;
++
++ /* if the name was not specified, use the name of the current profile */
++ if (!fqname) {
++ if (!profile)
++ fqname = ns->unconfined->fqname;
++ else
++ fqname = profile->fqname;
++ }
++ sa.name = fqname;
++
++ sa.perms = change_profile_perms(profile, ns, fqname, NULL);
++
++ if (!(sa.perms.allowed & AA_MAY_CHANGE_PROFILE)) {
++ sa.base.error = -EACCES;
++ goto audit;
++ }
++
++ target = aa_find_profile_by_fqname(ns, fqname);
++ if (!target) {
++ sa.base.info = "profile not found";
++ sa.base.error = -ENOENT;
++ if (permtest || !PROFILE_COMPLAIN(profile))
++ goto audit;
++ target = aa_alloc_null_profile(profile, 0);
++ }
++
++ /* check if tracing task is allowed to trace target domain */
++ sa.base.error = aa_may_change_ptraced_domain(current, target);
++ if (sa.base.error) {
++ sa.base.info = "ptrace prevents transition";
++ goto audit;
++ }
++
++ if (permtest)
++ goto audit;
++
++ if (onexec)
++ sa.base.error = aa_set_current_onexec(target);
++ else
++ sa.base.error = aa_replace_current_profiles(target);
++
++audit:
++ if (!permtest)
++ sa.base.error = aa_audit_file(profile, &sa);
++
++ aa_put_namespace(ns);
++ aa_put_profile(target);
++
++ return sa.base.error;
++}
+--- /dev/null
++++ b/security/apparmor/file.c
+@@ -0,0 +1,427 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor mediation of files
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include "include/apparmor.h"
++#include "include/audit.h"
++#include "include/file.h"
++#include "include/match.h"
++#include "include/path.h"
++#include "include/policy.h"
++
++struct file_perms nullperms;
++
++static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer,
++ u16 mask, u16 xindex)
++{
++
++ /* const char xchar[] = "PpCc";*/
++
++ char *m = buffer;
++
++ if (mask & AA_EXEC_MMAP)
++ *m++ = 'm';
++ if (mask & AA_MAY_CREATE)
++ *m++ = 'c';
++ if (mask & MAY_READ)
++ *m++ = 'r';
++ if (mask & MAY_WRITE)
++ *m++ = 'w';
++ else if (mask & MAY_APPEND)
++ *m++ = 'a';
++ if (mask & AA_MAY_LINK)
++ *m++ = 'l';
++ if (mask & AA_MAY_LOCK)
++ *m++ = 'k';
++ if (mask & MAY_EXEC) {
++ *m++ = 'x';
++
++/* FIXME: only want more advanced auditing of x if in audit/hint mode
++ u16 index = xindex & AA_X_INDEX_MASK;
++ u16 xtype = xindex & AA_X_TYPE_MASK;
++ if (xtype > AA_X_NONE)
++ *m++ = xchar[(xindex >> 12) & 0x3];
++ if (xindex & AA_X_INHERIT) {
++ *m++ = 'i';
++ } else if (xindex & AA_X_UNCONFINED) {
++ if (xindex & AA_X_UNSAFE)
++ *m++ = 'u';
++ else
++ *m++ = 'U';
++ }
++ *m++ = 'x';
++ / * at most 7 character including trailing \0 * /
++ if (xtype == AA_X_VARIABLE) {
++ m += sprintf(m, "->v%x", index);
++ } else if (xtype == AA_X_TABLE) {
++ m += sprintf(m, "->n%x", index);
++ }
++*/
++ }
++ *m++ = '\0';
++}
++
++static void aa_audit_file_mask(struct audit_buffer *ab, const char *name,
++ u16 mask, int xindex, int owner)
++{
++/* char str[18]; */
++ char str[10];
++
++ aa_audit_file_sub_mask(ab, str, mask, xindex);
++ if (owner)
++ audit_log_format(ab, " %s=\"%s::\"", name, str);
++ else
++ audit_log_format(ab, " %s=\"::%s\"", name, str);
++}
++
++void file_audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_file *sa = va;
++ u16 denied = sa->request & ~sa->perms.allowed;
++ uid_t fsuid;
++
++ if (sa->base.task)
++ fsuid = task_uid(sa->base.task);
++ else
++ fsuid = current_fsuid();
++
++ if (sa->request & AA_AUDIT_FILE_MASK)
++ aa_audit_file_mask(ab, "requested_mask", sa->request,
++ AA_X_NONE, fsuid == sa->cond->uid);
++
++ if (denied & AA_AUDIT_FILE_MASK)
++ aa_audit_file_mask(ab, "denied_mask", denied, sa->perms.xindex,
++ fsuid == sa->cond->uid);
++
++ if (sa->request & AA_AUDIT_FILE_MASK) {
++ audit_log_format(ab, " fsuid=%d", fsuid);
++ audit_log_format(ab, " ouid=%d", sa->cond->uid);
++ }
++
++ if (sa->name) {
++ audit_log_format(ab, " name=");
++ audit_log_untrustedstring(ab, sa->name);
++ }
++
++ if (sa->name2) {
++ audit_log_format(ab, " name2=");
++ audit_log_untrustedstring(ab, sa->name2);
++ }
++
++ if (sa->name3) {
++ audit_log_format(ab, " name3=");
++ audit_log_untrustedstring(ab, sa->name3);
++ }
++}
++
++int aa_audit_file(struct aa_profile *profile, struct aa_audit_file *sa)
++{
++ int type = AUDIT_APPARMOR_AUTO;
++
++ if (likely(!sa->base.error)) {
++ u16 mask = sa->perms.audit;
++
++ if (unlikely(PROFILE_AUDIT_MODE(profile) == AUDIT_ALL))
++ mask = 0xffff;
++
++ /* mask off perms that are not being force audited */
++ sa->request &= mask;
++
++ if (likely(!sa->request))
++ return 0;
++ } else {
++ /* quiet auditing of specific known rejects */
++ u16 mask = sa->perms.quiet;
++ u16 denied = sa->request & ~sa->perms.allowed;
++
++ if (denied & sa->perms.kill)
++ type = AUDIT_APPARMOR_KILL;
++
++ /* assumes quiet and kill do not overlap */
++ if ((denied & mask) &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_NOQUIET &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_ALL)
++ sa->request &= ~mask;
++
++ if (!sa->request)
++ return PROFILE_COMPLAIN(profile) ? 0 : sa->base.error;
++ }
++ return aa_audit(type, profile, (struct aa_audit *)sa, file_audit_cb);
++}
++
++/* FIXME: convert from dfa + state to permission entry */
++struct file_perms aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
++ struct path_cond *cond)
++{
++ struct file_perms perms;
++
++ /* FIXME: change over to new dfa format */
++ /* currently file perms are encoded in the dfa */
++ perms.kill = 0;
++ perms.dindex = 0;
++
++ if (current_fsuid() == cond->uid) {
++ perms.allowed = dfa_user_allow(dfa, state);
++ perms.audit = dfa_user_audit(dfa, state);
++ perms.quiet = dfa_user_quiet(dfa, state);
++ perms.xindex = dfa_user_xindex(dfa, state);
++ } else {
++ perms.allowed = dfa_other_allow(dfa, state);
++ perms.audit = dfa_other_audit(dfa, state);
++ perms.quiet = dfa_other_quiet(dfa, state);
++ perms.xindex = dfa_other_xindex(dfa, state);
++ }
++ /* in the old mapping MAY_WRITE implies AA_MAY_CREATE */
++ perms.allowed |= (perms.allowed & MAY_WRITE) << 6;
++ perms.audit |= (perms.audit & MAY_WRITE) << 6;
++ perms.quiet |= (perms.quiet & MAY_WRITE) << 6;
++
++ /* in the old mapping AA_MAY_LOCK and link subset are overlayed
++ * and only determined by which part of a pair they are in
++ */
++ if (perms.allowed & AA_MAY_LOCK)
++ perms.allowed |= AA_LINK_SUBSET;
++
++ /* change_profile wasn't determined by ownership in old mapping */
++ if (ACCEPT_TABLE2(dfa)[state] & 0x80000000)
++ perms.allowed |= AA_MAY_CHANGE_PROFILE;
++
++ return perms;
++}
++
++struct file_perms aa_str_perms(struct aa_dfa *dfa, unsigned int start,
++ const char *name, struct path_cond *cond,
++ unsigned int *rstate)
++{
++ unsigned int state;
++ if (!dfa)
++ return nullperms;
++
++ state = aa_dfa_match(dfa, start, name);
++
++ if (rstate)
++ *rstate = state;
++
++ /* TODO: convert to new dfa format */
++
++ return aa_compute_perms(dfa, state, cond);
++}
++
++int aa_pathstr_perm(struct aa_profile *profile, const char *op,
++ const char *name, u16 request, struct path_cond *cond)
++{
++ struct aa_audit_file sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = op;
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.request = request;
++ sa.name = name;
++ sa.cond = cond;
++
++ sa.perms = aa_str_perms(profile->file.dfa, DFA_START, sa.name, cond,
++ NULL);
++ if (request & ~sa.perms.allowed)
++ sa.base.error = -EACCES;
++ return aa_audit_file(profile, &sa);
++}
++
++int aa_path_perm(struct aa_profile *profile, const char *operation,
++ struct path *path, u16 request, struct path_cond *cond)
++{
++ struct aa_audit_file sa;
++ char *buffer, *name;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = operation;
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.request = request;
++ sa.cond = cond;
++
++ sa.base.error = aa_get_name(path, S_ISDIR(cond->mode), &buffer,
++ &name);
++ sa.name = name;
++ if (sa.base.error) {
++ sa.perms = nullperms;
++ if (sa.base.error == -ENOENT)
++ sa.base.info = "Failed name lookup - deleted entry";
++ else if (sa.base.error == -ESTALE)
++ sa.base.info = "Failed name lookup - disconnected path";
++ else if (sa.base.error == -ENAMETOOLONG)
++ sa.base.info = "Failed name lookup - name too long";
++ else
++ sa.base.info = "Failed name lookup";
++ } else {
++ sa.perms = aa_str_perms(profile->file.dfa, DFA_START, sa.name,
++ cond, NULL);
++ if (request & ~sa.perms.allowed)
++ sa.base.error = -EACCES;
++ }
++ sa.base.error = aa_audit_file(profile, &sa);
++ kfree(buffer);
++
++ return sa.base.error;
++}
++
++int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
++ struct path *new_dir, struct dentry *new_dentry)
++{
++ struct path link = { new_dir->mnt, new_dentry };
++ struct path target = { new_dir->mnt, old_dentry };
++ struct path_cond cond = { old_dentry->d_inode->i_uid,
++ old_dentry->d_inode->i_mode };
++ char *buffer = NULL, *buffer2 = NULL;
++ char *lname, *tname;
++ struct file_perms perms;
++ unsigned int state;
++
++ struct aa_audit_file sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = "link";
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.request = AA_MAY_LINK;
++ sa.cond = &cond;
++ sa.perms = nullperms;
++
++ sa.base.error = aa_get_name(&link, 0, &buffer, &lname);
++ sa.name = lname;
++ if (sa.base.error)
++ goto audit;
++
++ sa.base.error = aa_get_name(&target, 0, &buffer2, &tname);
++ sa.name2 = tname;
++ if (sa.base.error)
++ goto audit;
++
++
++ sa.perms = aa_str_perms(profile->file.dfa, DFA_START, sa.name, &cond,
++ &state);
++ sa.perms.audit &= AA_MAY_LINK;
++ sa.perms.quiet &= AA_MAY_LINK;
++ sa.perms.kill &= AA_MAY_LINK;
++
++ if ((!sa.perms.allowed & AA_MAY_LINK)) {
++ sa.base.error = -EACCES;
++ goto audit;
++ }
++
++ /* test to see if target can be paired with link */
++ state = aa_dfa_null_transition(profile->file.dfa, state);
++ perms = aa_str_perms(profile->file.dfa, state, sa.name2, &cond, NULL);
++ if (!(perms.allowed & AA_MAY_LINK)) {
++ sa.base.error = -EACCES;
++ sa.base.info = "target restricted";
++ goto audit;
++ }
++
++ /* done if link subset test is not required */
++ if (!(perms.allowed & AA_LINK_SUBSET))
++ goto audit;
++
++ /* Do link perm subset test requiring allowed permission on link are a
++ * subset of the allowed permissions on target.
++ */
++ perms = aa_str_perms(profile->file.dfa, DFA_START, sa.name2, &cond,
++ NULL);
++
++ /* AA_MAY_LINK is not considered in the subset test */
++ sa.request = sa.perms.allowed & ~AA_MAY_LINK;
++ sa.perms.allowed &= perms.allowed | AA_MAY_LINK;
++
++ sa.request |= AA_AUDIT_FILE_MASK & (sa.perms.allowed & ~perms.allowed);
++ if (sa.request & ~sa.perms.allowed)
++ sa.base.error = -EACCES;
++ else if (sa.perms.allowed & MAY_EXEC) {
++ if (((sa.perms.xindex & ~AA_X_UNSAFE) !=
++ (perms.xindex &~AA_X_UNSAFE)) ||
++ ((sa.perms.xindex & AA_X_UNSAFE) &&
++ !(perms.xindex & AA_X_UNSAFE))) {
++ sa.perms.allowed &= ~MAY_EXEC;
++ sa.request |= MAY_EXEC;
++ sa.base.error = -EACCES;
++ sa.base.info = "link not subset of target";
++ }
++ }
++
++audit:
++ sa.base.error = aa_audit_file(profile, &sa);
++ kfree(buffer);
++ kfree(buffer2);
++
++ return sa.base.error;
++}
++
++
++static inline int aa_is_deleted_file(struct dentry *dentry)
++{
++ if (d_unhashed(dentry) && dentry->d_inode->i_nlink == 0)
++ return 1;
++ return 0;
++}
++
++int aa_file_common_perm(struct aa_profile *profile, const char *operation,
++ struct file *file, u16 request, const char *name,
++ int error)
++{
++ struct path_cond cond = { .uid = file->f_path.dentry->d_inode->i_uid,
++ .mode = file->f_path.dentry->d_inode->i_mode };
++ struct aa_audit_file sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = operation;
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.request = request;
++ sa.base.error = error;
++ sa.name = name;
++ sa.cond = &cond;
++
++ if (sa.base.error) {
++ sa.perms = nullperms;
++ if (sa.base.error == -ENOENT &&
++ aa_is_deleted_file(file->f_path.dentry)) {
++ /* Access to open files that are deleted are
++ * give a pass (implicit delegation
++ */
++ sa.base.error = 0;
++ sa.perms.allowed = sa.request;
++ } else if (sa.base.error == -ENOENT)
++ sa.base.info = "Failed name lookup - deleted entry";
++ else if (sa.base.error == -ESTALE)
++ sa.base.info = "Failed name lookup - disconnected path";
++ else if (sa.base.error == -ENAMETOOLONG)
++ sa.base.info = "Failed name lookup - name too long";
++ else
++ sa.base.info = "Failed name lookup";
++ } else {
++ sa.perms = aa_str_perms(profile->file.dfa, DFA_START, sa.name,
++ &cond, NULL);
++ if (request & ~sa.perms.allowed)
++ sa.base.error = -EACCES;
++ }
++ sa.base.error = aa_audit_file(profile, &sa);
++
++ return sa.base.error;
++}
++
++int aa_file_perm(struct aa_profile *profile, const char *operation,
++ struct file *file, u16 request)
++{
++ char *buffer, *name;
++ umode_t mode = file->f_path.dentry->d_inode->i_mode;
++ int error = aa_get_name(&file->f_path, S_ISDIR(mode), &buffer, &name);
++
++ error = aa_file_common_perm(profile, operation, file, request, name,
++ error);
++ kfree(buffer);
++ return error;
++}
+--- /dev/null
++++ b/security/apparmor/include/apparmor.h
+@@ -0,0 +1,65 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor basic global and lib definitions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __APPARMOR_H
++#define __APPARMOR_H
++
++#include <linux/fs.h>
++
++/* Control parameters settable thru module/boot flags or
++ * via /sys/kernel/security/apparmor/control */
++extern enum audit_mode g_apparmor_audit;
++extern int g_apparmor_audit_header;
++extern int g_apparmor_debug;
++extern int g_apparmor_lock_policy;
++extern int g_apparmor_logsyscall;
++extern unsigned int g_apparmor_path_max;
++
++
++/*
++ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
++ * which is not related to profile accesses.
++ */
++
++#define AA_DEBUG(fmt, args...) \
++ do { \
++ if (g_apparmor_debug && printk_ratelimit()) \
++ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
++ } while (0)
++
++#define AA_ERROR(fmt, args...) \
++ do { \
++ if (printk_ratelimit()) \
++ printk(KERN_ERR "AppArmor: " fmt, ##args); \
++ } while (0)
++
++/* Flag indicating whether initialization completed */
++extern int apparmor_initialized;
++void apparmor_disable(void);
++
++/* fn's in lib */
++void info_message(const char *str);
++char *aa_split_name_from_ns(char *args, char **ns_name);
++char *new_compound_name(const char *n1, const char *n2);
++int aa_strneq(const char *str, const char *sub, int len);
++char *strchrnul(const char *s, int c);
++const char *fqname_subname(const char *name);
++
++static inline int mediated_filesystem(struct inode *inode)
++{
++ return !(inode->i_sb->s_flags & MS_NOUSER);
++}
++
++#endif /* __APPARMOR_H */
++
+--- /dev/null
++++ b/security/apparmor/include/apparmorfs.h
+@@ -0,0 +1,24 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor filesystem definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_APPARMORFS_H
++#define __AA_APPARMORFS_H
++
++extern struct dentry *apparmorfs_null;
++extern struct vfsmount *apparmorfs_mnt;
++
++extern int create_apparmorfs(void);
++extern void destroy_apparmorfs(void);
++
++#endif /* __AA_APPARMORFS_H */
+--- /dev/null
++++ b/security/apparmor/include/audit.h
+@@ -0,0 +1,59 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor auditing function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_AUDIT_H
++#define __AA_AUDIT_H
++
++#include <linux/audit.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++struct aa_profile;
++
++
++extern const char *audit_mode_names[];
++#define AUDIT_MAX_INDEX 5
++
++#define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */
++
++enum audit_mode {
++ AUDIT_NORMAL, /* follow normal auditing of accesses */
++ AUDIT_QUIET_DENIED, /* quiet all denied access messages */
++ AUDIT_QUIET, /* quiet all messages */
++ AUDIT_NOQUIET, /* do not quiet audit messages */
++ AUDIT_ALL /* audit all accesses */
++};
++
++/*
++ * aa_audit - AppArmor auditing structure
++ * Structure is populated by access control code and passed to aa_audit which
++ * provides for a single point of logging.
++ */
++struct aa_audit {
++ struct task_struct *task;
++ gfp_t gfp_mask;
++ int error;
++ const char *operation;
++ const char *info;
++};
++
++int aa_audit(int type, struct aa_profile *profile, struct aa_audit *sa,
++ void(*cb)(struct audit_buffer *, void *));
++
++int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, const char *,
++ void(*cb)(struct audit_buffer *, void *));
++
++
++#endif /* __AA_AUDIT_H */
+--- /dev/null
++++ b/security/apparmor/include/capability.h
+@@ -0,0 +1,45 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor capability mediation definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_CAPABILITY_H
++#define __AA_CAPABILITY_H
++
++#include <linux/sched.h>
++
++struct aa_profile;
++
++/* aa_caps - confinement data for capabilities
++ * @set_caps: capabilities that are being set
++ * @capabilities: capabilities mask
++ * @audit_caps: caps that are to be audited
++ * @quiet_caps: caps that should not be audited
++ */
++struct aa_caps {
++ kernel_cap_t set;
++ kernel_cap_t allowed;
++ kernel_cap_t audit;
++ kernel_cap_t quiet;
++ kernel_cap_t kill;
++};
++
++int aa_profile_capable(struct aa_profile *profile, int cap);
++int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
++ int audit);
++
++static inline void aa_free_cap_rules(struct aa_caps *caps)
++{
++ /* NOP */
++}
++
++#endif /* __AA_CAPBILITY_H */
+--- /dev/null
++++ b/security/apparmor/include/context.h
+@@ -0,0 +1,153 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor contexts used to associate "labels" to objects.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_CONTEXT_H
++#define __AA_CONTEXT_H
++
++#include <linux/cred.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++#include "policy.h"
++
++
++/* struct aa_file_cxt - the AppArmor context the file was opened in
++ * @profile: the profile the file was opened under
++ * @perms: the permission the file was opened with
++ */
++struct aa_file_cxt {
++ struct aa_profile *profile;
++ u16 allowed;
++};
++
++static inline struct aa_file_cxt *aa_alloc_file_context(gfp_t gfp)
++{
++ return kzalloc(sizeof(struct aa_file_cxt), gfp);
++}
++
++static inline void aa_free_file_context(struct aa_file_cxt *cxt)
++{
++ aa_put_profile(cxt->profile);
++ memset(cxt, 0, sizeof(struct aa_file_cxt));
++ kfree(cxt);
++}
++
++
++
++
++
++/* struct aa_task_cxt_group - a grouping label data for confined tasks
++ * @profile: the current profile
++ * @exec: profile to transition to on next exec
++ * @previous: profile the task may return to
++ * @token: magic value the task must know for returning to @previous_profile
++ *
++ * Contains the task's current profile (which could change due to
++ * change_hat). Plus the hat_magic needed during change_hat.
++ */
++struct aa_task_cxt_group {
++ struct aa_profile *profile;
++ struct aa_profile *onexec;
++ struct aa_profile *previous;
++ u64 token;
++};
++
++/**
++ * struct aa_task_context - primary label for confined tasks
++ * @sys: the system labeling for the task
++ *
++ * A task is confined by the intersection of its system and user profiles
++ */
++struct aa_task_context {
++ struct aa_task_cxt_group sys;
++};
++
++struct aa_task_context *aa_alloc_task_context(gfp_t flags);
++void aa_free_task_context(struct aa_task_context *cxt);
++struct aa_task_context *aa_dup_task_context(struct aa_task_context *old_cxt,
++ gfp_t gfp);
++void aa_cred_policy(const struct cred *cred, struct aa_profile **sys);
++struct cred *aa_get_task_policy(const struct task_struct *task,
++ struct aa_profile **sys);
++int aa_replace_current_profiles(struct aa_profile *sys);
++void aa_put_task_policy(struct cred *cred);
++int aa_set_current_onexec(struct aa_profile *sys);
++int aa_set_current_hat(struct aa_profile *profile, u64 token);
++int aa_restore_previous_profile(u64 cookie);
++
++
++static inline struct aa_task_context *__aa_task_cxt(struct task_struct *task)
++{
++ return __task_cred(task)->security;
++}
++
++/**
++ * __aa_task_is_confined - determine if @task has any confinement
++ * @task: task to check confinement of
++ *
++ * If @task != current needs to be in RCU safe critical section
++ */
++static inline int __aa_task_is_confined(struct task_struct *task)
++{
++ struct aa_task_context *cxt;
++ int rc = 1;
++
++ cxt = __aa_task_cxt(task);
++ if (!cxt || (cxt->sys.profile->flags & PFLAG_UNCONFINED))
++ rc = 0;
++
++ return rc;
++}
++
++static inline const struct cred *aa_current_policy(struct aa_profile **sys)
++{
++ const struct cred *cred = current_cred();
++ struct aa_task_context *cxt = cred->security;
++ BUG_ON(!cxt);
++ *sys = aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
++
++ return cred;
++}
++
++static inline const struct cred *aa_current_policy_wupd(struct aa_profile **sys)
++{
++ const struct cred *cred = current_cred();
++ struct aa_task_context *cxt = cred->security;
++ BUG_ON(!cxt);
++
++ *sys = aa_profile_newest(cxt->sys.profile);
++ if (unlikely((cxt->sys.profile != *sys)))
++ aa_replace_current_profiles(*sys);
++ *sys = aa_filtered_profile(*sys);
++
++ return cred;
++}
++
++static inline struct aa_profile *aa_current_profile(void)
++{
++ const struct cred *cred = current_cred();
++ struct aa_task_context *cxt = cred->security;
++ BUG_ON(!cxt);
++ return aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
++}
++
++static inline struct aa_profile *aa_current_profile_wupd(void)
++{
++ struct aa_profile *p;
++ aa_current_policy_wupd(&p);
++ return p;
++}
++
++
++#endif /* __AA_CONTEXT_H */
+--- /dev/null
++++ b/security/apparmor/include/domain.h
+@@ -0,0 +1,37 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor security domain transition function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/binfmts.h>
++#include <linux/types.h>
++
++#ifndef __AA_DOMAIN_H
++#define __AA_DOMAIN_H
++
++struct aa_domain {
++ int size;
++ char **table;
++};
++
++int apparmor_bprm_set_creds(struct linux_binprm *bprm);
++int apparmor_bprm_secureexec(struct linux_binprm *bprm);
++int apparmor_bprm_committing_creds(struct linux_binprm *bprm);
++void apparmor_bprm_committed_creds(struct linux_binprm *bprm);
++
++void aa_free_domain_entries(struct aa_domain *domain);
++int aa_change_hat(const char *hat_name, u64 token, int permtest);
++int aa_change_profile(const char *ns_name, const char *name, int onexec,
++ int permtest);
++
++
++#endif /* __AA_DOMAIN_H */
+--- /dev/null
++++ b/security/apparmor/include/file.h
+@@ -0,0 +1,227 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor file mediation function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_FILE_H
++#define __AA_FILE_H
++
++#include <linux/path.h>
++
++#include "audit.h"
++#include "domain.h"
++#include "match.h"
++
++struct aa_profile;
++
++/*
++ * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
++ * for profile permissions
++ */
++#define AA_MAY_LINK 0x0010
++#define AA_MAY_LOCK 0x0020
++#define AA_EXEC_MMAP 0x0040
++
++#define AA_MAY_CREATE 0x0080
++#define AA_LINK_SUBSET 0x0100
++#define AA_MAY_DELEGATE 0x0200
++#define AA_EXEC_DELEGATE 0x0400 /*exec allows delegate*/
++
++#define AA_MAY_CHANGEHAT 0x2000 /* ctrl auditing only */
++#define AA_MAY_ONEXEC 0x4000 /* exec allows onexec */
++#define AA_MAY_CHANGE_PROFILE 0x8000
++
++
++#define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
++ AA_MAY_LINK | AA_MAY_LOCK | AA_EXEC_MMAP | \
++ AA_MAY_CREATE)
++
++/*
++ * The xindex is broken into 3 parts
++ * - index - an index into either the exec name table or the variable table
++ * - exec type - which determines how the executable name and index are used
++ * - flags - which modify how the destination name is applied
++ */
++#define AA_X_INDEX_MASK 0x03ff
++
++#define AA_X_TYPE_MASK 0x0c00
++#define AA_X_TYPE_SHIFT 10
++#define AA_X_NONE 0x0000
++#define AA_X_NAME 0x0400 /* use executable name px */
++#define AA_X_TABLE 0x0800 /* use a specified name ->n# */
++
++#define AA_X_UNSAFE 0x1000
++#define AA_X_CHILD 0x2000 /* make >AA_X_NONE apply to children */
++#define AA_X_INHERIT 0x4000
++#define AA_X_UNCONFINED 0x8000
++
++
++/* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */
++#define AA_SECURE_X_NEEDED 0x8000
++
++/* need to conditionalize which ones are being set */
++struct path_cond {
++ uid_t uid;
++ umode_t mode;
++};
++
++/* struct file_perms - file permission fo
++ * @allowed: mask of permissions that are allowed
++ * @audit: mask of permissions to force an audit message for
++ * @quiet: mask of permissions to quiet audit messages for
++ * @kill: mask of permissions that when matched will kill the task
++ * @xindex: exec transition index if @allowed contains MAY_EXEC
++ * @dindex: delegate table index if @allowed contain AA_MAY_DELEGATE
++ *
++ * The @audit and @queit mask should be mutually exclusive.
++ */
++struct file_perms {
++ u16 allowed;
++ u16 audit;
++ u16 quiet;
++ u16 kill;
++ u16 xindex;
++ u16 dindex;
++};
++
++extern struct file_perms nullperms;
++
++#define COMBINED_PERM_MASK(X) ((X).allowed | (X).audit | (X).quiet | (X).kill)
++
++/* FIXME: split perms from dfa and match this to description
++ * also add delegation info.
++ */
++static inline u16 dfa_map_xindex(u16 mask)
++{
++ u16 old_index = (mask >> 10) & 0xf;
++ u16 index = 0;
++
++//printk("mask x%x\n", mask);
++ if (mask & 0x100)
++ index |= AA_X_UNSAFE;
++ if (mask & 0x200)
++ index |= AA_X_INHERIT;
++
++ if (old_index == 1) {
++ index |= AA_X_UNCONFINED;
++ } else if (old_index == 2) {
++ index |= AA_X_NAME;
++ } else if (old_index == 3) {
++ index |= AA_X_NAME | AA_X_CHILD;
++ } else {
++ index |= AA_X_TABLE;
++ index |= old_index - 4;
++ }
++
++ return index;
++}
++
++/*
++ * map old dfa inline permissions to new format
++ */
++#define dfa_user_allow(dfa, state) ((ACCEPT_TABLE(dfa)[state]) & 0x7f)
++#define dfa_user_audit(dfa, state) ((ACCEPT_TABLE2(dfa)[state]) & 0x7f)
++#define dfa_user_quiet(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 7) & 0x7f)
++#define dfa_user_xindex(dfa, state) \
++ (dfa_map_xindex(ACCEPT_TABLE(dfa)[state] & 0x3fff))
++
++#define dfa_other_allow(dfa, state) (((ACCEPT_TABLE(dfa)[state]) >> 14) & 0x7f)
++#define dfa_other_audit(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 14) & 0x7f)
++#define dfa_other_quiet(dfa, state) ((((ACCEPT_TABLE2(dfa)[state]) >> 7) >> 14) & 0x7f)
++#define dfa_other_xindex(dfa, state) \
++ dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
++
++
++struct aa_audit_file {
++ struct aa_audit base;
++
++ const char *name;
++ const char *name2;
++ const char *name3;
++ struct file_perms perms;
++ u16 request;
++ struct path_cond *cond;
++};
++
++int aa_audit_file(struct aa_profile *profile, struct aa_audit_file *sa);
++void file_audit_cb(struct audit_buffer *ab, void *va);
++
++/**
++ * struct aa_file_rules - components used for file rule permissions
++ * @dfa: dfa to match path names and conditionals against
++ * @perms: permission table indexed by the matched state accept entry of @dfa
++ * @trans: transition table for indexed by named x transitions
++ *
++ * File permission are determined by matching a path against @dfa and then
++ * then using the value of the accept entry for the matching state as
++ * an index into @perms. If a named exec transition is required it is
++ * looked up in the transition table.
++ */
++struct aa_file_rules {
++ struct aa_dfa *dfa;
++ /* struct perms perms; */
++ struct aa_domain trans;
++ /* TODO: add delegate table */
++};
++
++struct file_perms aa_str_perms(struct aa_dfa *dfa, unsigned int start,
++ const char *name, struct path_cond *cond,
++ unsigned int *rstate);
++
++int aa_pathstr_perm(struct aa_profile *profile, const char *op,
++ const char *name, u16 request, struct path_cond *cond);
++
++int aa_path_perm(struct aa_profile *profile, const char *operation,
++ struct path *path, u16 request, struct path_cond *cond);
++
++int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
++ struct path *new_dir, struct dentry *new_dentry);
++
++int aa_file_common_perm(struct aa_profile *profile, const char *operation,
++ struct file *file, u16 request, const char *name,
++ int error);
++
++int aa_file_perm(struct aa_profile *profile, const char *operation,
++ struct file *file, u16 request);
++
++
++static inline void aa_free_file_rules(struct aa_file_rules *rules)
++{
++ aa_match_free(rules->dfa);
++ aa_free_domain_entries(&rules->trans);
++}
++
++#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) >> 5) & 0x1))
++
++/* from namei.c */
++#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
++#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
++/*
++ * map file flags to AppArmor permissions
++ */
++static inline u16 aa_map_file_to_perms(struct file *file)
++{
++ int flags = MAP_OPEN_FLAGS(file->f_flags);
++ u16 perms = ACC_FMODE(file->f_mode);
++
++ if ((flags & O_APPEND) && (perms & MAY_WRITE))
++ perms = (perms & ~MAY_WRITE) | MAY_APPEND;
++ /* trunc implies write permission */
++ if (flags & O_TRUNC)
++ perms |= MAY_WRITE;
++ if (flags & O_CREAT)
++ perms |= AA_MAY_CREATE;
++
++ return perms;
++}
++
++#endif /* __AA_FILE_H */
+--- /dev/null
++++ b/security/apparmor/include/ipc.h
+@@ -0,0 +1,28 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor ipc mediation function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_IPC_H
++#define __AA_IPC_H
++
++#include <linux/sched.h>
++
++struct aa_profile;
++
++int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
++ struct aa_profile *tracee, unsigned int mode);
++
++int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
++ unsigned int mode);
++
++#endif /* __AA_IPC_H */
+--- /dev/null
++++ b/security/apparmor/include/match.h
+@@ -0,0 +1,105 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor policy dfa matching engine definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_MATCH_H
++#define __AA_MATCH_H
++
++#define DFA_NOMATCH 0
++#define DFA_START 1
++
++#define DFA_VALID_PERM_MASK 0xffffffff
++#define DFA_VALID_PERM2_MASK 0xffffffff
++
++
++/**
++ * The format used for transition tables is based on the GNU flex table
++ * file format (--tables-file option; see Table File Format in the flex
++ * info pages and the flex sources for documentation). The magic number
++ * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because
++ * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used
++ * slightly differently (see the apparmor-parser package).
++ */
++
++#define YYTH_MAGIC 0x1B5E783D
++
++struct table_set_header {
++ u32 th_magic; /* YYTH_MAGIC */
++ u32 th_hsize;
++ u32 th_ssize;
++ u16 th_flags;
++ char th_version[];
++};
++
++#define YYTD_ID_ACCEPT 1
++#define YYTD_ID_BASE 2
++#define YYTD_ID_CHK 3
++#define YYTD_ID_DEF 4
++#define YYTD_ID_EC 5
++#define YYTD_ID_META 6
++#define YYTD_ID_ACCEPT2 7
++#define YYTD_ID_NXT 8
++
++
++#define YYTD_DATA8 1
++#define YYTD_DATA16 2
++#define YYTD_DATA32 4
++
++struct table_header {
++ u16 td_id;
++ u16 td_flags;
++ u32 td_hilen;
++ u32 td_lolen;
++ char td_data[];
++};
++
++#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data))
++#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data))
++#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data))
++#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data))
++#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data))
++#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data))
++#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 - 1]->td_data))
++
++struct aa_dfa {
++ struct table_header *tables[YYTD_ID_NXT];
++};
++
++#define byte_to_byte(X) (X)
++
++#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
++ do { \
++ typeof(LEN) __i; \
++ TYPE *__t = (TYPE *) TABLE; \
++ TYPE *__b = (TYPE *) BLOB; \
++ for (__i = 0; __i < LEN; __i++) { \
++ __t[__i] = NTOHX(__b[__i]); \
++ } \
++ } while (0)
++
++static inline size_t table_size(size_t len, size_t el_size)
++{
++ return ALIGN(sizeof(struct table_header) + len * el_size, 8);
++}
++
++struct aa_dfa *aa_match_alloc(void);
++void aa_match_free(struct aa_dfa *dfa);
++int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size);
++int verify_dfa(struct aa_dfa *dfa);
++unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
++ const char *str, int len);
++unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
++ const char *str);
++unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start);
++
++#endif /* __AA_MATCH_H */
+--- /dev/null
++++ b/security/apparmor/include/net.h
+@@ -0,0 +1,40 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor network mediation definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_NET_H
++#define __AA_NET_H
++
++#include <net/sock.h>
++
++/* struct aa_net - network confinement data
++ * @allowed: basic network families permissions
++ * @audit_network: which network permissions to force audit
++ * @quiet_network: which network permissions to quiet rejects
++ */
++struct aa_net {
++ u16 allowed[AF_MAX];
++ u16 audit[AF_MAX];
++ u16 quiet[AF_MAX];
++};
++
++extern int aa_net_perm(struct aa_profile *profile, char *operation,
++ int family, int type, int protocol);
++extern int aa_revalidate_sk(struct sock *sk, char *operation);
++
++static inline void aa_free_net_rules(struct aa_net *new)
++{
++ /* NOP */
++}
++
++#endif /* __AA_NET_H */
+--- /dev/null
++++ b/security/apparmor/include/path.h
+@@ -0,0 +1,24 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor basic path manipulation function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_PATH_H
++#define __AA_PATH_H
++
++int aa_get_name_to_buffer(struct path *path, int is_dir, char *buffer, int size,
++ char **name);
++int aa_get_name(struct path *path, int is_dir, char **buffer, char **name);
++int d_namespace_path(struct path *path, char *buf, int buflen, char **name);
++char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen);
++
++#endif /* __AA_PATH_H */
+--- /dev/null
++++ b/security/apparmor/include/policy.h
+@@ -0,0 +1,301 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor policy definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_POLICY_H
++#define __AA_POLICY_H
++
++#include <linux/capability.h>
++#include <linux/cred.h>
++#include <linux/kref.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/socket.h>
++
++#include "apparmor.h"
++#include "audit.h"
++#include "capability.h"
++#include "domain.h"
++#include "file.h"
++#include "net.h"
++#include "resource.h"
++
++extern const char *profile_mode_names[];
++#define APPARMOR_NAMES_MAX_INDEX 3
++
++#define PROFILE_COMPLAIN(_profile) \
++ ((g_profile_mode == APPARMOR_COMPLAIN) || ((_profile) && \
++ (_profile)->mode == APPARMOR_COMPLAIN))
++
++#define PROFILE_KILL(_profile) \
++ ((g_profile_mode == APPARMOR_KILL) || ((_profile) && \
++ (_profile)->mode == APPARMOR_KILL))
++
++#define PROFILE_IS_HAT(_profile) \
++ ((_profile) && (_profile)->flags & PFLAG_HAT)
++
++
++/*
++ * FIXME: currently need a clean way to replace and remove profiles as a
++ * set. It should be done at the namespace level.
++ * Either, with a set of profiles loaded at the namespace level or via
++ * a mark and remove marked interface.
++ */
++enum profile_mode {
++ APPARMOR_ENFORCE, /* enforce access rules */
++ APPARMOR_COMPLAIN, /* allow and log access violations */
++ APPARMOR_KILL, /* kill task on access violation */
++};
++
++enum profile_flags {
++ PFLAG_HAT = 1, /* profile is a hat */
++ PFLAG_UNCONFINED = 2, /* profile is the unconfined profile */
++ PFLAG_NULL = 4, /* profile is null learning profile */
++ PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
++ PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */
++ PFLAG_USER_DEFINED = 0x20, /* user based profile */
++ PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
++};
++
++#define AA_NEW_SID 0
++
++struct aa_profile;
++
++/* struct aa_policy_common - common part of both namespaces and profiles
++ * @name: name of the object
++ * @count: reference count of the obj
++ * lock: lock for modifying the object
++ * @list: list object is on
++ * @profiles: head of the profiles list contained in the object
++ */
++struct aa_policy_common {
++ char *name;
++ struct kref count;
++ rwlock_t lock;
++ struct list_head list;
++ struct list_head profiles;
++};
++
++/* struct aa_ns_acct - accounting of profiles in namespace
++ * @max_size: maximum space allowed for all profiles in namespace
++ * @max_count: maximum number of profiles that can be in this namespace
++ * @size: current size of profiles
++ * @count: current count of profiles (includes null profiles)
++ */
++struct aa_ns_acct {
++ int max_size;
++ int max_count;
++ int size;
++ int count;
++};
++
++/* struct aa_namespace - namespace for a set of profiles
++ * @name: the name of the namespace
++ * @list: list the namespace is on
++ * @profiles: list of profile in the namespace
++ * @acct: accounting for the namespace
++ * @profile_count: count of profiles on @profiles list
++ * @size: accounting of how much memory is consumed by the contained profiles
++ * @unconfined: special unconfined profile for the namespace
++ * @count: reference count on the namespace
++ * @lock: lock for adding/removing profile to the namespace
++ *
++ * An aa_namespace defines the set profiles that are searched to determine
++ * which profile to attach to a task. Profiles can not be shared between
++ * aa_namespaces and profile names within a namespace are guarenteed to be
++ * unique. When profiles in seperate namespaces have the same name they
++ * are NOT considered to be equivalent.
++ *
++ * Namespace names must be unique and can not contain the characters :/\0
++ *
++ * FIXME TODO: add vserver support so a vserer gets a default namespace
++ */
++struct aa_namespace {
++ struct aa_policy_common base;
++ struct aa_ns_acct acct;
++ int is_stale;
++ struct aa_profile *unconfined;
++};
++
++
++/* struct aa_profile - basic confinement data
++ * @base - base componets of the profile (name, refcount, lists, lock ...)
++ * @fqname - The fully qualified profile name, less the namespace name
++ * @ns: namespace the profile is in
++ * @parent: parent profile of this profile, if one exists
++ * @replacedby: is set profile that replaced this profile
++ * @xmatch: optional extended matching for unconfined executables names
++ * @xmatch_plen: xmatch prefix len, used to determine xmatch priority
++ * @sid: the unique security id number of this profile
++ * @audit: the auditing mode of the profile
++ * @mode: the enforcement mode of the profile
++ * @flags: flags controlling profile behavior
++ * @size: the memory consumed by this profiles rules
++ * @file: The set of rules governing basic file access and domain transitions
++ * @caps: capabilities for the profile
++ * @net: network controls for the profile
++ * @rlimits: rlimits for the profile
++ *
++ * The AppArmor profile contains the basic confinement data. Each profile
++ * has a name, and exist in a namespace. The @name and @exec_match are
++ * used to determine profile attachment against unconfined tasks. All other
++ * attachments are determined by in profile X transition rules.
++ *
++ * The @replacedby field is write protected by the profile lock. Reads
++ * are assumed to be atomic, and are done without locking.
++ *
++ * Profiles have a hierachy where hats and children profiles keep
++ * a reference to their parent.
++ *
++ * Profile names can not begin with a : and can not contain the \0
++ * character. If a profile name begins with / it will be considered when
++ * determining profile attachment on "unconfined" tasks.
++ */
++struct aa_profile {
++ struct aa_policy_common base;
++ char *fqname;
++
++ struct aa_namespace *ns;
++ struct aa_profile *parent;
++ struct aa_profile *replacedby;
++
++ struct aa_dfa *xmatch;
++ int xmatch_len;
++ u32 sid;
++ enum audit_mode audit;
++ enum profile_mode mode;
++ u32 flags;
++ int size;
++
++ struct aa_file_rules file;
++ struct aa_caps caps;
++ struct aa_net net;
++ struct aa_rlimit rlimits;
++};
++
++
++extern struct list_head ns_list;
++extern rwlock_t ns_list_lock;
++
++extern struct aa_namespace *default_namespace;
++extern enum profile_mode g_profile_mode;
++
++
++void aa_add_profile(struct aa_policy_common *common,
++ struct aa_profile *profile);
++
++int alloc_default_namespace(void);
++void free_default_namespace(void);
++struct aa_namespace *alloc_aa_namespace(const char *name);
++void free_aa_namespace_kref(struct kref *kref);
++void free_aa_namespace(struct aa_namespace *ns);
++struct aa_namespace *__aa_find_namespace(struct list_head *head,
++ const char *name);
++
++struct aa_namespace *aa_find_namespace(const char *name);
++struct aa_namespace *aa_prepare_namespace(const char *name);
++void aa_remove_namespace(struct aa_namespace *ns);
++struct aa_namespace *aa_prepare_namespace(const char *name);
++void aa_profile_list_release(struct list_head *head);
++void aa_profile_ns_list_release(void);
++void __aa_remove_namespace(struct aa_namespace *ns);
++
++
++static inline struct aa_policy_common *aa_get_common(struct aa_policy_common *c)
++{
++ if (c)
++ kref_get(&c->count);
++
++ return c;
++}
++
++static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
++{
++ if (ns)
++ kref_get(&(ns->base.count));
++
++ return ns;
++}
++
++static inline void aa_put_namespace(struct aa_namespace *ns)
++{
++ if (ns)
++ kref_put(&ns->base.count, free_aa_namespace_kref);
++}
++
++
++
++struct aa_profile *alloc_aa_profile(const char *name);
++struct aa_profile *aa_alloc_null_profile(struct aa_profile *parent, int hat);
++void free_aa_profile_kref(struct kref *kref);
++void free_aa_profile(struct aa_profile *profile);
++struct aa_profile *__aa_find_profile(struct list_head *head, const char *name);
++struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
++struct aa_policy_common *__aa_find_parent_by_fqname(struct aa_namespace *ns,
++ const char *fqname);
++struct aa_profile *__aa_find_profile_by_fqname(struct aa_namespace *ns,
++ const char *fqname);
++struct aa_profile *aa_find_profile_by_fqname(struct aa_namespace *ns,
++ const char *name);
++struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
++struct aa_profile *aa_profile_newest(struct aa_profile *profile);
++struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns,
++ const char *name);
++void __aa_add_profile(struct aa_policy_common *common,
++ struct aa_profile *profile);
++void __aa_remove_profile(struct aa_profile *profile,
++ struct aa_profile *replacement);
++void __aa_replace_profile(struct aa_profile *profile,
++ struct aa_profile *replacement);
++void __aa_profile_list_release(struct list_head *head);
++
++static inline struct aa_profile *aa_filtered_profile(struct aa_profile *profile)
++{
++ if (profile->flags & PFLAG_UNCONFINED)
++ return NULL;
++ return profile;
++}
++
++/**
++ * aa_get_profile - increment refcount on profile @p
++ * @p: profile
++ */
++static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
++{
++ if (p)
++ kref_get(&(p->base.count));
++
++ return p;
++}
++
++/**
++ * aa_put_profile - decrement refcount on profile @p
++ * @p: profile
++ */
++static inline void aa_put_profile(struct aa_profile *p)
++{
++ if (p)
++ kref_put(&p->base.count, free_aa_profile_kref);
++}
++
++static inline int PROFILE_AUDIT_MODE(struct aa_profile *profile)
++{
++ if (g_apparmor_audit != AUDIT_NORMAL)
++ return g_apparmor_audit;
++ if (profile)
++ return profile->audit;
++ return AUDIT_NORMAL;
++}
++
++#endif /* __AA_POLICY_H */
++
+--- /dev/null
++++ b/security/apparmor/include/policy_interface.h
+@@ -0,0 +1,22 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor policy loading interface function definitions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __POLICY_INTERFACE_H
++#define __POLICY_INTERFACE_H
++
++ssize_t aa_interface_add_profiles(void *data, size_t size);
++ssize_t aa_interface_replace_profiles(void *udata, size_t size);
++ssize_t aa_interface_remove_profiles(char *name, size_t size);
++
++#endif /* __POLICY_INTERFACE_H */
+--- /dev/null
++++ b/security/apparmor/include/procattr.h
+@@ -0,0 +1,26 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor /proc/<pid>/attr/ interface function defintions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_PROCATTR_H
++#define __AA_PROCATTR_H
++
++#define AA_DO_TEST 1
++
++int aa_getprocattr(struct aa_namespace *ns, struct aa_profile *profile,
++ char **string);
++int aa_setprocattr_changehat(char *args, int test);
++int aa_setprocattr_changeprofile(char *args, int onexec, int test);
++int aa_setprocattr_permipc(char *args);
++
++#endif /* __AA_PROCATTR_H */
+--- /dev/null
++++ b/security/apparmor/include/resource.h
+@@ -0,0 +1,46 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor resource limits function defintions.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_RESOURCE_H
++#define __AA_RESOURCE_H
++
++#include <linux/resource.h>
++#include <linux/sched.h>
++
++struct aa_profile;
++
++/* struct aa_rlimit - rlimits settings for the profile
++ * @mask: which hard limits to set
++ * @limits: rlimit values that override task limits
++ *
++ * AppArmor rlimits are used to set confined task rlimits. Only the
++ * limits specified in @mask will be controlled by apparmor.
++ */
++struct aa_rlimit {
++ unsigned int mask;
++ struct rlimit limits[RLIM_NLIMITS];
++};
++
++
++int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
++ struct rlimit *new_rlim);
++
++void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new);
++
++static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
++{
++ /* NOP */
++}
++
++#endif /* __AA_RESOURCE_H */
+--- /dev/null
++++ b/security/apparmor/include/sid.h
+@@ -0,0 +1,46 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor security identifier (sid) definitions
++ *
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#ifndef __AA_SID_H
++#define __AA_SID_H
++
++#include <linux/types.h>
++
++struct aa_profile;
++
++#define AA_ALLOC_USR_SID 1
++#define AA_ALLOC_SYS_SID 0
++
++u32 aa_alloc_sid(int is_usr);
++void aa_free_sid(u32 sid);
++int aa_add_sid_profile(u32 sid, struct aa_profile *profile);
++int aa_replace_sid_profile(u32 sid, struct aa_profile *profile);
++struct aa_profile *aa_get_sid_profile(u32 sid);
++
++
++static inline u32 aa_compound_sid(u32 sys, u32 usr)
++{
++ return sys | usr;
++}
++
++static inline u32 aa_usr_sid(u32 sid)
++{
++ return sid & 0xffff0000;
++}
++
++static inline u32 aa_sys_sid(u32 sid)
++{
++ return sid & 0xffff;
++}
++
++#endif /* __AA_SID_H */
+--- /dev/null
++++ b/security/apparmor/ipc.c
+@@ -0,0 +1,106 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor ipc mediation
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/gfp.h>
++#include <linux/ptrace.h>
++
++#include "include/audit.h"
++#include "include/capability.h"
++#include "include/context.h"
++#include "include/policy.h"
++
++
++struct aa_audit_ptrace {
++ struct aa_audit base;
++
++ pid_t tracer, tracee;
++};
++
++/* call back to audit ptrace fields */
++static void audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_ptrace *sa = va;
++ audit_log_format(ab, " tracer=%d tracee=%d", sa->tracer, sa->tracee);
++}
++
++static int aa_audit_ptrace(struct aa_profile *profile,
++ struct aa_audit_ptrace *sa)
++{
++ return aa_audit(AUDIT_APPARMOR_AUTO, profile, (struct aa_audit *)sa,
++ audit_cb);
++}
++
++int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
++ struct aa_profile *tracee, unsigned int mode)
++{
++ /* TODO: currently only based on capability, not extended ptrace
++ * rules,
++ * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
++ */
++
++ if (!tracer || tracer == tracee)
++ return 0;
++ /* log this capability request */
++ return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1);
++}
++
++int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
++ unsigned int mode)
++{
++ /*
++ * tracer can ptrace tracee when
++ * - tracer is unconfined ||
++ * - tracer & tracee are in the same namespace &&
++ * - tracer is in complain mode
++ * - tracer has rules allowing it to trace tracee currently this is:
++ * - confined by the same profile ||
++ * - tracer profile has CAP_SYS_PTRACE
++ */
++
++ struct aa_profile *tracer_p;
++ const struct cred *cred = aa_get_task_policy(tracer, &tracer_p);
++ int error = 0;
++
++ if (tracer_p) {
++ struct aa_audit_ptrace sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = "ptrace";
++ sa.base.gfp_mask = GFP_ATOMIC;
++ sa.tracer = tracer->pid;
++ sa.tracee = tracee->pid;
++ /* FIXME: different namespace restriction can be lifted
++ * if, namespace are matched to AppArmor namespaces
++ */
++ if (tracer->nsproxy != tracee->nsproxy) {
++ sa.base.info = "different namespaces";
++ sa.base.error = -EPERM;
++ aa_audit(AUDIT_APPARMOR_DENIED, tracer_p, &sa.base,
++ audit_cb);
++ } else {
++ struct aa_profile *tracee_p;
++ struct cred *lcred = aa_get_task_policy(tracee,
++ &tracee_p);
++
++ sa.base.error = aa_may_ptrace(tracer, tracer_p,
++ tracee_p, mode);
++ //sa.base.error = aa_audit_ptrace(tracer_p, &sa);
++
++ put_cred(lcred);
++ }
++ error = sa.base.error;
++ }
++ put_cred(cred);
++
++ return error;
++}
+--- /dev/null
++++ b/security/apparmor/lib.c
+@@ -0,0 +1,100 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains basic common functions used in AppArmor
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/slab.h>
++#include <linux/string.h>
++
++#include "include/audit.h"
++
++void info_message(const char *str)
++{
++ struct aa_audit sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.gfp_mask = GFP_KERNEL;
++ sa.info = str;
++ printk(KERN_INFO "AppArmor: %s\n", str);
++ if (audit_enabled)
++ aa_audit(AUDIT_APPARMOR_STATUS, NULL, &sa, NULL);
++}
++
++char *strchrnul(const char *s, int c)
++{
++ for (; *s != (char)c && *s != '\0'; ++s)
++ ;
++ return (char *)s;
++}
++
++char *aa_split_name_from_ns(char *args, char **ns_name)
++{
++ char *name = strstrip(args);
++
++ *ns_name = NULL;
++ if (args[0] == ':') {
++ char *split = strstrip(strchr(&args[1], ':'));
++
++ if (!split)
++ return NULL;
++
++ *split = 0;
++ *ns_name = &args[1];
++ name = strstrip(split + 1);
++ }
++ if (*name == 0)
++ name = NULL;
++
++ return name;
++}
++
++char *new_compound_name(const char *n1, const char *n2)
++{
++ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
++ if (name)
++ sprintf(name, "%s//%s", n1, n2);
++ return name;
++}
++
++/**
++ * aa_strneq - compare null terminated @str to a non null terminated substring
++ * @str: a null terminated string
++ * @sub: a substring, not necessarily null terminated
++ * @len: length of @sub to compare
++ *
++ * The @str string must be full consumed for this to be considered a match
++ */
++int aa_strneq(const char *str, const char *sub, int len)
++{
++ int res = strncmp(str, sub, len);
++ if (res)
++ return 0;
++ if (str[len] == 0)
++ return 1;
++ return 0;
++}
++
++const char *fqname_subname(const char *name)
++{
++ char *split;
++ /* check for namespace which begins with a : and ends with : or \0 */
++ name = strstrip((char *) name);
++ if (*name == ':') {
++ split = strchrnul(name + 1, ':');
++ if (*split == '\0')
++ return NULL;
++ name = strstrip(split + 1);
++ }
++ for (split = strstr(name, "//"); split; split = strstr(name, "//")) {
++ name = split + 2;
++ }
++ return name;
++}
+--- /dev/null
++++ b/security/apparmor/lsm.c
+@@ -0,0 +1,1059 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor LSM hooks.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/security.h>
++#include <linux/moduleparam.h>
++#include <linux/mm.h>
++#include <linux/mman.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/ptrace.h>
++#include <linux/ctype.h>
++#include <linux/sysctl.h>
++#include <linux/audit.h>
++#include <net/sock.h>
++
++#include "include/apparmor.h"
++#include "include/apparmorfs.h"
++#include "include/audit.h"
++#include "include/capability.h"
++#include "include/context.h"
++#include "include/file.h"
++#include "include/ipc.h"
++#include "include/net.h"
++#include "include/path.h"
++#include "include/policy.h"
++#include "include/procattr.h"
++
++/* Flag indicating whether initialization completed */
++int apparmor_initialized;
++
++
++/*
++ * LSM hook functions
++ */
++
++/*
++ * prepare new aa_task_context for modification by prepare_cred block
++ */
++static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
++ gfp_t gfp)
++{
++ struct aa_task_context *cxt = aa_dup_task_context(old->security, gfp);
++ if (!cxt)
++ return -ENOMEM;
++ new->security = cxt;
++ return 0;
++}
++
++/*
++ * free the associated aa_task_context and put its profiles
++ */
++static void apparmor_cred_free(struct cred *cred)
++{
++ struct aa_task_context *cxt = cred->security;
++ cred->security = NULL;
++ aa_free_task_context(cxt);
++}
++
++
++static int apparmor_ptrace_may_access(struct task_struct *child,
++ unsigned int mode)
++{
++ return aa_ptrace(current, child, mode);
++}
++
++
++static int apparmor_ptrace_traceme(struct task_struct *parent)
++{
++ return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
++}
++
++/* Derived from security/commoncap.c:cap_capget */
++static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
++ kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++ struct aa_profile *profile;
++ const struct cred *cred;
++
++ rcu_read_lock();
++ cred = __task_cred(target);
++ aa_cred_policy(cred, &profile);
++
++ *effective = cred->cap_effective;
++ *inheritable = cred->cap_inheritable;
++ *permitted = cred->cap_permitted;
++
++ if (profile) {
++ *effective = cap_combine(*effective, profile->caps.set);
++ *effective = cap_intersect(*effective, profile->caps.allowed);
++ }
++ rcu_read_unlock();
++
++ return 0;
++}
++
++static int apparmor_capable(struct task_struct *task, const struct cred *cred,
++ int cap, int audit)
++{
++ struct aa_profile *profile;
++ /* cap_capable returns 0 on success, else -EPERM */
++ int error = cap_capable(task, cred, cap, audit);
++
++ aa_cred_policy(cred, &profile);
++ if (profile && (!error || cap_raised(profile->caps.set, cap)))
++ error = aa_capable(task, profile, cap, audit);
++
++ return error;
++}
++
++static int apparmor_sysctl(struct ctl_table *table, int op)
++{
++ int error = 0;
++ struct aa_profile *profile = aa_current_profile_wupd();
++
++ if (profile) {
++ char *buffer, *name;
++ int mask;
++
++ mask = 0;
++ if (op & 4)
++ mask |= MAY_READ;
++ if (op & 2)
++ mask |= MAY_WRITE;
++
++ error = -ENOMEM;
++ buffer = (char *)__get_free_page(GFP_KERNEL);
++ if (!buffer)
++ goto out;
++
++ /*
++ * TODO: convert this over to using a global or per
++ * namespace control instead of a hard coded /proc
++ */
++ name = sysctl_pathname(table, buffer, PAGE_SIZE);
++ if (name && name - buffer >= 5) {
++ struct path_cond cond = { 0, S_IFREG };
++ name -= 5;
++ memcpy(name, "/proc", 5);
++ error = aa_pathstr_perm(profile, "sysctl", name, mask,
++ &cond);
++ }
++ free_page((unsigned long)buffer);
++ }
++
++out:
++ return error;
++}
++
++static int common_perm(const char *op, struct path *path, u16 mask,
++ struct path_cond *cond)
++{
++ struct aa_profile *profile;
++ int error = 0;
++
++ profile = aa_current_profile();
++ if (profile)
++ error = aa_path_perm(profile, op, path, mask, cond);
++
++ return error;
++}
++
++static int common_perm_dentry(const char *op, struct path *dir,
++ struct dentry *dentry, u16 mask,
++ struct path_cond *cond)
++{
++ struct path path = { dir->mnt, dentry };
++
++ return common_perm(op, &path, mask, cond);
++}
++
++static int common_perm_rm(const char *op, struct path *dir,
++ struct dentry *dentry, u16 mask)
++{
++ struct inode *inode = dentry->d_inode;
++
++ if (!dir->mnt || !inode || !mediated_filesystem(inode))
++ return 0;
++
++ struct path_cond cond = { inode->i_uid, inode->i_mode };
++
++ return common_perm_dentry(op, dir, dentry, mask, &cond);
++}
++
++static int common_perm_create(const char *op, struct path *dir,
++ struct dentry *dentry, u16 mask, umode_t mode)
++{
++ struct path_cond cond = { current_fsuid(), mode };
++
++ if (!dir->mnt || !mediated_filesystem(dir->dentry->d_inode))
++ return 0;
++
++ return common_perm_dentry(op, dir, dentry, mask, &cond);
++}
++
++static int apparmor_path_unlink(struct path *dir, struct dentry *dentry)
++{
++ return common_perm_rm("unlink", dir, dentry, MAY_WRITE);
++}
++
++static int apparmor_path_mkdir(struct path *dir, struct dentry *dentry,
++ int mode)
++{
++ return common_perm_create("mkdir", dir, dentry, AA_MAY_CREATE, S_IFDIR);
++}
++
++static int apparmor_path_rmdir(struct path *dir, struct dentry *dentry)
++{
++ return common_perm_rm("rmdir", dir, dentry, MAY_WRITE);
++}
++
++static int apparmor_path_mknod(struct path *dir, struct dentry *dentry,
++ int mode, unsigned int dev)
++{
++ return common_perm_create("mknod", dir, dentry, AA_MAY_CREATE, mode);
++}
++
++static int apparmor_path_truncate(struct path *path, loff_t length,
++ unsigned int time_attrs)
++{
++ struct path_cond cond = { path->dentry->d_inode->i_uid,
++ path->dentry->d_inode->i_mode };
++
++ if (!path->mnt || !mediated_filesystem(path->dentry->d_inode))
++ return 0;
++ return common_perm("truncate", path, MAY_WRITE, &cond);
++}
++
++static int apparmor_path_symlink(struct path *dir, struct dentry *dentry,
++ const char *old_name)
++{
++ return common_perm_create("symlink_create", dir, dentry, AA_MAY_CREATE,
++ S_IFLNK);
++}
++
++static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir,
++ struct dentry *new_dentry)
++{
++ struct aa_profile *profile;
++ int error = 0;
++
++ if (!mediated_filesystem(old_dentry->d_inode))
++ return 0;
++
++ profile = aa_current_profile_wupd();
++ if (profile)
++ error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
++ return error;
++}
++
++static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
++ struct path *new_dir, struct dentry *new_dentry)
++{
++ struct aa_profile *profile;
++ int error = 0;
++
++ if (!mediated_filesystem(old_dentry->d_inode))
++ return 0;
++
++ profile = aa_current_profile_wupd();
++ if (profile) {
++ struct path old_path = { old_dir->mnt, old_dentry };
++ struct path new_path = { new_dir->mnt, new_dentry };
++ struct path_cond cond = { old_dentry->d_inode->i_uid,
++ old_dentry->d_inode->i_mode };
++
++ error = aa_path_perm(profile, "rename_src", &old_path,
++ MAY_READ | MAY_WRITE, &cond);
++ if (!error)
++ error = aa_path_perm(profile, "rename_dest", &new_path,
++ AA_MAY_CREATE | MAY_WRITE, &cond);
++
++ }
++ return error;
++}
++
++static int apparmor_dentry_open(struct file *file, const struct cred *cred)
++{
++ struct aa_profile *profile;
++ int error = 0;
++
++ /* If in exec permission is handled by bprm hooks */
++ if (current->in_execve ||
++ !mediated_filesystem(file->f_path.dentry->d_inode))
++ return 0;
++
++ aa_cred_policy(cred, &profile);
++ if (profile) {
++ struct aa_file_cxt *fcxt = file->f_security;
++ struct inode *inode = file->f_path.dentry->d_inode;
++ struct path_cond cond = { inode->i_uid, inode->i_mode };
++
++ error = aa_path_perm(profile, "open", &file->f_path,
++ aa_map_file_to_perms(file), &cond);
++ fcxt->profile = aa_get_profile(profile);
++ /* todo cache actual allowed permissions */
++ fcxt->allowed = 0;
++ }
++
++ return error;
++}
++
++static int apparmor_file_alloc_security(struct file *file)
++{
++ file->f_security = aa_alloc_file_context(GFP_KERNEL);
++ if (!file->f_security)
++ return -ENOMEM;
++ return 0;
++
++}
++
++static void apparmor_file_free_security(struct file *file)
++{
++ struct aa_file_cxt *cxt = file->f_security;
++
++ aa_free_file_context(cxt);
++}
++
++static int apparmor_file_permission(struct file *file, int mask)
++{
++ /*
++ * Most basic (rw) file access is revalidated at exec.
++ * The revalidation done here is for parent/child hat
++ * file accesses.
++ *
++ * Currently profile replacement does not cause revalidation
++ * or file revocation.
++ *
++ * TODO: cache profiles that have revalidated?
++ */
++ struct aa_file_cxt *fcxt = file->f_security;
++ struct aa_profile *profile, *fprofile = fcxt->profile;
++ int error = 0;
++
++ if (!fprofile || !file->f_path.mnt ||
++ !mediated_filesystem(file->f_path.dentry->d_inode))
++ return 0;
++
++ profile = aa_current_profile();
++ /* TODO: Enable at exec time revalidation of files
++ if (profile && (fprofile != profile) &&
++ ((PROFILE_IS_HAT(profile) && (profile->parent == fprofile)) ||
++ (PROFILE_IS_HAT(fprofile) && (fprofile->parent == profile))))
++ error = aa_file_perm(profile, "file_perm", file, mask);
++ */
++ if (profile && ((fprofile != profile) || (mask & ~fcxt->allowed)))
++ error = aa_file_perm(profile, "file_perm", file, mask);
++
++ return error;
++}
++
++static int common_file_perm(const char *op, struct file *file, u16 mask)
++{
++ const struct aa_file_cxt *fcxt = file->f_security;
++ struct aa_profile *profile, *fprofile = fcxt->profile;
++ int error = 0;
++
++ if (!fprofile || !file->f_path.mnt ||
++ !mediated_filesystem(file->f_path.dentry->d_inode))
++ return 0;
++
++ profile = aa_current_profile_wupd();
++ if (profile && ((fprofile != profile) || (mask & ~fcxt->allowed)))
++ error = aa_file_perm(profile, op, file, mask);
++
++ return error;
++}
++
++static int apparmor_file_lock(struct file *file, unsigned int cmd)
++{
++ u16 mask = AA_MAY_LOCK;
++
++ if (cmd == F_WRLCK)
++ mask |= MAY_WRITE;
++
++ return common_file_perm("file_lock", file, mask);
++}
++
++
++/*
++ * AppArmor doesn't current use the fcntl hook.
++ *
++ * FIXME - these are not implemented yet - REMOVE file_fcntl hook
++ * NOTE: some of the file control commands are further mediated
++ * by other hooks
++ * F_SETOWN - security_file_set_fowner
++ * F_SETLK - security_file_lock
++ * F_SETLKW - security_file_lock
++ * O_APPEND - AppArmor mediates append as a subset of full write
++ * so changing from full write to appending write is
++ * dropping priviledge and not restricted.
++
++
++static int apparmor_file_fcntl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ return 0;
++}
++*/
++
++static int common_mmap(struct file *file, const char *operation,
++ unsigned long prot, unsigned long flags)
++{
++ struct dentry *dentry;
++ int mask = 0;
++
++ if (!file || !file->f_security)
++ return 0;
++
++ if (prot & PROT_READ)
++ mask |= MAY_READ;
++ /* Private mappings don't require write perms since they don't
++ * write back to the files */
++ if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
++ mask |= MAY_WRITE;
++ if (prot & PROT_EXEC)
++ mask |= AA_EXEC_MMAP;
++
++ dentry = file->f_path.dentry;
++ return common_file_perm(operation, file, mask);
++}
++
++static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
++ unsigned long prot, unsigned long flags,
++ unsigned long addr, unsigned long addr_only)
++{
++ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) {
++ struct aa_profile *profile = aa_current_profile_wupd();
++ if (profile)
++ /* future control check here */
++ return -EACCES;
++ else
++ return -EACCES;
++ }
++
++ return common_mmap(file, "file_mmap", prot, flags);
++}
++
++static int apparmor_file_mprotect(struct vm_area_struct *vma,
++ unsigned long reqprot, unsigned long prot)
++{
++ return common_mmap(vma->vm_file, "file_mprotect", prot,
++ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
++}
++
++static int apparmor_getprocattr(struct task_struct *task, char *name,
++ char **value)
++{
++ int error = -ENOENT;
++ struct aa_namespace *ns;
++ struct aa_profile *profile, *onexec, *prev;
++ const struct cred *cred = aa_get_task_policy(task, &profile);
++ struct aa_task_context *cxt = cred->security;
++ ns = cxt->sys.profile->ns;
++ onexec = cxt->sys.onexec;
++ prev = cxt->sys.previous;
++
++ /* task must be either querying itself, unconfined or can ptrace */
++ if (current != task && profile && !capable(CAP_SYS_PTRACE)) {
++ error = -EPERM;
++ } else {
++ if (strcmp(name, "current") == 0) {
++ error = aa_getprocattr(ns, profile, value);
++ } else if (strcmp(name, "prev") == 0) {
++ if (prev)
++ error = aa_getprocattr(ns, prev, value);
++ } else if (strcmp(name, "exec") == 0) {
++ if (onexec)
++ error = aa_getprocattr(ns, onexec, value);
++ } else {
++ error = -EINVAL;
++ }
++ }
++
++ put_cred(cred);
++
++ return error;
++}
++
++static int apparmor_setprocattr(struct task_struct *task, char *name,
++ void *value, size_t size)
++{
++ char *command, *args;
++ int error;
++
++ if (size == 0 || size >= PAGE_SIZE)
++ return -EINVAL;
++
++ /* task can only write its own attributes */
++ if (current != task)
++ return -EACCES;
++
++ args = value;
++ args[size] = '\0';
++ args = strstrip(args);
++ command = strsep(&args, " ");
++ if (!args)
++ return -EINVAL;
++ while (isspace(*args))
++ args++;
++ if (!*args)
++ return -EINVAL;
++
++ if (strcmp(name, "current") == 0) {
++ if (strcmp(command, "changehat") == 0) {
++ error = aa_setprocattr_changehat(args, !AA_DO_TEST);
++ } else if (strcmp(command, "permhat") == 0) {
++ error = aa_setprocattr_changehat(args, AA_DO_TEST);
++ } else if (strcmp(command, "changeprofile") == 0) {
++ error = aa_setprocattr_changeprofile(args, 0,
++ !AA_DO_TEST);
++ } else if (strcmp(command, "permprofile") == 0) {
++ error = aa_setprocattr_changeprofile(args, 0,
++ AA_DO_TEST);
++ } else if (strcmp(command, "permipc") == 0) {
++ error = aa_setprocattr_permipc(args);
++ } else {
++ struct aa_audit sa;
++ memset(&sa, 0, sizeof(sa));
++ sa.operation = "setprocattr";
++ sa.gfp_mask = GFP_KERNEL;
++ sa.info = name;
++ sa.error = -EINVAL;
++ return aa_audit(AUDIT_APPARMOR_DENIED, NULL, &sa, NULL);
++ }
++ } else if (strcmp(name, "exec") == 0) {
++ error = aa_setprocattr_changeprofile(strstrip(args), 1,
++ !AA_DO_TEST);
++ } else {
++ /* only support the "current" and "exec" process attributes */
++ return -EINVAL;
++ }
++ if (!error)
++ error = size;
++ return error;
++}
++
++static int apparmor_task_setrlimit(unsigned int resource,
++ struct rlimit *new_rlim)
++{
++ struct aa_profile *profile = aa_current_profile_wupd();
++ int error = 0;
++
++ if (profile) {
++ error = aa_task_setrlimit(profile, resource, new_rlim);
++ }
++
++ return error;
++}
++
++#ifdef CONFIG_SECURITY_APPARMOR_NETWORK
++static int apparmor_socket_create(int family, int type, int protocol, int kern){
++ struct aa_profile *profile;
++ int error = 0;
++
++ if (kern)
++ return 0;
++
++ profile = aa_current_profile();
++ if (profile)
++ error = aa_net_perm(profile, "socket_create", family,
++ type, protocol);
++ return error;
++}
++
++static int apparmor_socket_post_create(struct socket *sock, int family,
++ int type, int protocol, int kern)
++{
++ struct sock *sk = sock->sk;
++
++ if (kern)
++ return 0;
++
++ return aa_revalidate_sk(sk, "socket_post_create");
++}
++
++static int apparmor_socket_bind(struct socket *sock,
++ struct sockaddr *address, int addrlen)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_bind");
++}
++
++static int apparmor_socket_connect(struct socket *sock,
++ struct sockaddr *address, int addrlen)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_connect");
++}
++
++static int apparmor_socket_listen(struct socket *sock, int backlog)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_listen");
++}
++
++static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_accept");
++}
++
++static int apparmor_socket_sendmsg(struct socket *sock,
++ struct msghdr *msg, int size)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_sendmsg");
++}
++
++static int apparmor_socket_recvmsg(struct socket *sock,
++ struct msghdr *msg, int size, int flags)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_recvmsg");
++}
++
++static int apparmor_socket_getsockname(struct socket *sock)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_getsockname");
++}
++
++static int apparmor_socket_getpeername(struct socket *sock)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_getpeername");
++}
++
++static int apparmor_socket_getsockopt(struct socket *sock, int level,
++ int optname)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_getsockopt");
++}
++
++static int apparmor_socket_setsockopt(struct socket *sock, int level,
++ int optname)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_setsockopt");
++}
++
++static int apparmor_socket_shutdown(struct socket *sock, int how)
++{
++ struct sock *sk = sock->sk;
++
++ return aa_revalidate_sk(sk, "socket_shutdown");
++}
++#endif
++
++static struct security_operations apparmor_ops = {
++ .name = "apparmor",
++
++ .ptrace_may_access = apparmor_ptrace_may_access,
++ .ptrace_traceme = apparmor_ptrace_traceme,
++ .capget = apparmor_capget,
++ .sysctl = apparmor_sysctl,
++ .capable = apparmor_capable,
++/*
++ .inode_create = apparmor_inode_create,
++ .inode_setattr = apparmor_inode_setattr,
++ .inode_setxattr = apparmor_inode_setxattr,
++ .inode_getxattr = apparmor_inode_getxattr,
++ .inode_listxattr = apparmor_inode_listxattr,
++ .inode_removexattr = apparmor_inode_removexattr,
++ .inode_permission = ??? use to mediate owner access to non-mediated fs
++*/
++
++ .path_link = apparmor_path_link,
++ .path_unlink = apparmor_path_unlink,
++ .path_symlink = apparmor_path_symlink,
++ .path_mkdir = apparmor_path_mkdir,
++ .path_rmdir = apparmor_path_rmdir,
++ .path_mknod = apparmor_path_mknod,
++ .path_rename = apparmor_path_rename,
++ .path_truncate = apparmor_path_truncate,
++ .dentry_open = apparmor_dentry_open,
++
++ .file_permission = apparmor_file_permission,
++ .file_alloc_security = apparmor_file_alloc_security,
++ .file_free_security = apparmor_file_free_security,
++ .file_mmap = apparmor_file_mmap,
++ .file_mprotect = apparmor_file_mprotect,
++ .file_lock = apparmor_file_lock,
++
++/* .file_fcntl = apparmor_file_fcntl, */
++
++ .getprocattr = apparmor_getprocattr,
++ .setprocattr = apparmor_setprocattr,
++
++#ifdef CONFIG_SECURITY_APPARMOR_NETWORK
++ .socket_create = apparmor_socket_create,
++ .socket_post_create = apparmor_socket_post_create,
++ .socket_bind = apparmor_socket_bind,
++ .socket_connect = apparmor_socket_connect,
++ .socket_listen = apparmor_socket_listen,
++ .socket_accept = apparmor_socket_accept,
++ .socket_sendmsg = apparmor_socket_sendmsg,
++ .socket_recvmsg = apparmor_socket_recvmsg,
++ .socket_getsockname = apparmor_socket_getsockname,
++ .socket_getpeername = apparmor_socket_getpeername,
++ .socket_getsockopt = apparmor_socket_getsockopt,
++ .socket_setsockopt = apparmor_socket_setsockopt,
++ .socket_shutdown = apparmor_socket_shutdown,
++#endif
++
++ .cred_free = apparmor_cred_free,
++ .cred_prepare = apparmor_cred_prepare,
++
++ .bprm_set_creds = apparmor_bprm_set_creds,
++ // .bprm_committing_creds = apparmor_bprm_committing_creds,
++ .bprm_committed_creds = apparmor_bprm_committed_creds,
++ .bprm_secureexec = apparmor_bprm_secureexec,
++
++ .task_setrlimit = apparmor_task_setrlimit,
++};
++
++
++/*
++ * AppArmor sysfs module parameters
++ */
++
++static int param_set_aabool(const char *val, struct kernel_param *kp);
++static int param_get_aabool(char *buffer, struct kernel_param *kp);
++#define param_check_aabool(name, p) __param_check(name, p, int)
++
++static int param_set_aauint(const char *val, struct kernel_param *kp);
++static int param_get_aauint(char *buffer, struct kernel_param *kp);
++#define param_check_aauint(name, p) __param_check(name, p, int)
++
++static int param_set_aalockpolicy(const char *val, struct kernel_param *kp);
++static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp);
++#define param_check_aalockpolicy(name, p) __param_check(name, p, int)
++
++static int param_set_audit(const char *val, struct kernel_param *kp);
++static int param_get_audit(char *buffer, struct kernel_param *kp);
++#define param_check_audit(name, p) __param_check(name, p, int)
++
++static int param_set_mode(const char *val, struct kernel_param *kp);
++static int param_get_mode(char *buffer, struct kernel_param *kp);
++#define param_check_mode(name, p) __param_check(name, p, int)
++
++/* Flag values, also controllable via /sys/module/apparmor/parameters
++ * We define special types as we want to do additional mediation.
++ */
++
++/* AppArmor global enforcement switch - complain, enforce, kill */
++enum profile_mode g_profile_mode = APPARMOR_ENFORCE;
++module_param_call(mode, param_set_mode, param_get_mode,
++ &g_profile_mode, S_IRUSR | S_IWUSR);
++
++/* Debug mode */
++int g_apparmor_debug;
++module_param_named(debug, g_apparmor_debug, aabool, S_IRUSR | S_IWUSR);
++
++/* Audit mode */
++enum audit_mode g_apparmor_audit;
++module_param_call(audit, param_set_audit, param_get_audit,
++ &g_apparmor_audit, S_IRUSR | S_IWUSR);
++
++/* Determines if audit header is included in audited messages. This
++ * provides more context if the audit daemon is not running
++ */
++int g_apparmor_audit_header;
++module_param_named(audit_header, g_apparmor_audit_header, aabool,
++ S_IRUSR | S_IWUSR);
++
++/* lock out loading/removal of policy
++ * TODO: add in at boot loading of policy, which is the only way to
++ * load policy, if lock_policy is set
++ */
++int g_apparmor_lock_policy;
++module_param_named(lock_policy, g_apparmor_lock_policy, aalockpolicy,
++ S_IRUSR | S_IWUSR);
++
++/* Syscall logging mode */
++int g_apparmor_logsyscall;
++module_param_named(logsyscall, g_apparmor_logsyscall, aabool,
++ S_IRUSR | S_IWUSR);
++
++/* Maximum pathname length before accesses will start getting rejected */
++unsigned int g_apparmor_path_max = 2 * PATH_MAX;
++module_param_named(path_max, g_apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
++
++/* Boot time disable flag */
++#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
++#define AA_ENABLED_PERMS 0600
++#else
++#define AA_ENABLED_PERMS 0400
++#endif
++static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
++static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
++module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
++ &apparmor_enabled, AA_ENABLED_PERMS);
++
++static int __init apparmor_enabled_setup(char *str)
++{
++ apparmor_enabled = simple_strtol(str, NULL, 0);
++ return 1;
++}
++__setup("apparmor=", apparmor_enabled_setup);
++
++static int param_set_aalockpolicy(const char *val, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ if (g_apparmor_lock_policy)
++ return -EACCES;
++ return param_set_bool(val, kp);
++}
++
++static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ return param_get_bool(buffer, kp);
++}
++
++static int param_set_aabool(const char *val, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ return param_set_bool(val, kp);
++}
++
++static int param_get_aabool(char *buffer, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ return param_get_bool(buffer, kp);
++}
++
++static int param_set_aauint(const char *val, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ return param_set_uint(val, kp);
++}
++
++static int param_get_aauint(char *buffer, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++ return param_get_uint(buffer, kp);
++}
++
++/* allow run time disabling of apparmor */
++static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
++{
++ unsigned long l;
++
++ if (!apparmor_initialized) {
++ apparmor_enabled = 0;
++ return 0;
++ }
++
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++
++ if (!apparmor_enabled)
++ return -EINVAL;
++
++ if (!val)
++ return -EINVAL;
++
++ if (strict_strtoul(val, 0, &l) || l != 0)
++ return -EINVAL;
++
++ apparmor_enabled = 0;
++ apparmor_disable();
++ return 0;
++}
++
++static int param_get_audit(char *buffer, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++
++ if (!apparmor_enabled)
++ return -EINVAL;
++
++ return sprintf(buffer, "%s", audit_mode_names[g_apparmor_audit]);
++}
++
++static int param_set_audit(const char *val, struct kernel_param *kp)
++{
++ int i;
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++
++ if (!apparmor_enabled)
++ return -EINVAL;
++
++ if (!val)
++ return -EINVAL;
++
++ for (i = 0; i < AUDIT_MAX_INDEX; i++) {
++ if (strcmp(val, audit_mode_names[i]) == 0) {
++ g_apparmor_audit = i;
++ return 0;
++ }
++ }
++
++ return -EINVAL;
++}
++
++static int param_get_mode(char *buffer, struct kernel_param *kp)
++{
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++
++ if (!apparmor_enabled)
++ return -EINVAL;
++
++ return sprintf(buffer, "%s", profile_mode_names[g_profile_mode]);
++}
++
++static int param_set_mode(const char *val, struct kernel_param *kp)
++{
++ int i;
++ if (__aa_task_is_confined(current))
++ return -EPERM;
++
++ if (!apparmor_enabled)
++ return -EINVAL;
++
++ if (!val)
++ return -EINVAL;
++
++ for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) {
++ if (strcmp(val, profile_mode_names[i]) == 0) {
++ g_profile_mode = i;
++ return 0;
++ }
++ }
++
++ return -EINVAL;
++}
++
++
++/*
++ * AppArmor init functions
++ */
++
++static int set_init_cxt(void)
++{
++ struct cred *cred = (struct cred *) current->real_cred;
++ struct aa_task_context *cxt;
++
++ cxt = aa_alloc_task_context(GFP_KERNEL);
++ if (!cxt)
++ return -ENOMEM;
++
++ cxt->sys.profile = aa_get_profile(default_namespace->unconfined);
++ cred->security = cxt;
++
++ return 0;
++}
++
++static int __init apparmor_init(void)
++{
++ int error;
++
++ if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
++ info_message("AppArmor disabled by boot time parameter\n");
++ return 0;
++ }
++
++ /*
++ * Activated with fs_initcall
++ error = create_apparmorfs();
++ if (error) {
++ AA_ERROR("Unable to activate AppArmor filesystem\n");
++ goto createfs_out;
++ }
++ */
++
++ error = alloc_default_namespace();
++ if (error) {
++ AA_ERROR("Unable to allocate default profile namespace\n");
++ goto alloc_out;
++ }
++
++ error = set_init_cxt();
++ if (error) {
++ AA_ERROR("Failed to set context on init task\n");
++ goto alloc_out;
++ }
++
++ error = register_security(&apparmor_ops);
++ if (error) {
++ AA_ERROR("Unable to register AppArmor\n");
++ goto register_security_out;
++ }
++
++ /* Report that AppArmor successfully initialized */
++ apparmor_initialized = 1;
++ if (g_profile_mode == APPARMOR_COMPLAIN)
++ info_message("AppArmor initialized: complain mode enabled");
++ else if (g_profile_mode == APPARMOR_KILL)
++ info_message("AppArmor initialized: kill mode enabled");
++ else
++ info_message("AppArmor initialized");
++
++ return error;
++
++register_security_out:
++ free_default_namespace();
++
++alloc_out:
++ destroy_apparmorfs();
++
++/*createfs_out:*/
++ return error;
++
++}
++
++security_initcall(apparmor_init);
++
++void apparmor_disable(void)
++{
++ /* Remove and release all the profiles on the profile list. */
++ aa_profile_ns_list_release();
++
++ /* FIXME: cleanup profiles references on files */
++ free_default_namespace();
++
++ /*
++ * Delay for an rcu cycle to make sure that all active task
++ * context readers have finished, and all profiles have been
++ * freed by their rcu callbacks.
++ */
++ synchronize_rcu();
++ destroy_apparmorfs();
++ apparmor_initialized = 0;
++
++ info_message("AppArmor protection disabled");
++}
++
+--- /dev/null
++++ b/security/apparmor/match.c
+@@ -0,0 +1,293 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor dfa based regular expression matching engine
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++
++/* TODO: remove !!!! */
++// #include <linux/fs.h>
++
++#include "include/apparmor.h"
++#include "include/match.h"
++#include "include/file.h"
++
++static struct table_header *unpack_table(void *blob, size_t bsize)
++{
++ struct table_header *table = NULL;
++ struct table_header th;
++ size_t tsize;
++
++ if (bsize < sizeof(struct table_header))
++ goto out;
++
++ th.td_id = be16_to_cpu(*(u16 *) (blob));
++ th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
++ th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
++ blob += sizeof(struct table_header);
++
++ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
++ th.td_flags == YYTD_DATA8))
++ goto out;
++
++ tsize = table_size(th.td_lolen, th.td_flags);
++ if (bsize < tsize)
++ goto out;
++
++ table = kmalloc(tsize, GFP_KERNEL);
++ if (table) {
++ *table = th;
++ if (th.td_flags == YYTD_DATA8)
++ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
++ u8, byte_to_byte);
++ else if (th.td_flags == YYTD_DATA16)
++ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
++ u16, be16_to_cpu);
++ else
++ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
++ u32, be32_to_cpu);
++ }
++
++out:
++ return table;
++}
++
++int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
++{
++ int hsize, i;
++ int error = -ENOMEM;
++
++ /* get dfa table set header */
++ if (size < sizeof(struct table_set_header))
++ goto fail;
++
++ if (ntohl(*(u32 *)blob) != YYTH_MAGIC)
++ goto fail;
++
++ hsize = ntohl(*(u32 *)(blob + 4));
++ if (size < hsize)
++ goto fail;
++
++ blob += hsize;
++ size -= hsize;
++
++ error = -EPROTO;
++ while (size > 0) {
++ struct table_header *table;
++ table = unpack_table(blob, size);
++ if (!table)
++ goto fail;
++
++ switch (table->td_id) {
++ case YYTD_ID_ACCEPT:
++ case YYTD_ID_ACCEPT2:
++ case YYTD_ID_BASE:
++ dfa->tables[table->td_id - 1] = table;
++ if (table->td_flags != YYTD_DATA32)
++ goto fail;
++ break;
++ case YYTD_ID_DEF:
++ case YYTD_ID_NXT:
++ case YYTD_ID_CHK:
++ dfa->tables[table->td_id - 1] = table;
++ if (table->td_flags != YYTD_DATA16)
++ goto fail;
++ break;
++ case YYTD_ID_EC:
++ dfa->tables[table->td_id - 1] = table;
++ if (table->td_flags != YYTD_DATA8)
++ goto fail;
++ break;
++ default:
++ kfree(table);
++ goto fail;
++ }
++
++ blob += table_size(table->td_lolen, table->td_flags);
++ size -= table_size(table->td_lolen, table->td_flags);
++ }
++
++ return 0;
++
++fail:
++ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
++ kfree(dfa->tables[i]);
++ dfa->tables[i] = NULL;
++ }
++ return error;
++}
++
++/**
++ * verify_dfa - verify that all the transitions and states in the dfa tables
++ * are in bounds.
++ * @dfa: dfa to test
++ *
++ * assumes dfa has gone through the verification done by unpacking
++ */
++int verify_dfa(struct aa_dfa *dfa)
++{
++ size_t i, state_count, trans_count;
++ int error = -EPROTO;
++
++ /* check that required tables exist */
++ if (!(dfa->tables[YYTD_ID_ACCEPT - 1] &&
++ dfa->tables[YYTD_ID_ACCEPT2 - 1] &&
++ dfa->tables[YYTD_ID_DEF - 1] &&
++ dfa->tables[YYTD_ID_BASE - 1] &&
++ dfa->tables[YYTD_ID_NXT - 1] &&
++ dfa->tables[YYTD_ID_CHK - 1]))
++ goto out;
++
++ /* accept.size == default.size == base.size */
++ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen;
++ if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen &&
++ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen &&
++ state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen))
++ goto out;
++
++ /* next.size == chk.size */
++ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen;
++ if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
++ goto out;
++
++ /* if equivalence classes then its table size must be 256 */
++ if (dfa->tables[YYTD_ID_EC - 1] &&
++ dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
++ goto out;
++
++ for (i = 0; i < state_count; i++) {
++ if (DEFAULT_TABLE(dfa)[i] >= state_count)
++ goto out;
++ if (BASE_TABLE(dfa)[i] >= trans_count + 256)
++ goto out;
++ }
++
++ for (i = 0; i < trans_count ; i++) {
++ if (NEXT_TABLE(dfa)[i] >= state_count)
++ goto out;
++ if (CHECK_TABLE(dfa)[i] >= state_count)
++ goto out;
++ }
++
++ /* verify accept permissions */
++ for (i = 0; i < state_count; i++) {
++ int mode = ACCEPT_TABLE(dfa)[i];
++
++ if (mode & ~DFA_VALID_PERM_MASK)
++ goto out;
++ if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
++ goto out;
++
++ }
++
++ error = 0;
++out:
++ return error;
++}
++
++struct aa_dfa *aa_match_alloc(void)
++{
++ return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
++}
++
++void aa_match_free(struct aa_dfa *dfa)
++{
++ if (dfa) {
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
++ kfree(dfa->tables[i]);
++ }
++ kfree(dfa);
++}
++
++/**
++ * aa_dfa_match_len - traverse @dfa to find state @str stops at
++ * @dfa: the dfa to match @str against
++ * @start: the state of the dfa to start matching in
++ * @str: the string of bytes to match against the dfa
++ * @len: length of the string of bytes to match
++ *
++ * aa_dfa_match_len will match @str against the dfa and return the state it
++ * finished matching in. The final state can be used to look up the accepting
++ * label, or as the start state of a continuing match.
++ *
++ * This function will happily match again the 0 byte and only finishes
++ * when @len input is consumed.
++ */
++unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
++ const char *str, int len)
++{
++ u16 *def = DEFAULT_TABLE(dfa);
++ u32 *base = BASE_TABLE(dfa);
++ u16 *next = NEXT_TABLE(dfa);
++ u16 *check = CHECK_TABLE(dfa);
++ unsigned int state = start, pos;
++
++ if (state == 0)
++ return 0;
++
++ /* current state is <state>, matching character *str */
++ if (dfa->tables[YYTD_ID_EC - 1]) {
++ u8 *equiv = EQUIV_TABLE(dfa);
++ for (; len; len--) {
++ pos = base[state] + equiv[(u8)*str++];
++ if (check[pos] == state)
++ state = next[pos];
++ else
++ state = def[state];
++ }
++ } else {
++ for (; len; len--) {
++ pos = base[state] + (u8)*str++;
++ if (check[pos] == state)
++ state = next[pos];
++ else
++ state = def[state];
++ }
++ }
++ return state;
++}
++
++
++/**
++ * aa_dfa_next_state - traverse @dfa to find state @str stops at
++ * @dfa: the dfa to match @str against
++ * @start: the state of the dfa to start matching in
++ * @str: the null terminated string of bytes to match against the dfa
++ *
++ * aa_dfa_next_state will match @str against the dfa and return the state it
++ * finished matching in. The final state can be used to look up the accepting
++ * label, or as the start state of a continuing match.
++ */
++unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
++ const char *str)
++{
++ return aa_dfa_match_len(dfa, start, str, strlen(str));
++}
++
++/**
++ * aa_dfa_null_transition - step to next state after null character
++ * @dfa: the dfa to match against
++ * @start: the state of the dfa to start matching in
++ *
++ * aa_dfa_null_transition transitions to the next state after a null
++ * character which is not used in standard matching and is only
++ * used to seperate pairs.
++ */
++unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
++{
++ return aa_dfa_match_len(dfa, start, "", 1);
++}
++
+--- /dev/null
++++ b/security/apparmor/net.c
+@@ -0,0 +1,146 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor network mediation
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include "include/apparmor.h"
++#include "include/audit.h"
++#include "include/context.h"
++#include "include/net.h"
++#include "include/policy.h"
++
++#include "af_names.h"
++
++static const char *sock_type_names[] = {
++ "unknown(0)",
++ "stream",
++ "dgram",
++ "raw",
++ "rdm",
++ "seqpacket",
++ "dccp",
++ "unknown(7)",
++ "unknown(8)",
++ "unknown(9)",
++ "packet",
++};
++
++struct aa_audit_net {
++ struct aa_audit base;
++
++ int family, type, protocol;
++
++};
++
++static void audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_net *sa = va;
++
++ if (sa->family || sa->type) {
++ if (address_family_names[sa->family])
++ audit_log_format(ab, " family=\"%s\"",
++ address_family_names[sa->family]);
++ else
++ audit_log_format(ab, " family=\"unknown(%d)\"",
++ sa->family);
++
++ if (sock_type_names[sa->type])
++ audit_log_format(ab, " sock_type=\"%s\"",
++ sock_type_names[sa->type]);
++ else
++ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
++ sa->type);
++
++ audit_log_format(ab, " protocol=%d", sa->protocol);
++ }
++
++}
++
++static int aa_audit_net(struct aa_profile *profile, struct aa_audit_net *sa)
++{
++ int type = AUDIT_APPARMOR_AUTO;
++
++ if (likely(!sa->base.error)) {
++ u16 audit_mask = profile->net.audit[sa->family];
++ if (likely((PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) &&
++ !(1 << sa->type & audit_mask)))
++ return 0;
++ } else {
++ u16 quiet_mask = profile->net.quiet[sa->family];
++ u16 kill_mask = 0;
++ u16 denied = (1 << sa->type) & ~quiet_mask;
++
++ if (denied & kill_mask)
++ type = AUDIT_APPARMOR_KILL;
++
++ if ((denied & quiet_mask) &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_NOQUIET &&
++ PROFILE_AUDIT_MODE(profile) != AUDIT_ALL)
++ return PROFILE_COMPLAIN(profile) ? 0 : sa->base.error;
++ }
++
++ return aa_audit(type, profile, (struct aa_audit *)sa, audit_cb);
++}
++
++int aa_net_perm(struct aa_profile *profile, char *operation,
++ int family, int type, int protocol)
++{
++ struct aa_audit_net sa;
++ u16 family_mask;
++
++ if ((family < 0) || (family >= AF_MAX))
++ return -EINVAL;
++
++ if ((type < 0) || (type >= SOCK_MAX))
++ return -EINVAL;
++
++ /* unix domain and netlink sockets are handled by ipc */
++ if (family == AF_UNIX || family == AF_NETLINK)
++ return 0;
++
++ family_mask = profile->net.allowed[family];
++
++ sa.base.error = (family_mask & (1 << type)) ? 0 : -EACCES;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = operation;
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.family = family;
++ sa.type = type;
++ sa.protocol = protocol;
++
++ return aa_audit_net(profile, &sa);
++}
++
++int aa_revalidate_sk(struct sock *sk, char *operation)
++{
++ struct aa_profile *profile;
++ struct cred *cred;
++ int error = 0;
++
++ /* this is some debugging code to flush out the network hooks that
++ that are called in interrupt context */
++ if (in_interrupt()) {
++ printk(KERN_WARNING "AppArmor Debug: Hook being called from interrupt context\n");
++ dump_stack();
++ return 0;
++ }
++
++ cred = aa_get_task_policy(current, &profile);
++ if (profile)
++ error = aa_net_perm(profile, operation,
++ sk->sk_family, sk->sk_type,
++ sk->sk_protocol);
++ put_cred(cred);
++
++ return error;
++}
+--- /dev/null
++++ b/security/apparmor/path.c
+@@ -0,0 +1,155 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor function for pathnames
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/mnt_namespace.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/path.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/fs_struct.h>
++
++#include "include/apparmor.h"
++#include "include/path.h"
++
++int aa_get_name_to_buffer(struct path *path, int is_dir, char *buffer, int size,
++ char **name)
++{
++ int error = d_namespace_path(path, buffer, size - is_dir, name);
++
++ if (!error && is_dir && (*name)[1] != '\0')
++ /*
++ * Append "/" to the pathname. The root directory is a special
++ * case; it already ends in slash.
++ */
++ strcpy(&buffer[size - 2], "/");
++
++ return error;
++}
++
++/**
++ * aa_get_name - compute the pathname of a file
++ * @path: path the file
++ * @is_dir: set if the file is a directory
++ * @buffer: buffer that aa_get_name() allocated
++ * @name: the error code indicating whether aa_get_name failed
++ *
++ * Returns an error code if the there was a failure in obtaining the
++ * name.
++ *
++ * @name is apointer to the beginning of the pathname (which usually differs
++ * from the beginning of the buffer), or NULL. If there is an error @name
++ * may contain a partial or invalid name (in the case of a deleted file), that
++ * can be used for audit purposes, but it can not be used for mediation.
++ *
++ * We need @is_dir to indicate whether the file is a directory or not because
++ * the file may not yet exist, and so we cannot check the inode's file type.
++ */
++int aa_get_name(struct path *path, int is_dir, char **buffer, char **name)
++{
++ char *buf, *str = NULL;
++ int size = 256;
++ int error;
++
++ *name = NULL;
++ *buffer = NULL;
++ for (;;) {
++ buf = kmalloc(size, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ error = aa_get_name_to_buffer(path, is_dir, buf, size, &str);
++ if (!error || (error == -ENOENT) || (error == -ESTALE))
++ break;
++
++ kfree(buf);
++ size <<= 1;
++ if (size > g_apparmor_path_max)
++ return -ENAMETOOLONG;
++ }
++ *buffer = buf;
++ *name = str;
++
++ return error;
++}
++
++int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
++{
++ struct path root, tmp, ns_root = { };
++ char *res;
++ int error = 0;
++
++ read_lock(&current->fs->lock);
++ root = current->fs->root;
++ path_get(&current->fs->root);
++ read_unlock(&current->fs->lock);
++ spin_lock(&vfsmount_lock);
++ if (root.mnt && root.mnt->mnt_ns)
++ ns_root.mnt = mntget(root.mnt->mnt_ns->root);
++ if (ns_root.mnt)
++ ns_root.dentry = dget(ns_root.mnt->mnt_root);
++ spin_unlock(&vfsmount_lock);
++ spin_lock(&dcache_lock);
++ tmp = ns_root;
++ res = __d_path(path, &tmp, buf, buflen);
++
++ *name = res;
++ /* handle error conditions - and still allow a partial path to
++ * be returned */
++ if (IS_ERR(res)) {
++ error = PTR_ERR(res);
++ *name = buf;
++ } else if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) {
++ error = -ENOENT;
++#if 0
++ } else if (tmp.dentry != ns_root.dentry && tmp.mnt != ns_root.mnt) {
++ /* disconnected path don return pathname starting with '/' */
++ error = -ESTALE;
++ if (*res == '/')
++ *name = res + 1;
++#endif
++ }
++
++ spin_unlock(&dcache_lock);
++ path_put(&root);
++ path_put(&ns_root);
++
++ return error;
++}
++
++char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen)
++{
++ if (buflen < 1)
++ return NULL;
++ buffer += --buflen;
++ *buffer = '\0';
++
++ while (table) {
++ int namelen = strlen(table->procname);
++
++ if (buflen < namelen + 1)
++ return NULL;
++ buflen -= namelen + 1;
++ buffer -= namelen;
++ memcpy(buffer, table->procname, namelen);
++ *--buffer = '/';
++ table = table->parent;
++ }
++ if (buflen < 4)
++ return NULL;
++ buffer -= 4;
++ memcpy(buffer, "/sys", 4);
++
++ return buffer;
++}
+--- /dev/null
++++ b/security/apparmor/policy.c
+@@ -0,0 +1,727 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor policy manipulation functions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ *
++ *
++ * AppArmor policy is based around profiles, which contain the rules a
++ * task is confined by. Every task in the sytem has a profile attached
++ * to it determined either by matching "unconfined" tasks against the
++ * visible set of profiles or by following a profiles attachment rules.
++ *
++ * Each profile exists in an AppArmor profile namespace which is a
++ * container of related profiles. Each namespace contains a special
++ * "unconfined" profile, which doesn't efforce any confinement on
++ * a task beyond DAC.
++ *
++ * Namespace and profile names can be written together in either
++ * of two syntaxes.
++ * :namespace:profile - used by kernel interfaces for easy detection
++ * namespace://profile - used by policy
++ *
++ * Profile names name not start with : or @ and may not contain \0
++ * a // in a profile name indicates a compound name with the name before
++ * the // being the parent profile and the name after the child
++ *
++ * Reserved profile names
++ * unconfined - special automatically generated unconfined profile
++ * inherit - special name to indicate profile inheritance
++ * null-XXXX-YYYY - special automically generated learning profiles
++ *
++ * Namespace names may not start with / or @ and may not contain \0 or //
++ * it is recommend that they do not contain any '/' characters
++ * Reserved namespace namespace
++ * default - the default namespace setup by AppArmor
++ * user-XXXX - user defined profiles
++ */
++
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/string.h>
++
++#include "include/apparmor.h"
++#include "include/capability.h"
++#include "include/file.h"
++#include "include/ipc.h"
++#include "include/match.h"
++#include "include/policy.h"
++#include "include/resource.h"
++#include "include/sid.h"
++
++/* list of profile namespaces and lock */
++LIST_HEAD(ns_list);
++DEFINE_RWLOCK(ns_list_lock);
++
++struct aa_namespace *default_namespace;
++
++const char *profile_mode_names[] = {
++ "enforce",
++ "complain",
++ "kill",
++};
++
++#define AA_SYS_SID 0
++#define AA_USR_SID 1
++
++
++static int common_init(struct aa_policy_common *common, const char *name)
++{
++ common->name = kstrdup(name, GFP_KERNEL);
++ if (!common->name)
++ return 0;
++ INIT_LIST_HEAD(&common->list);
++ INIT_LIST_HEAD(&common->profiles);
++ kref_init(&common->count);
++ rwlock_init(&common->lock);
++
++ return 1;
++}
++
++static void common_free(struct aa_policy_common *common)
++{
++ /* still contains profiles -- invalid */
++ if (!list_empty(&common->profiles)) {
++ AA_ERROR("%s: internal error, "
++ "policy '%s' still contains profiles\n",
++ __func__, common->name);
++ BUG();
++ }
++ if (!list_empty(&common->list)) {
++ AA_ERROR("%s: internal error, policy '%s' still on list\n",
++ __func__, common->name);
++ BUG();
++ }
++
++ kfree(common->name);
++}
++
++static struct aa_policy_common *__common_find(struct list_head *head,
++ const char *name)
++
++{
++ struct aa_policy_common *common;
++
++ list_for_each_entry(common, head, list) {
++ if (!strcmp(common->name, name))
++ return common;
++ }
++ return NULL;
++}
++
++static struct aa_policy_common *__common_find_strn(struct list_head *head,
++ const char *str, int len)
++{
++ struct aa_policy_common *common;
++
++ list_for_each_entry(common, head, list) {
++ if (aa_strneq(common->name, str, len))
++ return common;
++ }
++
++ return NULL;
++}
++
++/*
++ * Routines for AppArmor namespaces
++ */
++
++int alloc_default_namespace(void)
++{
++ struct aa_namespace *ns;
++ ns = alloc_aa_namespace("default");
++ if (!ns)
++ return -ENOMEM;
++
++ default_namespace = aa_get_namespace(ns);
++ write_lock(&ns_list_lock);
++ list_add(&ns->base.list, &ns_list);
++ write_unlock(&ns_list_lock);
++
++ return 0;
++}
++
++void free_default_namespace(void)
++{
++ write_lock(&ns_list_lock);
++ list_del_init(&default_namespace->base.list);
++ aa_put_namespace(default_namespace);
++ write_unlock(&ns_list_lock);
++ aa_put_namespace(default_namespace);
++ default_namespace = NULL;
++}
++
++/**
++ * alloc_aa_namespace - allocate, initialize and return a new namespace
++ * @name: a preallocated name
++ * Returns NULL on failure.
++ */
++struct aa_namespace *alloc_aa_namespace(const char *name)
++{
++ struct aa_namespace *ns;
++
++ ns = kzalloc(sizeof(*ns), GFP_KERNEL);
++ AA_DEBUG("%s(%p)\n", __func__, ns);
++ if (!ns)
++ return NULL;
++
++ if (!common_init(&ns->base, name))
++ goto fail_ns;
++
++ /* null profile is not added to the profile list */
++ ns->unconfined = alloc_aa_profile("unconfined");
++ if (!ns->unconfined)
++ goto fail_unconfined;
++
++ ns->unconfined->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
++ ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
++ PFLAG_IMMUTABLE;
++ ns->unconfined->ns = aa_get_namespace(ns);
++
++ return ns;
++
++fail_unconfined:
++ if (ns->base.name)
++ kfree(ns->base.name);
++fail_ns:
++ kfree(ns);
++ return NULL;
++}
++
++/**
++ * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
++ * @kr: kref callback for freeing of a namespace
++ */
++void free_aa_namespace_kref(struct kref *kref)
++{
++ free_aa_namespace(container_of(kref, struct aa_namespace, base.count));
++}
++
++/**
++ * free_aa_namespace - free a profile namespace
++ * @namespace: the namespace to free
++ *
++ * Free a namespace. All references to the namespace must have been put.
++ * If the namespace was referenced by a profile confining a task,
++ */
++void free_aa_namespace(struct aa_namespace *ns)
++{
++ if (!ns)
++ return;
++
++ common_free(&ns->base);
++
++ if (ns->unconfined && ns->unconfined->ns == ns)
++ ns->unconfined->ns = NULL;
++
++ aa_put_profile(ns->unconfined);
++ memset(ns, 0, sizeof(*ns));
++ kfree(ns);
++}
++
++struct aa_namespace *__aa_find_namespace(struct list_head *head,
++ const char *name)
++
++{
++ return (struct aa_namespace *) __common_find(head, name);
++}
++
++/**
++ * aa_find_namespace - look up a profile namespace on the namespace list
++ * @name: name of namespace to find
++ *
++ * Returns a pointer to the namespace on the list, or NULL if no namespace
++ * called @name exists.
++ */
++struct aa_namespace *aa_find_namespace(const char *name)
++{
++ struct aa_namespace *ns = NULL;
++
++ read_lock(&ns_list_lock);
++ ns = aa_get_namespace(__aa_find_namespace(&ns_list, name));
++ read_unlock(&ns_list_lock);
++
++ return ns;
++}
++
++static struct aa_namespace *__aa_find_namespace_by_strn(struct list_head *head,
++ const char *name,
++ int len)
++{
++ return (struct aa_namespace *) __common_find_strn(head, name, len);
++}
++
++struct aa_namespace *aa_find_namespace_by_strn(const char *name, int len)
++{
++ struct aa_namespace *ns = NULL;
++
++ read_lock(&ns_list_lock);
++ ns = aa_get_namespace(__aa_find_namespace_by_strn(&ns_list, name, len));
++ read_unlock(&ns_list_lock);
++
++ return ns;
++}
++
++/**
++ * aa_prepare_namespace - find an existing or create a new namespace of @name
++ * @name: the namespace to find or add
++ */
++struct aa_namespace *aa_prepare_namespace(const char *name)
++{
++ struct aa_namespace *ns;
++
++ write_lock(&ns_list_lock);
++ if (name)
++ ns = aa_get_namespace(__aa_find_namespace(&ns_list, name));
++ else
++ ns = aa_get_namespace(default_namespace);
++ if (!ns) {
++ struct aa_namespace *new_ns;
++ write_unlock(&ns_list_lock);
++ new_ns = alloc_aa_namespace(name);
++ if (!new_ns)
++ return NULL;
++ write_lock(&ns_list_lock);
++ ns = __aa_find_namespace(&ns_list, name);
++ if (!ns) {
++ list_add(&new_ns->base.list, &ns_list);
++ ns = new_ns;
++ } else {
++ /* raced so free the new one */
++ free_aa_namespace(new_ns);
++ aa_get_namespace(ns);
++ }
++ }
++ write_unlock(&ns_list_lock);
++
++ return ns;
++}
++
++/*
++ * requires profile->ns set first, takes profiles refcount
++ * TODO: add accounting
++ */
++void __aa_add_profile(struct aa_policy_common *common,
++ struct aa_profile *profile)
++{
++ list_add(&profile->base.list, &common->profiles);
++ if (!(profile->flags & PFLAG_NO_LIST_REF))
++ aa_get_profile(profile);
++}
++
++void __aa_remove_profile(struct aa_profile *profile,
++ struct aa_profile *replacement)
++{
++ if (replacement)
++ profile->replacedby = aa_get_profile(replacement);
++ else
++ profile->replacedby = ERR_PTR(-EINVAL);
++ list_del_init(&profile->base.list);
++ if (!(profile->flags & PFLAG_NO_LIST_REF))
++ aa_put_profile(profile);
++}
++
++/* TODO: add accounting */
++void __aa_replace_profile(struct aa_profile *profile,
++ struct aa_profile *replacement)
++{
++ if (replacement) {
++ struct aa_policy_common *common;
++
++ if (profile->parent)
++ common = &profile->parent->base;
++ else
++ common = &profile->ns->base;
++
++ __aa_remove_profile(profile, replacement);
++ __aa_add_profile(common, replacement);
++ } else
++ __aa_remove_profile(profile, NULL);
++}
++
++/**
++ * __aa_profile_list_release - remove all profiles on the list and put refs
++ * @head: list of profiles
++ */
++void __aa_profile_list_release(struct list_head *head)
++{
++ struct aa_profile *profile, *tmp;
++ list_for_each_entry_safe(profile, tmp, head, base.list) {
++ __aa_profile_list_release(&profile->base.profiles);
++ __aa_remove_profile(profile, NULL);
++ }
++}
++
++void __aa_remove_namespace(struct aa_namespace *ns)
++{
++ struct aa_profile *unconfined = ns->unconfined;
++ list_del_init(&ns->base.list);
++
++ /*
++ * break the ns, unconfined profile cyclic reference and forward
++ * all new unconfined profiles requests to the default namespace
++ */
++ ns->unconfined = aa_get_profile(default_namespace->unconfined);
++ __aa_profile_list_release(&ns->base.profiles);
++ aa_put_profile(unconfined);
++ aa_put_namespace(ns);
++}
++
++/**
++ * aa_remove_namespace = Remove namespace from the list
++ * @ns: namespace to remove
++ */
++void aa_remove_namespace(struct aa_namespace *ns)
++{
++ write_lock(&ns_list_lock);
++ write_lock(&ns->base.lock);
++ __aa_remove_namespace(ns);
++ write_unlock(&ns->base.lock);
++ write_unlock(&ns_list_lock);
++}
++
++/**
++ * aa_profilelist_release - remove all namespaces and all associated profiles
++ */
++void aa_profile_ns_list_release(void)
++{
++ struct aa_namespace *ns, *tmp;
++
++ /* Remove and release all the profiles on namespace profile lists. */
++ write_lock(&ns_list_lock);
++ list_for_each_entry_safe(ns, tmp, &ns_list, base.list) {
++ write_lock(&ns->base.lock);
++ __aa_remove_namespace(ns);
++ write_unlock(&ns->base.lock);
++ }
++ write_unlock(&ns_list_lock);
++}
++
++/**
++ * alloc_aa_profile - allocate, initialize and return a new profile
++ * @fqname: name of the profile
++ *
++ * Returns NULL on failure.
++ */
++struct aa_profile *alloc_aa_profile(const char *fqname)
++{
++ struct aa_profile *profile;
++
++ profile = kzalloc(sizeof(*profile), GFP_KERNEL);
++ if (!profile)
++ return NULL;
++
++ if (!common_init(&profile->base, fqname)) {
++ kfree(profile);
++ return NULL;
++ }
++
++ profile->fqname = profile->base.name;
++ profile->base.name = (char *) fqname_subname((const char *) profile->fqname);
++ return profile;
++}
++
++/**
++ * aa_new_null_profile - create a new null-X learning profile
++ * @parent: profile that caused this profile to be created
++ * @hat: true if the null- learning profile is a hat
++ *
++ * Create a null- complain mode profile used in learning mode. The name of
++ * the profile is unique and follows the format of parent//null-sid.
++ *
++ * null profiles are added to the profile list but the list does not
++ * hold a count on them so that they are automatically released when
++ * not in use.
++ */
++struct aa_profile *aa_alloc_null_profile(struct aa_profile *parent, int hat)
++{
++ struct aa_profile *profile = NULL;
++ char *name;
++ u32 sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
++
++ name = kmalloc(strlen(parent->fqname) + 2 + 7 + 8, GFP_KERNEL);
++ if (!name)
++ goto fail;
++ sprintf(name, "%s//null-%x", parent->fqname, sid);
++
++ profile = alloc_aa_profile(name);
++ kfree(name);
++ if (!profile)
++ goto fail;
++
++ profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
++ profile->mode = APPARMOR_COMPLAIN;
++ profile->flags = PFLAG_NULL | PFLAG_NO_LIST_REF;
++ if (hat)
++ profile->flags |= PFLAG_HAT;
++
++ profile->parent = aa_get_profile(parent);
++ profile->ns = aa_get_namespace(parent->ns);
++
++ write_lock(&profile->ns->base.lock);
++ __aa_add_profile(&parent->base, profile);
++ write_unlock(&profile->ns->base.lock);
++
++ return profile;
++
++fail:
++ aa_free_sid(sid);
++ return NULL;
++}
++
++/**
++ * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile)
++ * @kr: kref callback for freeing of a profile
++ */
++void free_aa_profile_kref(struct kref *kref)
++{
++ struct aa_profile *p = container_of(kref, struct aa_profile,
++ base.count);
++
++ free_aa_profile(p);
++}
++
++/**
++ * free_aa_profile - free a profile
++ * @profile: the profile to free
++ *
++ * Free a profile, its hats and null_profile. All references to the profile,
++ * its hats and null_profile must have been put.
++ *
++ * If the profile was referenced from a task context, free_aa_profile() will
++ * be called from an rcu callback routine, so we must not sleep here.
++ */
++void free_aa_profile(struct aa_profile *profile)
++{
++ AA_DEBUG("%s(%p)\n", __func__, profile);
++
++ if (!profile)
++ return;
++
++ /*
++ * profile can still be on the list if the list doesn't hold a
++ * reference. There is no race as NULL profiles can't be attached
++ */
++ if (!list_empty(&profile->base.list)) {
++ if ((profile->flags & PFLAG_NULL) && profile->ns) {
++ write_lock(&profile->ns->base.lock);
++ list_del_init(&profile->base.list);
++ write_unlock(&profile->ns->base.lock);
++ } else {
++ AA_ERROR("%s: internal error, "
++ "profile '%s' still on ns list\n",
++ __func__, profile->base.name);
++ BUG();
++ }
++ }
++
++ /* profile->name is a substring of fqname */
++ profile->base.name = NULL;
++ common_free(&profile->base);
++
++ BUG_ON(!list_empty(&profile->base.profiles));
++
++ kfree(profile->fqname);
++
++ aa_put_namespace(profile->ns);
++ aa_put_profile(profile->parent);
++
++ aa_free_file_rules(&profile->file);
++ aa_free_cap_rules(&profile->caps);
++ aa_free_net_rules(&profile->net);
++ aa_free_rlimit_rules(&profile->rlimits);
++
++ aa_free_sid(profile->sid);
++ aa_match_free(profile->xmatch);
++
++ if (profile->replacedby && !PTR_ERR(profile->replacedby))
++ aa_put_profile(profile->replacedby);
++
++ memset(profile, 0, sizeof(profile));
++ kfree(profile);
++}
++
++
++/* TODO: profile count accounting - setup in remove */
++
++
++struct aa_profile *__aa_find_profile(struct list_head *head, const char *name)
++{
++ return (struct aa_profile *) __common_find(head, name);
++}
++
++struct aa_profile *__aa_find_profile_by_strn(struct list_head *head,
++ const char *name, int len)
++{
++ return (struct aa_profile *) __common_find_strn(head, name, len);
++}
++
++
++/**
++ * aa_find_child - find a profile by @name in @parent
++ * @parent: profile to search
++ * @name: profile name to search for
++ *
++ * Returns a ref counted profile or NULL if not found
++ */
++struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
++{
++ struct aa_profile *profile;
++
++ read_lock(&parent->ns->base.lock);
++ profile = aa_get_profile(__aa_find_profile(&parent->base.profiles,
++ name));
++ read_unlock(&parent->ns->base.lock);
++
++ return profile;
++}
++
++
++struct aa_policy_common *__aa_find_parent_by_fqname(struct aa_namespace *ns,
++ const char *fqname)
++{
++ struct aa_policy_common *common;
++ struct aa_profile *profile = NULL;
++ char *split;
++
++ common = &ns->base;
++
++
++ for (split = strstr(fqname, "//"); split; ) {
++ profile = __aa_find_profile_by_strn(&common->profiles, fqname,
++ split - fqname);
++ if (!profile)
++ return NULL;
++ common = &profile->base;
++ fqname = split + 2;
++ split = strstr(fqname, "//");
++ }
++ if (!profile)
++ return &ns->base;
++ return &profile->base;
++}
++
++struct aa_profile *__aa_find_profile_by_fqname(struct aa_namespace *ns,
++ const char *fqname)
++{
++ struct aa_policy_common *common;
++ struct aa_profile *profile = NULL;
++ char *split;
++
++ common = &ns->base;
++ for (split = strstr(fqname, "//"); split; ) {
++ profile = __aa_find_profile_by_strn(&common->profiles, fqname,
++ split - fqname);
++ if (!profile)
++ return NULL;
++
++ common = &profile->base;
++ fqname = split + 2;
++ split = strstr(fqname, "//");
++ }
++
++ profile = __aa_find_profile(&common->profiles, fqname);
++
++ return profile;
++}
++
++/**
++ * aa_find_profile_by_name - find a profile by its full or partial name
++ * @ns: the namespace to start from
++ * @fqname: name to do lookup on. Does not contain namespace prefix
++ */
++struct aa_profile *aa_find_profile_by_fqname(struct aa_namespace *ns,
++ const char *fqname)
++{
++ struct aa_profile *profile;
++
++ read_lock(&ns->base.lock);
++ profile = aa_get_profile(__aa_find_profile_by_fqname(ns, fqname));
++ read_unlock(&ns->base.lock);
++ return profile;
++}
++
++
++/* __aa_attach_match_ - find an attachment match
++ * @name - to match against
++ * @head - profile list to walk
++ *
++ * Do a linear search on the profiles in the list. There is a matching
++ * preference where an exact match is prefered over a name which uses
++ * expressions to match, and matching expressions with the greatest
++ * xmatch_len are prefered.
++ */
++static struct aa_profile *__aa_attach_match(const char *name,
++ struct list_head *head)
++{
++ int len = 0;
++ struct aa_profile *profile, *candidate = NULL;
++
++ list_for_each_entry(profile, head, base.list) {
++ if (profile->flags & PFLAG_NULL)
++ continue;
++ if (profile->xmatch && profile->xmatch_len > len) {
++ unsigned int state = aa_dfa_match(profile->xmatch,
++ DFA_START, name);
++ /* any accepting state means a valid match */
++ if (state > DFA_START) {
++ candidate = profile;
++ len = profile->xmatch_len;
++ }
++ } else if (!strcmp(profile->base.name, name))
++ /* exact non-re match, no more searching required */
++ return profile;
++ }
++
++ return candidate;
++}
++
++/**
++ * aa_sys_find_attach - do attachment search for sys unconfined processes
++ * @ns: the namespace to search
++ * name: the executable name to match against
++ */
++struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns, const char *name)
++{
++ struct aa_profile *profile;
++
++ read_lock(&ns->base.lock);
++ profile = aa_get_profile(__aa_attach_match(name, &ns->base.profiles));
++ read_unlock(&ns->base.lock);
++
++ return profile;
++}
++
++/**
++ * aa_profile_newest - find the newest version of @profile
++ * @profile: the profile to check for newer versions of
++ *
++ * Find the newest version of @profile, if @profile is the newest version
++ * return @profile. If @profile has been removed return NULL.
++ *
++ * NOTE: the profile returned is not refcounted, The refcount on @profile
++ * must be held until the caller decides what to do with the returned newest
++ * version.
++ */
++struct aa_profile *aa_profile_newest(struct aa_profile *profile)
++{
++ if (unlikely(profile && profile->replacedby)) {
++ for (;profile->replacedby; profile = profile->replacedby) {
++ if (IS_ERR(profile->replacedby)) {
++ /* profile has been removed */
++ profile = NULL;
++ break;
++ }
++ }
++ }
++
++ return profile;
++}
++
+--- /dev/null
++++ b/security/apparmor/policy_interface.c
+@@ -0,0 +1,850 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor functions for unpacking policy loaded from
++ * userspace.
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ *
++ * AppArmor uses a serialized binary format for loading policy.
++ * The policy format is documented in Documentation/???
++ * All policy is validated all before it is used.
++ */
++
++#include <asm/unaligned.h>
++#include <linux/errno.h>
++
++#include "include/apparmor.h"
++#include "include/audit.h"
++#include "include/context.h"
++#include "include/match.h"
++#include "include/policy.h"
++#include "include/policy_interface.h"
++#include "include/sid.h"
++
++/* FIXME: convert profiles to internal hieracy, accounting
++ * FIXME: have replacement routines set replaced_by profile instead of error
++ * FIXME: name mapping to hierarchy
++ */
++
++/*
++ * The AppArmor interface treats data as a type byte followed by the
++ * actual data. The interface has the notion of a a named entry
++ * which has a name (AA_NAME typecode followed by name string) followed by
++ * the entries typecode and data. Named types allow for optional
++ * elements and extensions to be added and tested for without breaking
++ * backwards compatability.
++ */
++
++enum aa_code {
++ AA_U8,
++ AA_U16,
++ AA_U32,
++ AA_U64,
++ AA_NAME, /* same as string except it is items name */
++ AA_STRING,
++ AA_BLOB,
++ AA_STRUCT,
++ AA_STRUCTEND,
++ AA_LIST,
++ AA_LISTEND,
++ AA_ARRAY,
++ AA_ARRAYEND,
++};
++
++/*
++ * aa_ext is the read of the buffer containing the serialized profile. The
++ * data is copied into a kernel buffer in apparmorfs and then handed off to
++ * the unpack routines.
++ */
++struct aa_ext {
++ void *start;
++ void *end;
++ void *pos; /* pointer to current position in the buffer */
++ u32 version;
++ char *ns_name;
++};
++
++
++struct aa_audit_iface {
++ struct aa_audit base;
++
++ const char *name;
++ const char *name2;
++ const struct aa_ext *e;
++};
++
++static void aa_audit_init(struct aa_audit_iface *sa, const char *operation,
++ struct aa_ext *e)
++{
++ memset(sa, 0, sizeof(*sa));
++ sa->base.operation = operation;
++ sa->base.gfp_mask = GFP_KERNEL;
++ sa->e = e;
++}
++
++static void audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_iface *sa = va;
++
++ if (sa->name)
++ audit_log_format(ab, " name=%s", sa->name);
++ if (sa->name2)
++ audit_log_format(ab, " namespace=%s", sa->name2);
++ if (sa->base.error && sa->e)
++ audit_log_format(ab, " offset=%d", sa->e->pos - sa->e->start);
++}
++
++static int aa_audit_iface(struct aa_audit_iface *sa)
++{
++ struct aa_profile *profile;
++ struct cred *cred = aa_get_task_policy(current, &profile);
++ int error = aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa->base,
++ audit_cb);
++ put_cred(cred);
++ return error;
++}
++
++static int aa_inbounds(struct aa_ext *e, size_t size)
++{
++ return (size <= e->end - e->pos);
++}
++
++/**
++ * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
++ * @e: serialized data read head
++ * @chunk: start address for chunk of data
++ *
++ * return the size of chunk found with the read head at the end of
++ * the chunk.
++ */
++static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk)
++{
++ void *pos = e->pos;
++ size_t size = 0;
++
++ if (!aa_inbounds(e, sizeof(u16)))
++ goto fail;
++ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
++ e->pos += sizeof(u16);
++ if (!aa_inbounds(e, size))
++ goto fail;
++ *chunk = e->pos;
++ e->pos += size;
++ return size;
++
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_X(struct aa_ext *e, enum aa_code code)
++{
++ if (!aa_inbounds(e, 1))
++ return 0;
++ if (*(u8 *) e->pos != code)
++ return 0;
++ e->pos++;
++ return 1;
++}
++
++/**
++ * aa_is_nameX - check is the next element is of type X with a name of @name
++ * @e: serialized data extent information
++ * @code: type code
++ * @name: name to match to the serialized element.
++ *
++ * check that the next serialized data element is of type X and has a tag
++ * name @name. If @name is specified then there must be a matching
++ * name element in the stream. If @name is NULL any name element will be
++ * skipped and only the typecode will be tested.
++ * returns 1 on success (both type code and name tests match) and the read
++ * head is advanced past the headers
++ * returns %0 if either match failes, the read head does not move
++ */
++static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name)
++{
++ void *pos = e->pos;
++ /*
++ * Check for presence of a tagname, and if present name size
++ * AA_NAME tag value is a u16.
++ */
++ if (aa_is_X(e, AA_NAME)) {
++ char *tag = NULL;
++ size_t size = aa_is_u16_chunk(e, &tag);
++ /* if a name is specified it must match. otherwise skip tag */
++ if (name && (!size || strcmp(name, tag)))
++ goto fail;
++ } else if (name) {
++ /* if a name is specified and there is no name tag fail */
++ goto fail;
++ }
++
++ /* now check if type code matches */
++ if (aa_is_X(e, code))
++ return 1;
++
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name)
++{
++ void *pos = e->pos;
++ if (aa_is_nameX(e, AA_U16, name)) {
++ if (!aa_inbounds(e, sizeof(u16)))
++ goto fail;
++ if (data)
++ *data = le16_to_cpu(get_unaligned((u16 *)e->pos));
++ e->pos += sizeof(u16);
++ return 1;
++ }
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name)
++{
++ void *pos = e->pos;
++ if (aa_is_nameX(e, AA_U32, name)) {
++ if (!aa_inbounds(e, sizeof(u32)))
++ goto fail;
++ if (data)
++ *data = le32_to_cpu(get_unaligned((u32 *)e->pos));
++ e->pos += sizeof(u32);
++ return 1;
++ }
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name)
++{
++ void *pos = e->pos;
++ if (aa_is_nameX(e, AA_U64, name)) {
++ if (!aa_inbounds(e, sizeof(u64)))
++ goto fail;
++ if (data)
++ *data = le64_to_cpu(get_unaligned((u64 *)e->pos));
++ e->pos += sizeof(u64);
++ return 1;
++ }
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static size_t aa_is_array(struct aa_ext *e, const char *name)
++{
++ void *pos = e->pos;
++ if (aa_is_nameX(e, AA_ARRAY, name)) {
++ int size;
++ if (!aa_inbounds(e, sizeof(u16)))
++ goto fail;
++ size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos));
++ e->pos += sizeof(u16);
++ return size;
++ }
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name)
++{
++ void *pos = e->pos;
++ if (aa_is_nameX(e, AA_BLOB, name)) {
++ u32 size;
++ if (!aa_inbounds(e, sizeof(u32)))
++ goto fail;
++ size = le32_to_cpu(get_unaligned((u32 *)e->pos));
++ e->pos += sizeof(u32);
++ if (aa_inbounds(e, (size_t) size)) {
++ *blob = e->pos;
++ e->pos += size;
++ return size;
++ }
++ }
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_string(struct aa_ext *e, char **string, const char *name)
++{
++ char *src_str;
++ size_t size = 0;
++ void *pos = e->pos;
++ *string = NULL;
++ if (aa_is_nameX(e, AA_STRING, name) &&
++ (size = aa_is_u16_chunk(e, &src_str))) {
++ /* strings are null terminated, length is size - 1 */
++ if (src_str[size - 1] != 0)
++ goto fail;
++ *string = src_str;
++ }
++
++ return size;
++
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name)
++{
++ char *tmp;
++ void *pos = e->pos;
++ int res = aa_is_string(e, &tmp, name);
++ *string = NULL;
++
++ if (!res)
++ return res;
++
++ *string = kstrdup(tmp, GFP_KERNEL);
++ if (!*string) {
++ e->pos = pos;
++ return 0;
++ }
++
++ return res;
++}
++
++/**
++ * aa_unpack_dfa - unpack a file rule dfa
++ * @e: serialized data extent information
++ *
++ * returns dfa or ERR_PTR
++ */
++static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e)
++{
++ char *blob = NULL;
++ size_t size, error = 0;
++ struct aa_dfa *dfa = NULL;
++
++ size = aa_is_blob(e, &blob, "aadfa");
++ if (size) {
++ dfa = aa_match_alloc();
++ if (dfa) {
++ /*
++ * The dfa is aligned with in the blob to 8 bytes
++ * from the beginning of the stream.
++ */
++ size_t sz = blob - (char *) e->start;
++ size_t pad = ALIGN(sz, 8) - sz;
++ error = unpack_dfa(dfa, blob + pad, size - pad);
++ if (!error)
++ error = verify_dfa(dfa);
++ } else {
++ error = -ENOMEM;
++ }
++
++ if (error) {
++ aa_match_free(dfa);
++ dfa = ERR_PTR(error);
++ }
++ }
++
++ return dfa;
++}
++
++static int aa_unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
++{
++ void *pos = e->pos;
++
++ /* exec table is optional */
++ if (aa_is_nameX(e, AA_STRUCT, "xtable")) {
++ int i, size;
++
++ size = aa_is_array(e, NULL);
++ /* currently 4 exec bits and entries 0-3 are reserved iupcx */
++ if (size > 16 - 4)
++ goto fail;
++ profile->file.trans.table = kzalloc(sizeof(char *) * size,
++ GFP_KERNEL);
++ if (!profile->file.trans.table)
++ goto fail;
++
++ for (i = 0; i < size; i++) {
++ char *tmp;
++ if (!aa_is_dynstring(e, &tmp, NULL))
++ goto fail;
++ /* note: strings beginning with a : have an embedded
++ \0 seperating the profile ns name from the profile
++ name */
++ profile->file.trans.table[i] = tmp;
++ }
++ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
++ goto fail;
++ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
++ goto fail;
++ profile->file.trans.size = size;
++ }
++ return 1;
++
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
++{
++ void *pos = e->pos;
++
++ /* rlimits are optional */
++ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
++ int i, size;
++ u32 tmp = 0;
++ if (!aa_is_u32(e, &tmp, NULL))
++ goto fail;
++ profile->rlimits.mask = tmp;
++
++ size = aa_is_array(e, NULL);
++ if (size > RLIM_NLIMITS)
++ goto fail;
++ for (i = 0; i < size; i++) {
++ u64 tmp = 0;
++ if (!aa_is_u64(e, &tmp, NULL))
++ goto fail;
++ profile->rlimits.limits[i].rlim_max = tmp;
++ }
++ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
++ goto fail;
++ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
++ goto fail;
++ }
++ return 1;
++
++fail:
++ e->pos = pos;
++ return 0;
++}
++
++/**
++ * aa_unpack_profile - unpack a serialized profile
++ * @e: serialized data extent information
++ * @sa: audit struct for the operation
++ */
++static struct aa_profile *aa_unpack_profile(struct aa_ext *e,
++ struct aa_audit_iface *sa)
++{
++ struct aa_profile *profile = NULL;
++ char *name;
++ size_t size = 0;
++ int i, error = -EPROTO;
++ u32 tmp;
++
++ /* check that we have the right struct being passed */
++ if (!aa_is_nameX(e, AA_STRUCT, "profile"))
++ goto fail;
++ if (!aa_is_string(e, &name, NULL))
++ goto fail;
++
++ profile = alloc_aa_profile(name);
++ if (!profile)
++ return ERR_PTR(-ENOMEM);
++
++ /* xmatch is optional and may be NULL */
++ profile->xmatch = aa_unpack_dfa(e);
++ if (IS_ERR(profile->xmatch)) {
++ error = PTR_ERR(profile->xmatch);
++ profile->xmatch = NULL;
++ goto fail;
++ }
++ /* xmatch_len is not optional is xmatch is set */
++ if (profile->xmatch && !aa_is_u32(e, &tmp, NULL))
++ goto fail;
++ profile->xmatch_len = tmp;
++
++ /* per profile debug flags (complain, audit) */
++ if (!aa_is_nameX(e, AA_STRUCT, "flags"))
++ goto fail;
++ if (!aa_is_u32(e, &tmp, NULL))
++ goto fail;
++ if (tmp)
++ profile->flags |= PFLAG_HAT;
++ if (!aa_is_u32(e, &tmp, NULL))
++ goto fail;
++ if (tmp)
++ profile->mode = APPARMOR_COMPLAIN;
++ if (!aa_is_u32(e, &tmp, NULL))
++ goto fail;
++ if (tmp)
++ profile->audit = AUDIT_ALL;
++
++ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
++ goto fail;
++
++ if (!aa_is_u32(e, &(profile->caps.allowed.cap[0]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.audit.cap[0]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.quiet.cap[0]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.set.cap[0]), NULL))
++ goto fail;
++
++ if (aa_is_nameX(e, AA_STRUCT, "caps64")) {
++ /* optional upper half of 64 bit caps */
++ if (!aa_is_u32(e, &(profile->caps.allowed.cap[1]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.audit.cap[1]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.quiet.cap[1]), NULL))
++ goto fail;
++ if (!aa_is_u32(e, &(profile->caps.set.cap[1]), NULL))
++ goto fail;
++ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
++ goto fail;
++ }
++
++ if (!aa_unpack_rlimits(e, profile))
++ goto fail;
++
++ size = aa_is_array(e, "net_allowed_af");
++ if (size) {
++ if (size > AF_MAX)
++ goto fail;
++
++ for (i = 0; i < size; i++) {
++ if (!aa_is_u16(e, &profile->net.allowed[i], NULL))
++ goto fail;
++ if (!aa_is_u16(e, &profile->net.audit[i], NULL))
++ goto fail;
++ if (!aa_is_u16(e, &profile->net.quiet[i], NULL))
++ goto fail;
++ }
++ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
++ goto fail;
++ /* allow unix domain and netlink sockets they are handled
++ * by IPC
++ */
++ }
++ profile->net.allowed[AF_UNIX] = 0xffff;
++ profile->net.allowed[AF_NETLINK] = 0xffff;
++
++ /* get file rules */
++ profile->file.dfa = aa_unpack_dfa(e);
++ if (IS_ERR(profile->file.dfa)) {
++ error = PTR_ERR(profile->file.dfa);
++ profile->file.dfa = NULL;
++ goto fail;
++ }
++
++ if (!aa_unpack_trans_table(e, profile))
++ goto fail;
++
++ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
++ goto fail;
++
++ return profile;
++
++fail:
++ sa->name = profile && profile->base.name ? profile->base.name :
++ "unknown";
++ if (!sa->base.info)
++ sa->base.info = "failed to unpack profile";
++ aa_audit_iface(sa);
++
++ free_aa_profile(profile);
++
++ return ERR_PTR(error);
++}
++
++/**
++ * aa_verify_head - unpack serialized stream header
++ * @e: serialized data read head
++ * @operation: operation header is being verified for
++ *
++ * returns error or 0 if header is good
++ */
++static int aa_verify_header(struct aa_ext *e, struct aa_audit_iface *sa)
++{
++ /* get the interface version */
++ if (!aa_is_u32(e, &e->version, "version")) {
++ sa->base.info = "invalid profile format";
++ aa_audit_iface(sa);
++ return -EPROTONOSUPPORT;
++ }
++
++ /* check that the interface version is currently supported */
++ if (e->version != 5) {
++ sa->base.info = "unsupported interface version";
++ aa_audit_iface(sa);
++ return -EPROTONOSUPPORT;
++ }
++
++ /* read the namespace if present */
++ if (!aa_is_string(e, &e->ns_name, "namespace"))
++ e->ns_name = NULL;
++
++ return 0;
++}
++
++
++
++/**
++ * aa_interface_add_profiles - Unpack and add new profile(s) to the profile list
++ * @data: serialized data stream
++ * @size: size of the serialized data stream
++ */
++ssize_t aa_interface_add_profiles(void *data, size_t size)
++{
++ struct aa_profile *profile;
++ struct aa_namespace *ns = NULL;
++ struct aa_policy_common *common;
++ struct aa_ext e = {
++ .start = data,
++ .end = data + size,
++ .pos = data,
++ .ns_name = NULL
++ };
++ ssize_t error;
++ struct aa_audit_iface sa;
++ aa_audit_init(&sa, "profile_load", &e);
++
++ error = aa_verify_header(&e, &sa);
++ if (error)
++ return error;
++
++ profile = aa_unpack_profile(&e, &sa);
++ if (IS_ERR(profile))
++ return PTR_ERR(profile);
++
++ sa.name2 = e.ns_name;
++ ns = aa_prepare_namespace(e.ns_name);
++ if (IS_ERR(ns)) {
++ sa.base.info = "failed to prepare namespace";
++ sa.base.error = PTR_ERR(ns);
++ goto fail;
++ }
++ /* profiles are currently loaded flat with fqnames */
++ sa.name = profile->fqname;
++
++ write_lock(&ns->base.lock);
++
++ common = __aa_find_parent_by_fqname(ns, sa.name);
++ if (!common) {
++ sa.base.info = "parent does not exist";
++ sa.base.error = -ENOENT;
++ goto fail2;
++ }
++
++ if (common != &ns->base)
++ profile->parent = aa_get_profile((struct aa_profile *) common);
++
++ if (__aa_find_profile(&common->profiles, profile->base.name)) {
++ /* A profile with this name exists already. */
++ sa.base.info = "profile already exists";
++ goto fail2;
++ }
++ profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
++ profile->ns = aa_get_namespace(ns);
++
++ __aa_add_profile(common, profile);
++ write_unlock(&ns->base.lock);
++
++ aa_audit_iface(&sa);
++ aa_put_namespace(ns);
++ kfree(e.ns_name);
++ return size;
++
++fail2:
++ write_unlock(&ns->base.lock);
++ sa.base.error = -EEXIST;
++
++fail:
++ error = aa_audit_iface(&sa);
++ aa_put_namespace(ns);
++ aa_put_profile(profile);
++ kfree(e.ns_name);
++ return error;
++}
++
++/**
++ * aa_interface_replace_profiles - replace profile(s) on the profile list
++ * @udata: serialized data stream
++ * @size: size of the serialized data stream
++ *
++ * unpack and replace a profile on the profile list and uses of that profile
++ * by any aa_task_context. If the profile does not exist on the profile list
++ * it is added. Return %0 or error.
++ */
++ssize_t aa_interface_replace_profiles(void *udata, size_t size)
++{
++ struct aa_policy_common *common;
++ struct aa_profile *old_profile = NULL, *new_profile;
++ struct aa_namespace *ns;
++ struct aa_ext e = {
++ .start = udata,
++ .end = udata + size,
++ .pos = udata,
++ .ns_name = NULL
++ };
++ ssize_t error;
++ struct aa_audit_iface sa;
++ aa_audit_init(&sa, "profile_replace", &e);
++
++ if (g_apparmor_lock_policy)
++ return -EACCES;
++
++ error = aa_verify_header(&e, &sa);
++ if (error)
++ return error;
++
++ new_profile = aa_unpack_profile(&e, &sa);
++ if (IS_ERR(new_profile))
++ return PTR_ERR(new_profile);
++
++ sa.name2 = e.ns_name;
++ ns = aa_prepare_namespace(e.ns_name);
++ if (!ns) {
++ sa.base.info = "failed to prepare namespace";
++ sa.base.error = -ENOMEM;
++ goto fail;
++ }
++
++ sa.name = new_profile->fqname;
++
++ write_lock(&ns->base.lock);
++ common = __aa_find_parent_by_fqname(ns, sa.name);
++
++ if (!common) {
++ sa.base.info = "parent does not exist";
++ sa.base.error = -ENOENT;
++ goto fail2;
++ }
++
++ if (common != &ns->base)
++ new_profile->parent = aa_get_profile((struct aa_profile *)
++ common);
++
++ old_profile = __aa_find_profile(&common->profiles,
++ new_profile->base.name);
++ aa_get_profile(old_profile);
++ if (old_profile && old_profile->flags & PFLAG_IMMUTABLE) {
++ sa.base.info = "cannot replace immutible profile";
++ sa.base.error = -EPERM;
++ goto fail2;
++ } else if (old_profile) {
++ // __aa_profile_list_release(&old_profile->base.profiles);
++ /* TODO: remove for new interface
++ * move children profiles over to the new profile so
++ * that replacement behaves correctly
++ */
++ // list_replace_init(&old_profile->base.profiles,
++ // &new_profile->base.profiles);
++ struct aa_profile *profile, *tmp;
++ list_for_each_entry_safe(profile, tmp, &old_profile->base.profiles,
++ base.list) {
++ aa_put_profile(profile->parent);
++ list_del(&profile->base.list);
++ profile->parent = aa_get_profile(new_profile);
++ list_add(&profile->base.list,
++ &new_profile->base.profiles);
++ }
++ __aa_replace_profile(old_profile, new_profile);
++ new_profile->sid = old_profile->sid;
++ } else {
++ __aa_add_profile(common, new_profile);
++ new_profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
++ }
++
++ new_profile->ns = aa_get_namespace(ns);
++
++ write_unlock(&ns->base.lock);
++
++ if (!old_profile)
++ sa.base.operation = "profile_load";
++
++ aa_audit_iface(&sa);
++ aa_put_namespace(ns);
++ aa_put_profile(old_profile);
++ kfree(e.ns_name);
++ return size;
++
++fail2:
++ write_unlock(&ns->base.lock);
++fail:
++ error = aa_audit_iface(&sa);
++ aa_put_namespace(ns);
++ aa_put_profile(old_profile);
++ aa_put_profile(new_profile);
++ kfree(e.ns_name);
++ return error;
++}
++
++/**
++ * aa_interface_remove_profiles - remove profile(s) from the system
++ * @name: name of the profile to remove
++ * @size: size of the name
++ *
++ * remove a profile from the profile list and all aa_task_context references
++ * to said profile.
++ * NOTE: removing confinement does not restore rlimits to preconfinemnet values
++ */
++ssize_t aa_interface_remove_profiles(char *name, size_t size)
++{
++ struct aa_namespace *ns;
++ struct aa_profile *profile;
++ struct aa_audit_iface sa;
++ aa_audit_init(&sa, "profile_remove", NULL);
++
++ if (g_apparmor_lock_policy)
++ return -EACCES;
++
++ write_lock(&ns_list_lock);
++ if (name[0] == ':') {
++ char *ns_name;
++ name = aa_split_name_from_ns(name, &ns_name);
++ ns = __aa_find_namespace(&ns_list, ns_name);
++ } else {
++ ns = aa_get_namespace(default_namespace);
++ }
++
++ if (!ns) {
++ sa.base.info = "failed: namespace does not exist";
++ goto fail_ns_list_lock;
++ }
++
++ sa.name2 = ns->base.name;
++ write_lock(&ns->base.lock);
++ if (!name) {
++ /* remove namespace */
++ // __aa_remove_namespace(ns);
++ } else {
++ /* remove profile */
++ profile = __aa_find_profile_by_fqname(ns, name);
++ if (!profile) {
++ sa.name = name;
++ sa.base.info = "failed: profile does not exist";
++ goto fail_ns_lock;
++ }
++ sa.name = profile->fqname;
++ __aa_profile_list_release(&profile->base.profiles);
++ __aa_remove_profile(profile, profile->ns->unconfined);
++ }
++ write_unlock(&ns->base.lock);
++ write_unlock(&ns_list_lock);
++
++ aa_audit_iface(&sa);
++ aa_put_namespace(ns);
++ return size;
++
++fail_ns_lock:
++ write_unlock(&ns->base.lock);
++
++fail_ns_list_lock:
++ write_unlock(&ns_list_lock);
++ aa_audit_iface(&sa);
++ return 0; //-ENOENT;
++}
+--- /dev/null
++++ b/security/apparmor/procattr.c
+@@ -0,0 +1,117 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor /proc/<pid>/attr/ interface functions
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include "include/apparmor.h"
++#include "include/policy.h"
++#include "include/domain.h"
++
++/* FIXME show profile multiplexing */
++int aa_getprocattr(struct aa_namespace *ns, struct aa_profile *profile,
++ char **string)
++{
++ char *str;
++ int len = 0;
++
++ if (profile) {
++ int mode_len, name_len, ns_len = 0;
++ const char *mode_str = profile_mode_names[profile->mode];
++ char *s;
++
++ mode_len = strlen(mode_str) + 3; /* _(mode_str)\n */
++ name_len = strlen(profile->fqname);
++ if (ns != default_namespace)
++ ns_len = strlen(ns->base.name) + 3;
++ len = mode_len + ns_len + name_len + 1;
++ s = str = kmalloc(len + 1, GFP_ATOMIC);
++ if (!str)
++ return -ENOMEM;
++
++ if (ns_len) {
++ sprintf(s, "%s://", ns->base.name);
++ s += ns_len;
++ }
++ memcpy(s, profile->fqname, name_len);
++ s += name_len;
++ sprintf(s, " (%s)\n", mode_str);
++ } else {
++ const char *unconfined_str = "unconfined\n";
++
++ len = strlen(unconfined_str);
++ if (ns != default_namespace)
++ len += strlen(ns->base.name) + 1;
++
++ str = kmalloc(len + 1, GFP_ATOMIC);
++ if (!str)
++ return -ENOMEM;
++
++ if (ns != default_namespace)
++ sprintf(str, "%s://%s", ns->base.name, unconfined_str);
++ else
++ memcpy(str, unconfined_str, len);
++ }
++ *string = str;
++
++ return len;
++}
++
++static char *split_token_from_name(const char *op, char *args, u64 *token)
++{
++ char *name;
++
++ *token = simple_strtoull(args, &name, 16);
++ if ((name == args) || *name != '^') {
++ AA_ERROR("%s: Invalid input '%s'", op, args);
++ return ERR_PTR(-EINVAL);
++ }
++
++ name++; /* skip ^ */
++ if (!*name)
++ name = NULL;
++ return name;
++}
++
++int aa_setprocattr_changehat(char *args, int test)
++{
++ char *hat;
++ u64 token;
++
++ hat = split_token_from_name("change_hat", args, &token);
++ if (IS_ERR(hat))
++ return PTR_ERR(hat);
++
++ if (!hat && !token) {
++ AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
++ return -EINVAL;
++ }
++
++ AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
++ __func__, token, hat ? hat : NULL);
++
++ return aa_change_hat(hat, token, test);
++}
++
++int aa_setprocattr_changeprofile(char *args, int onexec, int test)
++{
++ char *name, *ns_name;
++
++ name = aa_split_name_from_ns(args, &ns_name);
++ return aa_change_profile(ns_name, name, onexec, test);
++}
++
++
++int aa_setprocattr_permipc(char *args)
++{
++ /* TODO: add ipc permission querying */
++ return -ENOTSUPP;
++}
+--- /dev/null
++++ b/security/apparmor/resource.c
+@@ -0,0 +1,104 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor resource mediation and attachment
++ *
++ * Copyright (C) 1998-2008 Novell/SUSE
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ */
++
++#include <linux/audit.h>
++
++#include "include/audit.h"
++#include "include/resource.h"
++#include "include/policy.h"
++
++struct aa_audit_resource {
++ struct aa_audit base;
++
++ int rlimit;
++};
++
++static void audit_cb(struct audit_buffer *ab, void *va)
++{
++ struct aa_audit_resource *sa = va;
++
++ if (sa->rlimit)
++ audit_log_format(ab, " rlimit=%d", sa->rlimit - 1);
++}
++
++static int aa_audit_resource(struct aa_profile *profile,
++ struct aa_audit_resource *sa)
++{
++ return aa_audit(AUDIT_APPARMOR_AUTO, profile, (struct aa_audit *)sa,
++ audit_cb);
++}
++
++/**
++ * aa_task_setrlimit - test permission to set an rlimit
++ * @profile - profile confining the task
++ * @resource - the resource being set
++ * @new_rlim - the new resource limit
++ *
++ * Control raising the processes hard limit.
++ */
++int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
++ struct rlimit *new_rlim)
++{
++ struct aa_audit_resource sa;
++ int error = 0;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.base.operation = "setrlimit";
++ sa.base.gfp_mask = GFP_KERNEL;
++ sa.rlimit = resource + 1;
++
++ if (profile->rlimits.mask & (1 << resource) &&
++ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
++ sa.base.error = -EACCES;
++
++ error = aa_audit_resource(profile, &sa);
++ }
++
++ return error;
++}
++
++void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new)
++{
++ unsigned int mask = 0;
++ struct rlimit *rlim, *initrlim;
++ int i;
++
++ /* for any rlimits the profile controlled reset the soft limit
++ * to the less of the tasks hard limit and the init tasks soft limit
++ */
++ if (old && old->rlimits.mask) {
++ for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<=1) {
++ if (old->rlimits.mask & mask) {
++ rlim = current->signal->rlim + i;
++ initrlim = init_task.signal->rlim + i;
++ rlim->rlim_cur = min(rlim->rlim_max,
++ initrlim->rlim_cur);
++ }
++ }
++ }
++
++ /* set any new hard limits as dictated by the new profile */
++ if (!(new && new->rlimits.mask))
++ return;
++ for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<=1) {
++ if (!(new->rlimits.mask & mask))
++ continue;
++
++ rlim = current->signal->rlim + i;
++ rlim->rlim_max = min(rlim->rlim_max,
++ new->rlimits.limits[i].rlim_max);
++ /* soft limit should not exceed hard limit */
++ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ }
++}
+--- /dev/null
++++ b/security/apparmor/sid.c
+@@ -0,0 +1,111 @@
++/*
++ * AppArmor security module
++ *
++ * This file contains AppArmor security identifier (sid) manipulation fns
++ *
++ * Copyright 2009 Canonical Ltd.
++ *
++ * This program 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, version 2 of the
++ * License.
++ *
++ *
++ * AppArmor allocates a unique sid for every profile loaded. If a profile
++ * is replaced it receive the sid of the profile it is replacing. Each sid
++ * is a u32 with the lower u16 being sids of system profiles and the
++ * upper u16 being user profile sids.
++ *
++ * The sid value of 0 is invalid for system sids and is used to indicate
++ * unconfined for user sids.
++ *
++ * A compound sid is a pair of user and system sids that is used to identify
++ * both profiles confining a task.
++ *
++ * Both system and user sids are globally unique with all users pulling
++ * from the same sid pool. User sid allocation is limited by the
++ * user controls, that can limit how many profiles are loaded by a user.
++ */
++
++#include <linux/spinlock.h>
++
++#include "include/sid.h"
++
++/* global counter from which sids are allocated */
++static u16 global_sys_sid;
++static u16 global_usr_sid;
++static DEFINE_SPINLOCK(sid_lock);
++
++
++/* TODO FIXME: add sid to profile mapping, and sid recycling */
++
++
++/**
++ * aa_alloc_sid - allocate a new sid for a profile
++ * @is_usr: true if the new sid is a user based sid
++ */
++u32 aa_alloc_sid(int is_usr)
++{
++ u32 sid;
++
++ /*
++ * TODO FIXME: sid recycling - part of profile mapping table
++ */
++ spin_lock(&sid_lock);
++ if (is_usr) {
++ sid = (++global_usr_sid) << 16;
++
++ } else {
++ sid = ++global_sys_sid;
++ }
++ spin_unlock(&sid_lock);
++ return sid;
++}
++
++/**
++ * aa_free_sid - free a sid
++ * @sid: sid to free
++ */
++void aa_free_sid(u32 sid)
++{
++ ; /* NOP ATM */
++}
++
++/**
++ * aa_add_sid_profile - associate a profile to a sid for sid -> profile lookup
++ * @sid: sid of te profile
++ * @profile: profile to associate
++ *
++ * return 0 or error
++ */
++int aa_add_sid_profile(u32 sid, struct aa_profile *profile)
++{
++ /* NOP ATM */
++ return 0;
++}
++
++/**
++ * aa_replace_sid_profile - replace the profile associated with a sid
++ * @sid: sid to associate a new profile with
++ * @profile: profile to associate with side
++ *
++ * return 0 or error
++ */
++int aa_replace_sid_profile(u32 sid, struct aa_profile *profile)
++{
++ /* NOP ATM */
++ return 0;
++}
++
++/**
++ * aa_get_sid_profile - get the profile associated with the sid
++ * @sid: sid to lookup
++ *
++ * returns - the profile, or NULL for unconfined user.
++ * - if there is an error -ENOENT, -EINVAL
++ */
++struct aa_profile *aa_get_sid_profile(u32 sid)
++{
++ return ERR_PTR(-EINVAL);
++}
++
diff --git a/patches.apparmor/apparmor-turn-auditing-of-ptrace-on b/patches.apparmor/apparmor-turn-auditing-of-ptrace-on
new file mode 100644
index 0000000000..5a95472805
--- /dev/null
+++ b/patches.apparmor/apparmor-turn-auditing-of-ptrace-on
@@ -0,0 +1,29 @@
+From john.johansen@canonical.com Tue Nov 17 11:13:50 2009
+From: John Johansen <john.johansen@canonical.com>
+Date: Fri, 10 Jul 2009 09:32:23 +0000 (-0700)
+Subject: AppArmor: Turn auditing of ptrace on
+Git-commit: 6866f5f0b4ac80ec6a5f48b24568f0f9591d1832
+Git-Repo: git://kernel.ubuntu.com/jj/apparmor-mainline.git AppArmor-2.4
+
+AppArmor: Turn auditing of ptrace on
+
+Auditing of ptrace mediation was disabled, turn it on.
+
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ security/apparmor/ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/apparmor/ipc.c
++++ b/security/apparmor/ipc.c
+@@ -94,7 +94,7 @@ int aa_ptrace(struct task_struct *tracer
+
+ sa.base.error = aa_may_ptrace(tracer, tracer_p,
+ tracee_p, mode);
+- //sa.base.error = aa_audit_ptrace(tracer_p, &sa);
++ sa.base.error = aa_audit_ptrace(tracer_p, &sa);
+
+ put_cred(lcred);
+ }
diff --git a/patches.arch/s390-03-qeth-hs-traffic-analyzer.patch b/patches.arch/s390-03-qeth-hs-traffic-analyzer.patch
new file mode 100644
index 0000000000..9fbe6e738c
--- /dev/null
+++ b/patches.arch/s390-03-qeth-hs-traffic-analyzer.patch
@@ -0,0 +1,802 @@
+From: Ursula Braun-Krahl <braunu@de.ibm.com>
+Subject: qeth: HiperSockets Network Traffic Analyzer
+References: bnc#560674
+
+Description: New feature to trace HiperSockets network traffic
+ for debugging purposes.
+
+Acked-by: John Jolly <jjolly@suse.de>
+---
+
+ drivers/s390/net/qeth_core.h | 5 -
+ drivers/s390/net/qeth_core_main.c | 130 ++++++++++++++++------------
+ drivers/s390/net/qeth_core_mpc.h | 44 +++++++++
+ drivers/s390/net/qeth_core_sys.c | 8 +
+ drivers/s390/net/qeth_l2_main.c | 3
+ drivers/s390/net/qeth_l3.h | 2
+ drivers/s390/net/qeth_l3_main.c | 174 ++++++++++++++++++++++++++++++++------
+ drivers/s390/net/qeth_l3_sys.c | 56 ++++++++++++
+ 8 files changed, 336 insertions(+), 86 deletions(-)
+
+Index: linux-sles11sp1/drivers/s390/net/qeth_core.h
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_core.h
++++ linux-sles11sp1/drivers/s390/net/qeth_core.h
+@@ -649,6 +649,7 @@ struct qeth_card_options {
+ int performance_stats;
+ int rx_sg_cb;
+ enum qeth_ipa_isolation_modes isolation;
++ int sniffer;
+ };
+
+ /*
+@@ -737,6 +738,7 @@ struct qeth_card {
+ struct qeth_discipline discipline;
+ atomic_t force_alloc_skb;
+ struct service_level qeth_service_level;
++ struct qdio_ssqd_desc ssqd;
+ };
+
+ struct qeth_card_list_struct {
+@@ -812,7 +814,8 @@ int qeth_send_ipa_cmd(struct qeth_card *
+ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
+ enum qeth_ipa_cmds, enum qeth_prot_versions);
+ int qeth_query_setadapterparms(struct qeth_card *);
+-int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *);
++int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
++ unsigned int, const char *);
+ void qeth_queue_input_buffer(struct qeth_card *, int);
+ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
+ struct qdio_buffer *, struct qdio_buffer_element **, int *,
+Index: linux-sles11sp1/drivers/s390/net/qeth_core_main.c
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_core_main.c
++++ linux-sles11sp1/drivers/s390/net/qeth_core_main.c
+@@ -269,6 +269,7 @@ int qeth_realloc_buffer_pool(struct qeth
+ card->qdio.init_pool.buf_count = bufcnt;
+ return qeth_alloc_buffer_pool(card);
+ }
++EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
+
+ int qeth_set_large_send(struct qeth_card *card,
+ enum qeth_large_send_types type)
+@@ -385,8 +386,10 @@ static struct qeth_ipa_cmd *qeth_check_i
+ if (IS_IPA(iob->data)) {
+ cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
+ if (IS_IPA_REPLY(cmd)) {
+- if (cmd->hdr.command < IPA_CMD_SETCCID ||
+- cmd->hdr.command > IPA_CMD_MODCCID)
++ if (cmd->hdr.command != IPA_CMD_SETCCID &&
++ cmd->hdr.command != IPA_CMD_DELCCID &&
++ cmd->hdr.command != IPA_CMD_MODCCID &&
++ cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
+ qeth_issue_ipa_msg(cmd,
+ cmd->hdr.return_code, card);
+ return cmd;
+@@ -1135,11 +1138,6 @@ static int qeth_setup_card(struct qeth_c
+ card->thread_running_mask = 0;
+ INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
+ INIT_LIST_HEAD(&card->ip_list);
+- card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
+- if (!card->ip_tbd_list) {
+- QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
+- return -ENOMEM;
+- }
+ INIT_LIST_HEAD(card->ip_tbd_list);
+ INIT_LIST_HEAD(&card->cmd_waiter_list);
+ init_waitqueue_head(&card->wait_q);
+@@ -1173,21 +1171,30 @@ static struct qeth_card *qeth_alloc_card
+ QETH_DBF_TEXT(SETUP, 2, "alloccrd");
+ card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
+ if (!card)
+- return NULL;
++ goto out;
+ QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
+- if (qeth_setup_channel(&card->read)) {
+- kfree(card);
+- return NULL;
+- }
+- if (qeth_setup_channel(&card->write)) {
+- qeth_clean_channel(&card->read);
+- kfree(card);
+- return NULL;
++ card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
++ if (!card->ip_tbd_list) {
++ QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
++ goto out_card;
+ }
++ if (qeth_setup_channel(&card->read))
++ goto out_ip;
++ if (qeth_setup_channel(&card->write))
++ goto out_channel;
+ card->options.layer2 = -1;
+ card->qeth_service_level.seq_print = qeth_core_sl_print;
+ register_service_level(&card->qeth_service_level);
+ return card;
++
++out_channel:
++ qeth_clean_channel(&card->read);
++out_ip:
++ kfree(card->ip_tbd_list);
++out_card:
++ kfree(card);
++out:
++ return NULL;
+ }
+
+ static int qeth_determine_card_type(struct qeth_card *card)
+@@ -2608,8 +2615,8 @@ int qeth_query_setadapterparms(struct qe
+ }
+ EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
+
+-int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
+- const char *dbftext)
++int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
++ unsigned int qdio_error, const char *dbftext)
+ {
+ if (qdio_error) {
+ QETH_DBF_TEXT(TRACE, 2, dbftext);
+@@ -2619,7 +2626,11 @@ int qeth_check_qdio_errors(struct qdio_b
+ QETH_DBF_TEXT_(QERR, 2, " F14=%02X",
+ buf->element[14].flags & 0xff);
+ QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error);
+- return 1;
++ if ((buf->element[15].flags & 0xff) == 0x12) {
++ card->stats.rx_dropped++;
++ return 0;
++ } else
++ return 1;
+ }
+ return 0;
+ }
+@@ -2702,7 +2713,7 @@ static int qeth_handle_send_error(struct
+ qdio_err = 1;
+ }
+ }
+- qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
++ qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
+
+ if (!qdio_err)
+ return QETH_SEND_ERROR_NONE;
+@@ -3544,6 +3555,7 @@ void qeth_tx_timeout(struct net_device *
+ {
+ struct qeth_card *card;
+
++ QETH_DBF_TEXT(TRACE, 4, "txtimeo");
+ card = dev->ml_priv;
+ card->stats.tx_errors++;
+ qeth_schedule_recovery(card);
+@@ -3882,9 +3894,7 @@ static int qeth_core_driver_group(const
+
+ int qeth_core_hardsetup_card(struct qeth_card *card)
+ {
+- struct qdio_ssqd_desc *ssqd;
+ int retries = 3;
+- int mpno = 0;
+ int rc;
+
+ QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
+@@ -3911,31 +3921,6 @@ retry:
+ else
+ goto retry;
+ }
+-
+- rc = qeth_get_unitaddr(card);
+- if (rc) {
+- QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
+- return rc;
+- }
+-
+- ssqd = kmalloc(sizeof(struct qdio_ssqd_desc), GFP_KERNEL);
+- if (!ssqd) {
+- rc = -ENOMEM;
+- goto out;
+- }
+- rc = qdio_get_ssqd_desc(CARD_DDEV(card), ssqd);
+- if (rc == 0)
+- mpno = ssqd->pcnt;
+- kfree(ssqd);
+-
+- if (mpno)
+- mpno = min(mpno - 1, QETH_MAX_PORTNO);
+- if (card->info.portno > mpno) {
+- QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d"
+- "\n.", CARD_BUS_ID(card), card->info.portno);
+- rc = -ENODEV;
+- goto out;
+- }
+ qeth_init_tokens(card);
+ qeth_init_func_level(card);
+ rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
+@@ -4019,7 +4004,7 @@ struct sk_buff *qeth_core_get_next_skb(s
+ struct qdio_buffer_element *element = *__element;
+ int offset = *__offset;
+ struct sk_buff *skb = NULL;
+- int skb_len;
++ int skb_len = 0;
+ void *data_ptr;
+ int data_len;
+ int headroom = 0;
+@@ -4038,20 +4023,24 @@ struct sk_buff *qeth_core_get_next_skb(s
+ *hdr = element->addr + offset;
+
+ offset += sizeof(struct qeth_hdr);
+- if (card->options.layer2) {
+- if (card->info.type == QETH_CARD_TYPE_OSN) {
+- skb_len = (*hdr)->hdr.osn.pdu_length;
+- headroom = sizeof(struct qeth_hdr);
+- } else {
+- skb_len = (*hdr)->hdr.l2.pkt_length;
+- }
+- } else {
++ switch ((*hdr)->hdr.l2.id) {
++ case QETH_HEADER_TYPE_LAYER2:
++ skb_len = (*hdr)->hdr.l2.pkt_length;
++ break;
++ case QETH_HEADER_TYPE_LAYER3:
+ skb_len = (*hdr)->hdr.l3.length;
+ if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
+ (card->info.link_type == QETH_LINK_TYPE_HSTR))
+ headroom = TR_HLEN;
+ else
+ headroom = ETH_HLEN;
++ break;
++ case QETH_HEADER_TYPE_OSN:
++ skb_len = (*hdr)->hdr.osn.pdu_length;
++ headroom = sizeof(struct qeth_hdr);
++ break;
++ default:
++ break;
+ }
+
+ if (!skb_len)
+@@ -4206,6 +4195,33 @@ void qeth_core_free_discipline(struct qe
+ card->discipline.ccwgdriver = NULL;
+ }
+
++static void qeth_determine_capabilities(struct qeth_card *card)
++{
++ int rc;
++
++ QETH_DBF_TEXT(SETUP, 2, "detcapab");
++ rc = ccw_device_set_online(CARD_DDEV(card));
++ if (rc) {
++ QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
++ goto out;
++ }
++
++ rc = qeth_get_unitaddr(card);
++ if (rc) {
++ QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
++ goto out_offline;
++ }
++
++ rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
++ if (rc)
++ QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
++
++out_offline:
++ ccw_device_set_offline(CARD_DDEV(card));
++out:
++ return;
++}
++
+ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
+ {
+ struct qeth_card *card;
+@@ -4271,6 +4287,8 @@ static int qeth_core_probe_device(struct
+ write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
+ list_add_tail(&card->list, &qeth_core_card_list.list);
+ write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
++
++ qeth_determine_capabilities(card);
+ return 0;
+
+ err_card:
+Index: linux-sles11sp1/drivers/s390/net/qeth_core_mpc.h
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_core_mpc.h
++++ linux-sles11sp1/drivers/s390/net/qeth_core_mpc.h
+@@ -156,6 +156,8 @@ enum qeth_ipa_return_codes {
+ IPA_RC_IP_TABLE_FULL = 0x0002,
+ IPA_RC_UNKNOWN_ERROR = 0x0003,
+ IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
++ IPA_RC_TRACE_ALREADY_ACTIVE = 0x0005,
++ IPA_RC_INVALID_FORMAT = 0x0006,
+ IPA_RC_DUP_IPV6_REMOTE = 0x0008,
+ IPA_RC_DUP_IPV6_HOME = 0x0010,
+ IPA_RC_UNREGISTERED_ADDR = 0x0011,
+@@ -196,6 +198,11 @@ enum qeth_ipa_return_codes {
+ IPA_RC_INVALID_IP_VERSION2 = 0xf001,
+ IPA_RC_FFFF = 0xffff
+ };
++/* for DELIP */
++#define IPA_RC_IP_ADDRESS_NOT_DEFINED IPA_RC_PRIMARY_ALREADY_DEFINED
++/* for SET_DIAGNOSTIC_ASSIST */
++#define IPA_RC_INVALID_SUBCMD IPA_RC_IP_TABLE_FULL
++#define IPA_RC_HARDWARE_AUTH_ERROR IPA_RC_UNKNOWN_ERROR
+
+ /* IPA function flags; each flag marks availability of respective function */
+ enum qeth_ipa_funcs {
+@@ -246,6 +253,7 @@ enum qeth_ipa_setadp_cmd {
+ IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
+ IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
+ IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
++ IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
+ IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
+ };
+ enum qeth_ipa_mac_ops {
+@@ -424,6 +432,40 @@ struct qeth_create_destroy_address {
+ __u8 unique_id[8];
+ } __attribute__ ((packed));
+
++/* SET DIAGNOSTIC ASSIST IPA Command: *************************************/
++
++enum qeth_diags_cmds {
++ QETH_DIAGS_CMD_QUERY = 0x0001,
++ QETH_DIAGS_CMD_TRAP = 0x0002,
++ QETH_DIAGS_CMD_TRACE = 0x0004,
++ QETH_DIAGS_CMD_NOLOG = 0x0008,
++ QETH_DIAGS_CMD_DUMP = 0x0010,
++};
++
++enum qeth_diags_trace_types {
++ QETH_DIAGS_TYPE_HIPERSOCKET = 0x02,
++};
++
++enum qeth_diags_trace_cmds {
++ QETH_DIAGS_CMD_TRACE_ENABLE = 0x0001,
++ QETH_DIAGS_CMD_TRACE_DISABLE = 0x0002,
++ QETH_DIAGS_CMD_TRACE_MODIFY = 0x0004,
++ QETH_DIAGS_CMD_TRACE_REPLACE = 0x0008,
++ QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
++};
++
++struct qeth_ipacmd_diagass {
++ __u32 host_tod2;
++ __u32:32;
++ __u16 subcmd_len;
++ __u16:16;
++ __u32 subcmd;
++ __u8 type;
++ __u8 action;
++ __u16 options;
++ __u32:32;
++} __attribute__ ((packed));
++
+ /* Header for each IPA command */
+ struct qeth_ipacmd_hdr {
+ __u8 command;
+@@ -452,6 +494,7 @@ struct qeth_ipa_cmd {
+ struct qeth_create_destroy_address create_destroy_addr;
+ struct qeth_ipacmd_setadpparms setadapterparms;
+ struct qeth_set_routing setrtg;
++ struct qeth_ipacmd_diagass diagass;
+ } data;
+ } __attribute__ ((packed));
+
+@@ -469,7 +512,6 @@ enum qeth_ipa_arp_return_codes {
+ QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
+ };
+
+-
+ extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
+ extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
+
+Index: linux-sles11sp1/drivers/s390/net/qeth_core_sys.c
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_core_sys.c
++++ linux-sles11sp1/drivers/s390/net/qeth_core_sys.c
+@@ -118,7 +118,7 @@ static ssize_t qeth_dev_portno_store(str
+ {
+ struct qeth_card *card = dev_get_drvdata(dev);
+ char *tmp;
+- unsigned int portno;
++ unsigned int portno, limit;
+
+ if (!card)
+ return -EINVAL;
+@@ -128,9 +128,11 @@ static ssize_t qeth_dev_portno_store(str
+ return -EPERM;
+
+ portno = simple_strtoul(buf, &tmp, 16);
+- if (portno > QETH_MAX_PORTNO) {
++ if (portno > QETH_MAX_PORTNO)
++ return -EINVAL;
++ limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
++ if (portno > limit)
+ return -EINVAL;
+- }
+
+ card->info.portno = portno;
+ return count;
+Index: linux-sles11sp1/drivers/s390/net/qeth_l2_main.c
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_l2_main.c
++++ linux-sles11sp1/drivers/s390/net/qeth_l2_main.c
+@@ -781,7 +781,8 @@ static void qeth_l2_qdio_input_handler(s
+ index = i % QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &card->qdio.in_q->bufs[index];
+ if (!(qdio_err &&
+- qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr")))
++ qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
++ "qinerr")))
+ qeth_l2_process_inbound_buffer(card, buffer, index);
+ /* clear buffer and give back to hardware */
+ qeth_put_buffer_pool_entry(card, buffer->pool_entry);
+Index: linux-sles11sp1/drivers/s390/net/qeth_l3.h
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_l3.h
++++ linux-sles11sp1/drivers/s390/net/qeth_l3.h
+@@ -13,6 +13,8 @@
+
+ #include "qeth_core.h"
+
++#define QETH_SNIFF_AVAIL 0x0008
++
+ struct qeth_ipaddr {
+ struct list_head entry;
+ enum qeth_ip_types type;
+Index: linux-sles11sp1/drivers/s390/net/qeth_l3_main.c
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_l3_main.c
++++ linux-sles11sp1/drivers/s390/net/qeth_l3_main.c
+@@ -216,6 +216,8 @@ static int __qeth_l3_insert_ip_todo(stru
+ struct qeth_ipaddr *tmp, *t;
+ int found = 0;
+
++ if (card->options.sniffer)
++ return 0;
+ list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
+ if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
+ (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
+@@ -431,6 +433,8 @@ static void qeth_l3_set_ip_addr_list(str
+ QETH_DBF_TEXT(TRACE, 2, "sdiplist");
+ QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
+
++ if (card->options.sniffer)
++ return;
+ spin_lock_irqsave(&card->ip_lock, flags);
+ tbd_list = card->ip_tbd_list;
+ card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
+@@ -469,7 +473,7 @@ static void qeth_l3_set_ip_addr_list(str
+ spin_unlock_irqrestore(&card->ip_lock, flags);
+ rc = qeth_l3_deregister_addr_entry(card, addr);
+ spin_lock_irqsave(&card->ip_lock, flags);
+- if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED))
++ if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
+ kfree(addr);
+ else
+ list_add_tail(&addr->entry, &card->ip_list);
+@@ -487,6 +491,8 @@ static void qeth_l3_clear_ip_list(struct
+ unsigned long flags;
+
+ QETH_DBF_TEXT(TRACE, 4, "clearip");
++ if (recover && card->options.sniffer)
++ return;
+ spin_lock_irqsave(&card->ip_lock, flags);
+ /* clear todo list */
+ list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
+@@ -1619,6 +1625,76 @@ static int qeth_l3_get_unique_id(struct
+ return rc;
+ }
+
++static int
++qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
++ unsigned long data)
++{
++ struct qeth_ipa_cmd *cmd;
++ __u16 rc;
++
++ QETH_DBF_TEXT(SETUP, 2, "diastrcb");
++
++ cmd = (struct qeth_ipa_cmd *)data;
++ rc = cmd->hdr.return_code;
++ if (rc) {
++ QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
++ if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
++ switch (rc) {
++ case IPA_RC_HARDWARE_AUTH_ERROR:
++ dev_warn(&card->gdev->dev, "The device is not "
++ "authorized to run as a HiperSockets "
++ "network traffic analyzer\n");
++ break;
++ case IPA_RC_TRACE_ALREADY_ACTIVE:
++ dev_warn(&card->gdev->dev, "A HiperSockets "
++ "network traffic analyzer is already "
++ "active in the HiperSockets LAN\n");
++ break;
++ default:
++ break;
++ }
++ }
++ return 0;
++ }
++
++ switch (cmd->data.diagass.action) {
++ case QETH_DIAGS_CMD_TRACE_QUERY:
++ break;
++ case QETH_DIAGS_CMD_TRACE_DISABLE:
++ card->info.promisc_mode = SET_PROMISC_MODE_OFF;
++ dev_info(&card->gdev->dev, "The HiperSockets network traffic "
++ "analyzer is deactivated\n");
++ break;
++ case QETH_DIAGS_CMD_TRACE_ENABLE:
++ card->info.promisc_mode = SET_PROMISC_MODE_ON;
++ dev_info(&card->gdev->dev, "The HiperSockets network traffic "
++ "analyzer is activated\n");
++ break;
++ default:
++ QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
++ cmd->data.diagass.action, QETH_CARD_IFNAME(card));
++ }
++
++ return 0;
++}
++
++static int
++qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
++{
++ struct qeth_cmd_buffer *iob;
++ struct qeth_ipa_cmd *cmd;
++
++ QETH_DBF_TEXT(SETUP, 2, "diagtrac");
++
++ iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
++ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
++ cmd->data.diagass.subcmd_len = 16;
++ cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
++ cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
++ cmd->data.diagass.action = diags_cmd;
++ return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
++}
++
+ static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
+ struct net_device *dev)
+ {
+@@ -1896,7 +1972,10 @@ static inline __u16 qeth_l3_rebuild_skb(
+ case QETH_CAST_ANYCAST:
+ case QETH_CAST_NOCAST:
+ default:
+- skb->pkt_type = PACKET_HOST;
++ if (card->options.sniffer)
++ skb->pkt_type = PACKET_OTHERHOST;
++ else
++ skb->pkt_type = PACKET_HOST;
+ memcpy(tg_addr, card->dev->dev_addr,
+ card->dev->addr_len);
+ }
+@@ -1952,7 +2031,6 @@ static void qeth_l3_process_inbound_buff
+ int offset;
+ __u16 vlan_tag = 0;
+ unsigned int len;
+-
+ /* get first element of current buffer */
+ element = (struct qdio_buffer_element *)&buf->buffer->element[0];
+ offset = 0;
+@@ -1971,7 +2049,7 @@ static void qeth_l3_process_inbound_buff
+ case QETH_HEADER_TYPE_LAYER3:
+ vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
+ len = skb->len;
+- if (vlan_tag)
++ if (vlan_tag && !card->options.sniffer)
+ if (card->vlangrp)
+ vlan_hwaccel_rx(skb, card->vlangrp,
+ vlan_tag);
+@@ -1982,6 +2060,16 @@ static void qeth_l3_process_inbound_buff
+ else
+ netif_rx(skb);
+ break;
++ case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
++ skb->pkt_type = PACKET_HOST;
++ skb->protocol = eth_type_trans(skb, skb->dev);
++ if (card->options.checksum_type == NO_CHECKSUMMING)
++ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ else
++ skb->ip_summed = CHECKSUM_NONE;
++ len = skb->len;
++ netif_receive_skb(skb);
++ break;
+ default:
+ dev_kfree_skb_any(skb);
+ QETH_DBF_TEXT(TRACE, 3, "inbunkno");
+@@ -2063,6 +2151,9 @@ static int qeth_l3_stop_card(struct qeth
+ QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
+
+ qeth_set_allowed_threads(card, 0, 1);
++ if (card->options.sniffer &&
++ (card->info.promisc_mode == SET_PROMISC_MODE_ON))
++ qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
+ if (card->read.state == CH_STATE_UP &&
+ card->write.state == CH_STATE_UP &&
+ (card->state == CARD_STATE_UP)) {
+@@ -2107,6 +2198,36 @@ static int qeth_l3_stop_card(struct qeth
+ return rc;
+ }
+
++/*
++ * test for and Switch promiscuous mode (on or off)
++ * either for guestlan or HiperSocket Sniffer
++ */
++static void
++qeth_l3_handle_promisc_mode(struct qeth_card *card)
++{
++ struct net_device *dev = card->dev;
++
++ if (((dev->flags & IFF_PROMISC) &&
++ (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
++ (!(dev->flags & IFF_PROMISC) &&
++ (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
++ return;
++
++ if (card->info.guestlan) { /* Guestlan trace */
++ if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
++ qeth_setadp_promisc_mode(card);
++ } else if (card->options.sniffer && /* HiperSockets trace */
++ qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
++ if (dev->flags & IFF_PROMISC) {
++ QETH_DBF_TEXT(TRACE, 3, "+promisc");
++ qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
++ } else {
++ QETH_DBF_TEXT(TRACE, 3, "-promisc");
++ qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
++ }
++ }
++}
++
+ static void qeth_l3_set_multicast_list(struct net_device *dev)
+ {
+ struct qeth_card *card = dev->ml_priv;
+@@ -2115,15 +2236,17 @@ static void qeth_l3_set_multicast_list(s
+ if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
+ (card->state != CARD_STATE_UP))
+ return;
+- qeth_l3_delete_mc_addresses(card);
+- qeth_l3_add_multicast_ipv4(card);
++ if (!card->options.sniffer) {
++ qeth_l3_delete_mc_addresses(card);
++ qeth_l3_add_multicast_ipv4(card);
+ #ifdef CONFIG_QETH_IPV6
+- qeth_l3_add_multicast_ipv6(card);
++ qeth_l3_add_multicast_ipv6(card);
+ #endif
+- qeth_l3_set_ip_addr_list(card);
+- if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
+- return;
+- qeth_setadp_promisc_mode(card);
++ qeth_l3_set_ip_addr_list(card);
++ if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
++ return;
++ }
++ qeth_l3_handle_promisc_mode(card);
+ }
+
+ static const char *qeth_l3_arp_get_error_cause(int *rc)
+@@ -2705,8 +2828,9 @@ static int qeth_l3_hard_start_xmit(struc
+ int nr_frags;
+
+ if ((card->info.type == QETH_CARD_TYPE_IQD) &&
+- (skb->protocol != htons(ETH_P_IPV6)) &&
+- (skb->protocol != htons(ETH_P_IP)))
++ (((skb->protocol != htons(ETH_P_IPV6)) &&
++ (skb->protocol != htons(ETH_P_IP))) ||
++ card->options.sniffer))
+ goto tx_drop;
+
+ if ((card->state != CARD_STATE_UP) || !card->lan_online) {
+@@ -3094,7 +3218,7 @@ static void qeth_l3_qdio_input_handler(s
+ index = i % QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &card->qdio.in_q->bufs[index];
+ if (!(qdio_err &&
+- qeth_check_qdio_errors(buffer->buffer,
++ qeth_check_qdio_errors(card, buffer->buffer,
+ qdio_err, "qinerr")))
+ qeth_l3_process_inbound_buffer(card, buffer, index);
+ /* clear buffer and give back to hardware */
+@@ -3201,20 +3325,22 @@ static int __qeth_l3_set_online(struct c
+ goto out_remove;
+ } else
+ card->lan_online = 1;
+- qeth_set_large_send(card, card->options.large_send);
+
+ rc = qeth_l3_setadapter_parms(card);
+ if (rc)
+ QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
+- rc = qeth_l3_start_ipassists(card);
+- if (rc)
+- QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
+- rc = qeth_l3_setrouting_v4(card);
+- if (rc)
+- QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
+- rc = qeth_l3_setrouting_v6(card);
+- if (rc)
+- QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
++ if (!card->options.sniffer) {
++ rc = qeth_l3_start_ipassists(card);
++ if (rc)
++ QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
++ qeth_set_large_send(card, card->options.large_send);
++ rc = qeth_l3_setrouting_v4(card);
++ if (rc)
++ QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
++ rc = qeth_l3_setrouting_v6(card);
++ if (rc)
++ QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
++ }
+ netif_tx_disable(card->dev);
+
+ rc = qeth_init_qdio_queues(card);
+Index: linux-sles11sp1/drivers/s390/net/qeth_l3_sys.c
+===================================================================
+--- linux-sles11sp1.orig/drivers/s390/net/qeth_l3_sys.c
++++ linux-sles11sp1/drivers/s390/net/qeth_l3_sys.c
+@@ -318,6 +318,61 @@ static ssize_t qeth_l3_dev_checksum_stor
+ static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
+ qeth_l3_dev_checksum_store);
+
++static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct qeth_card *card = dev_get_drvdata(dev);
++
++ if (!card)
++ return -EINVAL;
++
++ return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
++}
++
++static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct qeth_card *card = dev_get_drvdata(dev);
++ int ret;
++ unsigned long i;
++
++ if (!card)
++ return -EINVAL;
++
++ if (card->info.type != QETH_CARD_TYPE_IQD)
++ return -EPERM;
++
++ if ((card->state != CARD_STATE_DOWN) &&
++ (card->state != CARD_STATE_RECOVER))
++ return -EPERM;
++
++ ret = strict_strtoul(buf, 16, &i);
++ if (ret)
++ return -EINVAL;
++ switch (i) {
++ case 0:
++ card->options.sniffer = i;
++ break;
++ case 1:
++ ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
++ if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
++ card->options.sniffer = i;
++ if (card->qdio.init_pool.buf_count !=
++ QETH_IN_BUF_COUNT_MAX)
++ qeth_realloc_buffer_pool(card,
++ QETH_IN_BUF_COUNT_MAX);
++ break;
++ } else
++ return -EPERM;
++ default: /* fall through */
++ return -EINVAL;
++ }
++ return count;
++}
++
++static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
++ qeth_l3_dev_sniffer_store);
++
+ static struct attribute *qeth_l3_device_attrs[] = {
+ &dev_attr_route4.attr,
+ &dev_attr_route6.attr,
+@@ -325,6 +380,7 @@ static struct attribute *qeth_l3_device_
+ &dev_attr_broadcast_mode.attr,
+ &dev_attr_canonical_macaddr.attr,
+ &dev_attr_checksumming.attr,
++ &dev_attr_sniffer.attr,
+ NULL,
+ };
+
diff --git a/patches.arch/s390-message-catalog.diff b/patches.arch/s390-message-catalog.diff
index 1304bf80e0..3cc557547f 100644
--- a/patches.arch/s390-message-catalog.diff
+++ b/patches.arch/s390-message-catalog.diff
@@ -1,8 +1,7 @@
-From: Gonzalo Muelas Serrano <gmuelas@de.ibm.com>
-Subject: [s390] Kernel message catalog.
-References: bnc#549193,LTC#57210,FATE#306999
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: Kernel message catalog.
+References: bnc#549193,FATE#306999,LTC#57210
-Summary: Kernel message catalog.
Description: Add support for automatic message tags to the printk macro
families dev_xyz and pr_xyz. The message tag consists of a
component name and a 24 bit hash of the message text. For
@@ -20,21 +19,20 @@ Description: Add support for automatic message tags to the printk macro
which are built based on the 'Development stream'
Acked-by: John Jolly <jjolly@suse.de>
-
---
Documentation/kmsg/s390/aes_s390 | 30
Documentation/kmsg/s390/af_iucv | 33
Documentation/kmsg/s390/ap | 47
Documentation/kmsg/s390/appldata | 88 +
- Documentation/kmsg/s390/cio | 92 +
- Documentation/kmsg/s390/claw | 731 ++++++++++++++
+ Documentation/kmsg/s390/cio | 145 ++
+ Documentation/kmsg/s390/claw | 731 +++++++++++++
Documentation/kmsg/s390/cpcmd | 17
Documentation/kmsg/s390/cpu | 69 +
Documentation/kmsg/s390/ctcm | 199 +++
- Documentation/kmsg/s390/dasd | 466 +++++++++
- Documentation/kmsg/s390/dasd-diag | 100 +
- Documentation/kmsg/s390/dasd-eckd | 1841 ++++++++++++++++++++++++++++++++++++
+ Documentation/kmsg/s390/dasd | 466 ++++++++
+ Documentation/kmsg/s390/dasd-diag | 118 ++
+ Documentation/kmsg/s390/dasd-eckd | 1901 ++++++++++++++++++++++++++++++++++++
Documentation/kmsg/s390/dasd-fba | 30
Documentation/kmsg/s390/dcssblk | 192 +++
Documentation/kmsg/s390/extmem | 290 +++++
@@ -51,18 +49,18 @@ Acked-by: John Jolly <jjolly@suse.de>
Documentation/kmsg/s390/sclp_config | 3
Documentation/kmsg/s390/sclp_cpi | 2
Documentation/kmsg/s390/sclp_sdias | 4
- Documentation/kmsg/s390/setup | 187 +++
- Documentation/kmsg/s390/tape | 104 ++
- Documentation/kmsg/s390/tape_34xx | 418 ++++++++
+ Documentation/kmsg/s390/setup | 181 +++
+ Documentation/kmsg/s390/tape | 104 +
+ Documentation/kmsg/s390/tape_34xx | 418 +++++++
Documentation/kmsg/s390/tape_3590 | 184 +++
Documentation/kmsg/s390/time | 36
Documentation/kmsg/s390/vmcp | 13
Documentation/kmsg/s390/vmlogrdr | 18
- Documentation/kmsg/s390/vmur | 48
+ Documentation/kmsg/s390/vmur | 47
Documentation/kmsg/s390/vmwatchdog | 26
Documentation/kmsg/s390/xpram | 73 +
Documentation/kmsg/s390/zdump | 12
- Documentation/kmsg/s390/zfcp | 846 ++++++++++++++++
+ Documentation/kmsg/s390/zfcp | 865 ++++++++++++++++
Makefile | 16
arch/s390/Kconfig | 8
include/linux/device.h | 34
@@ -70,10 +68,31 @@ Acked-by: John Jolly <jjolly@suse.de>
kernel/printk.c | 45
scripts/Makefile.build | 14
scripts/kmsg-doc | 479 +++++++++
- 47 files changed, 8174 insertions(+), 15 deletions(-)
+ 47 files changed, 8317 insertions(+), 15 deletions(-)
+Index: linux-sles11sp1/arch/s390/Kconfig
+===================================================================
+--- linux-sles11sp1.orig/arch/s390/Kconfig
++++ linux-sles11sp1/arch/s390/Kconfig
+@@ -577,6 +577,14 @@ bool "s390 guest support for KVM (EXPERI
+ virtio transport. If KVM is detected, the virtio console will be
+ the default console.
+
++config KMSG_IDS
++ bool "Kernel message numbers"
++ default y
++ help
++ Select this option if you want to include a message number to the
++ prefix for kernel messages issued by the s390 architecture and
++ driver code. See "Documentation/s390/kmsg.txt" for more details.
++
+ config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+Index: linux-sles11sp1/Documentation/kmsg/s390/aes_s390
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/aes_s390
++++ linux-sles11sp1/Documentation/kmsg/s390/aes_s390
@@ -0,0 +1,30 @@
+/*?
+ * Text: "Allocating AES fallback algorithm %s failed\n"
@@ -105,8 +124,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * None.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/af_iucv
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/af_iucv
++++ linux-sles11sp1/Documentation/kmsg/s390/af_iucv
@@ -0,0 +1,33 @@
+/*?
+ * Text: "Application %s on z/VM guest %s exceeds message limit\n"
@@ -141,8 +162,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * operating systems of the z/VM hypervisor. If the module has been
+ * compiled into the kernel, ignore this message.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/ap
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/ap
++++ linux-sles11sp1/Documentation/kmsg/s390/ap
@@ -0,0 +1,47 @@
+/*?
+ * Text: "%d is not a valid cryptographic domain\n"
@@ -191,8 +214,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * updates become active, then reload the ap module. If the ap module has been
+ * compiled into the kernel, reboot Linux.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/appldata
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/appldata
++++ linux-sles11sp1/Documentation/kmsg/s390/appldata
@@ -0,0 +1,88 @@
+/*?
+ * Text: "Starting the data collection for %s failed with rc=%d\n"
@@ -282,9 +307,11 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Linux instance to support less than 110 CPUs.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/cio
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/cio
-@@ -0,0 +1,92 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/cio
+@@ -0,0 +1,145 @@
+/*?
+ * Text: "%s is not a valid device for the cio_ignore kernel parameter\n"
+ * Severity: Warning
@@ -377,8 +404,63 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * See the errno man page to find out what caused the problem.
+ */
+ /*? Text: "%s: Got subchannel machine check but no sch_event handler provided.\n" */
++
++/*?
++ * Text: "%s: Setting the device online failed because it is boxed\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: Device bus-ID
++ * Description:
++ * Initialization of a device did not complete because it did not respond in
++ * time or it was reserved by another operating system.
++ * User action:
++ * Make sure that the device is working correctly, then try again to set it
++ * online. For devices that support the reserve/release mechanism (for example
++ * DASDs), you can try to override the reservation of the other system by
++ * writing 'force' to the 'online' sysfs attribute of the affected device.
++ */
++
++/*?
++ * Text: "%s: Setting the device online failed because it is not operational\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: Device bus-ID
++ * Description:
++ * Initialization of a device did not complete because it is not present or
++ * not operational.
++ * User action:
++ * Make sure that the device is present and working correctly, then try again
++ * to set it online.
++ */
++
++/*?
++ * Text: "%s: The device stopped operating while being set offline\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: Device bus-ID
++ * Description:
++ * While the device was set offline, it was not present or not operational.
++ * The device is now inactive, but setting it online again might fail.
++ * User action:
++ * None.
++ */
++
++/*?
++ * Text: "%s: The device entered boxed state while being set offline\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: Device bus-ID
++ * Description:
++ * While the device was set offline, it did not respond in time or it was
++ * reserved by another operating system. The device is now inactive, but
++ * setting it online again might fail.
++ * User action:
++ * None.
++ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/claw
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/claw
++++ linux-sles11sp1/Documentation/kmsg/s390/claw
@@ -0,0 +1,731 @@
+/*?
+ * Text: "%s: Creating the /proc files for a new CLAW device failed\n"
@@ -1111,8 +1193,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "%s: CLAW device %.8s: System validate completed.\n" */
+/*? Text: "%s: %s: Disconnect: Vers=%d,link_id=%d,Corr=%d\n" */
+/*? Text: "%s: %s: Recv Conn Resp: Vers=%d,link_id=%d,Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/cpcmd
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/cpcmd
++++ linux-sles11sp1/Documentation/kmsg/s390/cpcmd
@@ -0,0 +1,17 @@
+/*?
+ * Text: "The cpcmd kernel function failed to allocate a response buffer\n"
@@ -1131,8 +1215,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * machine.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/cpu
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/cpu
++++ linux-sles11sp1/Documentation/kmsg/s390/cpu
@@ -0,0 +1,69 @@
+/*?
+ * Text: "Processor %d started, address %d, identification %06X\n"
@@ -1174,8 +1260,8 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Text: "The CPU configuration topology of the machine is:"
+ * Severity: Informational
+ * Description:
-+ * The first six values of the topology information represent fields Mag1 to
-+ * Mag6 of system-information block (SYSIB) 15.1.2. These fields specify the
++ * The first six values of the topology information represent fields Mag6 to
++ * Mag1 of system-information block (SYSIB) 15.1.2. These fields specify the
+ * maximum numbers of topology-list entries (TLE) at successive topology nesting
+ * levels. The last value represents the MNest value of SYSIB 15.1.2 which
+ * specifies the maximum possible nesting that can be configured through
@@ -1203,8 +1289,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * message to a support organization, be sure to communicate that the dump
+ * does not include all CPU information.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/ctcm
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/ctcm
++++ linux-sles11sp1/Documentation/kmsg/s390/ctcm
@@ -0,0 +1,199 @@
+/*?
+ * Text: "%s: An I/O-error occurred on the CTCM device\n"
@@ -1405,8 +1493,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "%s: Connected with remote side\n" */
+/*? Text: "%s: Restarting device\n" */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/dasd
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/dasd
++++ linux-sles11sp1/Documentation/kmsg/s390/dasd
@@ -0,0 +1,466 @@
+/* dasd_ioctl */
+
@@ -1874,9 +1964,11 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * User action:
+ * Note the reason code and contact your support organization.
+*/
+Index: linux-sles11sp1/Documentation/kmsg/s390/dasd-diag
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/dasd-diag
-@@ -0,0 +1,100 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/dasd-diag
+@@ -0,0 +1,118 @@
+/* dasd_diag */
+
+/*?
@@ -1907,14 +1999,19 @@ Acked-by: John Jolly <jjolly@suse.de>
+ */
+
+/*?
-+ * Text: "%s: New DASD with %ld byte/block, total size %ld KB\n"
++ * Text: "%s: New DASD with %ld byte/block, total size %ld KB%s\n"
+ * Severity: Informational
+ * Parameter:
+ * @1: bus ID of the DASD
+ * @2: bytes per block
+ * @3: size
++ * @4: access mode
+ * Description:
+ * A DASD with the indicated block size and total size has been set online.
++ * If the DASD is configured as read-only to the real or virtual hardware,
++ * the message includes an indication of this hardware access mode. The
++ * hardware access mode is independent from the 'readonly' attribute of
++ * the device in sysfs.
+ * User action:
+ * None.
+ */
@@ -1941,8 +2038,8 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * @2: return code
+ * Description:
+ * Initializing the DASD with the DIAG discipline failed. Possible reasons for
-+ * this problem are that the device is read-only, has a device type other
-+ * than FBA or ECKD, or has a block size other than one of the supported sizes:
++ * this problem are that the device has a device type other than FBA or ECKD,
++ * or has a block size other than one of the supported sizes:
+ * 512 byte, 1024 byte, 2048 byte, or 4096 byte.
+ * User action:
+ * Ensure that the device can be written to and has a supported device type
@@ -1977,9 +2074,24 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * User action:
+ * Remove the unsupported discipline from the parameter string.
+ */
++
++/*?
++ * Text: "%s: The access mode of a DIAG device changed to read-only"
++ * Severity: Warning
++ * Parameter:
++ * @1: bus ID of the DASD
++ * Description:
++ * A device changed its access mode from writeable to
++ * read-only while in use.
++ * User action:
++ * Set the device offline, ensure that the device is configured correctly in
++ * z/VM, then set the device online again.
++ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/dasd-eckd
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/dasd-eckd
-@@ -0,0 +1,1841 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/dasd-eckd
+@@ -0,0 +1,1901 @@
+/* dasd_eckd */
+
+/*?
@@ -3821,8 +3933,70 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * User action:
+ * Look up the SRC in the storage server documentation.
+ */
++
++/*?
++ * Text: "%s: Reading device feature codes failed with rc=%d\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: bus ID of the DASD
++ * @2: return code
++ * Description:
++ * The device feature codes state which advanced features are supported by a
++ * device.
++ * Examples for advanced features are PAV or high performance FICON.
++ * Some early devices do not provide feature codes and no advanced features are
++ * available on these devices.
++ * User action:
++ * None, if the DASD does not provide feature codes. If the DASD provides
++ * feature codes, make sure that it is working correctly, then set it offline
++ * and back online.
++ */
++
++/*?
++ * Text: "%s: A channel path group could not be established\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: bus ID of the DASD
++ * Description:
++ * Initialization of a DASD did not complete because a channel path group
++ * could not be established.
++ * User action:
++ * Make sure that the DASD is working correctly, then try again to set it
++ * online. If initialization still fails, reboot.
++ */
++
++/*?
++ * Text: "%s: The DASD is not operating in multipath mode\n"
++ * Severity: Informational
++ * Parameter:
++ * @1: bus ID of the DASD
++ * Description:
++ * The DASD channel path group could not be configured to use multipath mode.
++ * This might negatively affect I/O performance on this DASD.
++ * User action:
++ * Make sure that the DASD is working correctly, then try again to set it
++ * online. If initialization still fails, reboot.
++ */
++
++/*?
++ * Text: "%s: Detecting the DASD disk layout failed because of an I/O error\n"
++ * Severity: Error
++ * Parameter:
++ * @1: bus ID of the DASD
++ * Description:
++ * The disk layout of the DASD could not be detected because of an unexpected
++ * I/O error. The DASD device driver treats the device like an unformatted DASD,
++ * and partitions on the device are not accessible.
++ * User action:
++ * If the DASD is formatted, make sure that the DASD is working correctly,
++ * then set it offline and back online. If the DASD is unformatted, format the
++ * DASD, for example, with dasdfmt.
++ * ATTENTION: Formatting irreversibly destroys all data on the DASD.
++ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/dasd-fba
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/dasd-fba
++++ linux-sles11sp1/Documentation/kmsg/s390/dasd-fba
@@ -0,0 +1,30 @@
+
+/*?
@@ -3854,8 +4028,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * User action:
+ * Free some memory and try the operation again.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/dcssblk
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/dcssblk
++++ linux-sles11sp1/Documentation/kmsg/s390/dcssblk
@@ -0,0 +1,192 @@
+/*?
+ * Text: "Adjacent DCSSs %s and %s are not contiguous\n"
@@ -4049,8 +4225,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * types SR and ER to read-only by writing 1 to the sysfs 'shared' attribute of
+ * the DCSS. Then try again to suspend the system.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/extmem
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/extmem
++++ linux-sles11sp1/Documentation/kmsg/s390/extmem
@@ -0,0 +1,290 @@
+/*?
+ * Text: "Querying a DCSS type failed with rc=%ld\n"
@@ -4342,8 +4520,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Ensure that the DCSS range is defined below the kernel mapping range.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/hvc_iucv
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/hvc_iucv
++++ linux-sles11sp1/Documentation/kmsg/s390/hvc_iucv
@@ -0,0 +1,122 @@
+/*?
+ * Text: "The z/VM IUCV HVC device driver cannot be used without z/VM\n"
@@ -4467,8 +4647,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Consider adding the z/VM user ID to the "hvc_iucv_allow=" list in the kernel
+ * parameter line and reboot Linux.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/hypfs
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/hypfs
++++ linux-sles11sp1/Documentation/kmsg/s390/hypfs
@@ -0,0 +1,56 @@
+/*?
+ * Text: "The hardware system does not support hypfs\n"
@@ -4526,8 +4708,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ */
+
+/*? Text: "Hypervisor filesystem mounted\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/iucv
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/iucv
++++ linux-sles11sp1/Documentation/kmsg/s390/iucv
@@ -0,0 +1,33 @@
+/*?
+ * Text: "Defining an interrupt buffer on CPU %i failed with 0x%02x (%s)\n"
@@ -4562,8 +4746,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+
+/*? Text: "iucv_external_interrupt: out of memory\n" */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/lcs
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/lcs
++++ linux-sles11sp1/Documentation/kmsg/s390/lcs
@@ -0,0 +1,161 @@
+/*?
+ * Text: "%s: Allocating a socket buffer to interface %s failed\n"
@@ -4726,8 +4912,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "Initialization failed\n" */
+/*? Text: "Terminating lcs module.\n" */
+/*? Text: "Device %s could not be recovered!\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/monreader
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/monreader
++++ linux-sles11sp1/Documentation/kmsg/s390/monreader
@@ -0,0 +1,127 @@
+/*?
+ * Text: "Reading monitor data failed with rc=%i\n"
@@ -4856,8 +5044,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * the *MONITOR DCSS on the z/VM hypervisor. If the default name, MONDCSS, is
+ * used, omit the monreader.mondcss or mondcss parameter.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/monwriter
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/monwriter
++++ linux-sles11sp1/Documentation/kmsg/s390/monwriter
@@ -0,0 +1,16 @@
+/*?
+ * Text: "Writing monitor data failed with rc=%i\n"
@@ -4875,8 +5065,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * For other return codes see the section about DIAGNOSE Code X'DC'
+ * in "z/VM CP Programming Services".
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/netiucv
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/netiucv
++++ linux-sles11sp1/Documentation/kmsg/s390/netiucv
@@ -0,0 +1,139 @@
+/*?
+ * Text: "%s: The peer interface of the IUCV device has closed the connection\n"
@@ -5017,8 +5209,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+
+/*? Text: "driver unloaded\n" */
+/*? Text: "driver initialized\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/qeth
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/qeth
++++ linux-sles11sp1/Documentation/kmsg/s390/qeth
@@ -0,0 +1,606 @@
+/*?
+ * Text: "%s: The LAN is offline\n"
@@ -5626,8 +5820,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "%s: Adapter is dedicated. QDIO data connection isolation not supported\n" */
+/*? Text: "%s: TSO does not permit QDIO data connection isolation\n" */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/s390dbf
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/s390dbf
++++ linux-sles11sp1/Documentation/kmsg/s390/s390dbf
@@ -0,0 +1,83 @@
+/*?
+ * Text: "Root becomes the owner of all s390dbf files in sysfs\n"
@@ -5712,8 +5908,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "%s: switched off\n" */
+/*? Text: "%s: level %i is out of range (%i - %i)\n" */
+/*? Text: "Registering view %s/%s failed due to out of memory\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/sclp_cmd
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/sclp_cmd
++++ linux-sles11sp1/Documentation/kmsg/s390/sclp_cmd
@@ -0,0 +1,16 @@
+/*? Text: "sync request failed (cmd=0x%08x, status=0x%02x)\n" */
+/*? Text: "readcpuinfo failed (response=0x%04x)\n" */
@@ -5731,27 +5929,35 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * The system needs to be restarted and no memory hotplug operation must be
+ * performed in order to allow suspend.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/sclp_config
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/sclp_config
++++ linux-sles11sp1/Documentation/kmsg/s390/sclp_config
@@ -0,0 +1,3 @@
+/*? Text: "cpu capability changed.\n" */
+/*? Text: "no configuration management.\n" */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/sclp_cpi
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/sclp_cpi
++++ linux-sles11sp1/Documentation/kmsg/s390/sclp_cpi
@@ -0,0 +1,2 @@
+/*? Text: "request failed (status=0x%02x)\n" */
+/*? Text: "request failed with response code 0x%x\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/sclp_sdias
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/sclp_sdias
++++ linux-sles11sp1/Documentation/kmsg/s390/sclp_sdias
@@ -0,0 +1,4 @@
+/*? Text: "sclp_send failed for get_nr_blocks\n" */
+/*? Text: "SCLP error: %x\n" */
+/*? Text: "sclp_send failed: %x\n" */
+/*? Text: "Error from SCLP while copying hsa. Event status = %x\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/setup
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/setup
-@@ -0,0 +1,187 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/setup
+@@ -0,0 +1,181 @@
+/*?
+ * Text: "Execute protection active, mvcos available\n"
+ * Severity: Informational
@@ -5896,15 +6102,6 @@ Acked-by: John Jolly <jjolly@suse.de>
+ */
+
+/*?
-+ * Text: "Linux is running under KVM in 64-bit mode\n"
-+ * Severity: Informational
-+ * Description:
-+ * The 64-bit kernel detected that it is running under the KVM hypervisor.
-+ * User action:
-+ * None.
-+ */
-+
-+/*?
+ * Text: "Defining the Linux kernel NSS failed with rc=%d\n"
+ * Severity: Error
+ * Parameter:
@@ -5939,8 +6136,13 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * For other return codes, see the help and message documentation for
+ * the CP SAVESYS command.
+ */
++
++/*? Text: "Linux is running under KVM in 64-bit mode\n" */
++
+Index: linux-sles11sp1/Documentation/kmsg/s390/tape
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/tape
++++ linux-sles11sp1/Documentation/kmsg/s390/tape
@@ -0,0 +1,104 @@
+/*?
+ * Text: "%s: A tape unit was detached while in use\n"
@@ -6046,8 +6248,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Terminate applications performing tape operations
+ * and then try to suspend the system again.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/tape_34xx
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/tape_34xx
++++ linux-sles11sp1/Documentation/kmsg/s390/tape_34xx
@@ -0,0 +1,418 @@
+/*?
+ * Text: "%s: An unexpected condition %d occurred in tape error recovery\n"
@@ -6467,8 +6671,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Either use a different tape unit or use a tape with a supported length.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/tape_3590
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/tape_3590
++++ linux-sles11sp1/Documentation/kmsg/s390/tape_3590
@@ -0,0 +1,184 @@
+/*?
+ * Text: "%s: The tape medium must be loaded into a different tape unit\n"
@@ -6654,8 +6860,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Unload the current cartridge to solve this problem.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/time
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/time
++++ linux-sles11sp1/Documentation/kmsg/s390/time
@@ -0,0 +1,36 @@
+/*?
+ * Text: "The ETR interface has adjusted the clock by %li microseconds\n"
@@ -6693,8 +6901,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * To avoid this warning remove the 'stp=' kernel parameter.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/vmcp
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/vmcp
++++ linux-sles11sp1/Documentation/kmsg/s390/vmcp
@@ -0,0 +1,13 @@
+/*?
+ * Text: "The z/VM CP interface device driver cannot be loaded without z/VM\n"
@@ -6709,8 +6919,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * operating systems of the z/VM hypervisor. If the device driver has been
+ * compiled into the kernel, ignore this message.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/vmlogrdr
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/vmlogrdr
++++ linux-sles11sp1/Documentation/kmsg/s390/vmlogrdr
@@ -0,0 +1,18 @@
+/*? Text: "vmlogrdr: failed to start recording automatically\n" */
+/*? Text: "vmlogrdr: connection severed with reason %i\n" */
@@ -6730,9 +6942,11 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * Close all applications that use any of the vmlogrdr devices
+ * and then try to suspend the system again.
+ */
+Index: linux-sles11sp1/Documentation/kmsg/s390/vmur
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/vmur
-@@ -0,0 +1,48 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/vmur
+@@ -0,0 +1,47 @@
+/*?
+ * Text: "The %s cannot be loaded without z/VM\n"
+ * Severity: Error
@@ -6772,17 +6986,18 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * @1: bus ID of the unit record device
+ * @1: z/VM virtual unit record device driver
+ * Description:
-+ * A request to suspend a unit record device being currently in use is
-+ * rejected.
++ * Linux cannot be suspended while a unit record device is in use.
+ * User action:
-+ * Terminate applications working on z/VM spool files queues (e.g. the
-+ * vmur user space tool) and then try to suspend the system again.
++ * Stop all applications that work on z/VM spool file queues, for example, the
++ * vmur tool. Then try again to suspend Linux.
+ */
+
+/*? Text: "%s loaded.\n" */
+/*? Text: "%s unloaded.\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/vmwatchdog
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/vmwatchdog
++++ linux-sles11sp1/Documentation/kmsg/s390/vmwatchdog
@@ -0,0 +1,26 @@
+/*?
+ * Text: "The system cannot be suspended while the watchdog is in use\n"
@@ -6810,8 +7025,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * uses the watchdog or reconfigure the program to not use the watchdog.
+ */
+
+Index: linux-sles11sp1/Documentation/kmsg/s390/xpram
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/xpram
++++ linux-sles11sp1/Documentation/kmsg/s390/xpram
@@ -0,0 +1,73 @@
+/*?
+ * Text: "%d is not a valid number of XPRAM devices\n"
@@ -6886,8 +7103,10 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: " partitions to be sized automatically: %d\n" */
+/*? Text: " automatically determined partition size: %lu kB\n" */
+/*? Text: " %u pages expanded memory found (%lu KB).\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/zdump
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/zdump
++++ linux-sles11sp1/Documentation/kmsg/s390/zdump
@@ -0,0 +1,12 @@
+/*?
+ * Text: "The 32-bit dump tool cannot be used for a 64-bit system\n"
@@ -6901,9 +7120,11 @@ Acked-by: John Jolly <jjolly@suse.de>
+/*? Text: "DETECTED 'S390 (32 bit) OS'\n" */
+/*? Text: "0x%x is an unknown architecture.\n" */
+/*? Text: "DETECTED 'S390X (64 bit) OS'\n" */
+Index: linux-sles11sp1/Documentation/kmsg/s390/zfcp
+===================================================================
--- /dev/null
-+++ b/Documentation/kmsg/s390/zfcp
-@@ -0,0 +1,846 @@
++++ linux-sles11sp1/Documentation/kmsg/s390/zfcp
+@@ -0,0 +1,865 @@
+/*?
+ * Text: "%s is not a valid SCSI device\n"
+ * Severity: Error
@@ -7750,64 +7971,29 @@ Acked-by: John Jolly <jjolly@suse.de>
+ * adapter. Check your SAN setup and consider reducing the number of ports
+ * visible to the FCP adapter by using more restrictive zoning in the SAN.
+ */
---- a/Makefile
-+++ b/Makefile
-@@ -59,6 +59,20 @@ ifndef KBUILD_CHECKSRC
- KBUILD_CHECKSRC = 0
- endif
-
-+# Call message checker as part of the C compilation
-+#
-+# Use 'make D=1' to enable checking
-+# Use 'make D=2' to create the message catalog
-+
-+ifdef D
-+ ifeq ("$(origin D)", "command line")
-+ KBUILD_KMSG_CHECK = $(D)
-+ endif
-+endif
-+ifndef KBUILD_KMSG_CHECK
-+ KBUILD_KMSG_CHECK = 0
-+endif
-+
- # Use make M=dir to specify directory of external module to build
- # Old syntax make ... SUBDIRS=$PWD is still supported
- # Setting the environment variable KBUILD_EXTMOD take precedence
-@@ -323,6 +337,7 @@ CHECK = sparse
-
- CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
- -Wbitwise -Wno-return-void $(CF)
-+KMSG_CHECK = $(srctree)/scripts/kmsg-doc
- MODFLAGS = -DMODULE
- CFLAGS_MODULE = $(MODFLAGS)
- AFLAGS_MODULE = $(MODFLAGS)
-@@ -366,6 +381,7 @@ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODU
- export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
- export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
- export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
-+export KBUILD_KMSG_CHECK KMSG_CHECK
-
- # When compiling out-of-tree modules, put MODVERDIR in the module
- # tree rather than in the kernel tree. The kernel tree might
---- a/arch/s390/Kconfig
-+++ b/arch/s390/Kconfig
-@@ -577,6 +577,14 @@ bool "s390 guest support for KVM (EXPERI
- virtio transport. If KVM is detected, the virtio console will be
- the default console.
-
-+config KMSG_IDS
-+ bool "Kernel message numbers"
-+ default y
-+ help
-+ Select this option if you want to include a message number to the
-+ prefix for kernel messages issued by the s390 architecture and
-+ driver code. See "Documentation/s390/kmsg.txt" for more details.
+
- config SECCOMP
- bool "Enable seccomp to safely compute untrusted bytecode"
- depends on PROC_FS
---- a/include/linux/device.h
-+++ b/include/linux/device.h
++/*?
++ * Text: "%s: A port opened with WWPN 0x%016Lx returned data that identifies it as WWPN 0x%016Lx\n"
++ * Severity: Warning
++ * Parameter:
++ * @1: bus ID of the zfcp device
++ * @2: expected WWPN
++ * @3: reported WWPN
++ * Description:
++ * A remote port was opened successfully, but it reported an
++ * unexpected WWPN in the returned port login (PLOGI) data. This
++ * condition might have been caused by a change applied to the SAN
++ * configuration while the port was being opened.
++ * User action:
++ * If this condition is only temporary and access to the remote port
++ * is possible, no action is required. If the condition persists,
++ * identify the storage system with the specified WWPN and contact the
++ * support organization of the storage system.
++ */
+Index: linux-sles11sp1/include/linux/device.h
+===================================================================
+--- linux-sles11sp1.orig/include/linux/device.h
++++ linux-sles11sp1/include/linux/device.h
@@ -577,20 +577,40 @@ extern const char *dev_driver_string(con
printk(level "%s %s: " format , dev_driver_string(dev) , \
dev_name(dev) , ## arg)
@@ -7856,9 +8042,11 @@ Acked-by: John Jolly <jjolly@suse.de>
#if defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
---- a/include/linux/kernel.h
-+++ b/include/linux/kernel.h
-@@ -377,22 +377,41 @@ static inline char *pack_hex_byte(char *
+Index: linux-sles11sp1/include/linux/kernel.h
+===================================================================
+--- linux-sles11sp1.orig/include/linux/kernel.h
++++ linux-sles11sp1/include/linux/kernel.h
+@@ -366,22 +366,41 @@ static inline char *pack_hex_byte(char *
#define pr_fmt(fmt) fmt
#endif
@@ -7908,8 +8096,10 @@ Acked-by: John Jolly <jjolly@suse.de>
/* pr_devel() should produce zero code unless DEBUG is defined */
#ifdef DEBUG
---- a/kernel/printk.c
-+++ b/kernel/printk.c
+Index: linux-sles11sp1/kernel/printk.c
+===================================================================
+--- linux-sles11sp1.orig/kernel/printk.c
++++ linux-sles11sp1/kernel/printk.c
@@ -33,6 +33,8 @@
#include <linux/bootmem.h>
#include <linux/syscalls.h>
@@ -7966,44 +8156,51 @@ Acked-by: John Jolly <jjolly@suse.de>
+}
+EXPORT_SYMBOL(printk_dev_hash);
+#endif
---- a/scripts/Makefile.build
-+++ b/scripts/Makefile.build
-@@ -228,12 +228,14 @@ endef
- # Built-in and composite module parts
- $(obj)/%.o: $(src)/%.c FORCE
- $(call cmd,force_checksrc)
-+ $(call cmd,force_check_kmsg)
- $(call if_changed_rule,cc_o_c)
-
- # Single-part modules are special since we need to mark them in $(MODVERDIR)
-
- $(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
- $(call cmd,force_checksrc)
-+ $(call cmd,force_check_kmsg)
- $(call if_changed_rule,cc_o_c)
- @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
-
-@@ -357,6 +359,18 @@ $(multi-used-m) : %.o: $(multi-objs-m) F
-
- targets += $(multi-used-y) $(multi-used-m)
+Index: linux-sles11sp1/Makefile
+===================================================================
+--- linux-sles11sp1.orig/Makefile
++++ linux-sles11sp1/Makefile
+@@ -59,6 +59,20 @@ ifndef KBUILD_CHECKSRC
+ KBUILD_CHECKSRC = 0
+ endif
-+# kmsg check tool
-+ifneq ($(KBUILD_KMSG_CHECK),0)
-+ ifeq ($(KBUILD_KMSG_CHECK),2)
-+ kmsg_cmd := print
-+ quiet_cmd_force_check_kmsg = KMSG_PRINT $<
-+ $(shell [ -d $(objtree)/man ] || mkdir -p $(objtree)/man)
-+ else
-+ kmsg_cmd := check
-+ quiet_cmd_force_check_kmsg = KMSG_CHECK $<
++# Call message checker as part of the C compilation
++#
++# Use 'make D=1' to enable checking
++# Use 'make D=2' to create the message catalog
++
++ifdef D
++ ifeq ("$(origin D)", "command line")
++ KBUILD_KMSG_CHECK = $(D)
+ endif
-+ cmd_force_check_kmsg = $(KMSG_CHECK) $(kmsg_cmd) $(CC) $(c_flags) $< ;
+endif
++ifndef KBUILD_KMSG_CHECK
++ KBUILD_KMSG_CHECK = 0
++endif
++
+ # Use make M=dir to specify directory of external module to build
+ # Old syntax make ... SUBDIRS=$PWD is still supported
+ # Setting the environment variable KBUILD_EXTMOD take precedence
+@@ -323,6 +337,7 @@ CHECK = sparse
- # Descending
- # ---------------------------------------------------------------------------
+ CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
+ -Wbitwise -Wno-return-void $(CF)
++KMSG_CHECK = $(srctree)/scripts/kmsg-doc
+ MODFLAGS = -DMODULE
+ CFLAGS_MODULE = $(MODFLAGS)
+ AFLAGS_MODULE = $(MODFLAGS)
+@@ -361,6 +376,7 @@ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODU
+ export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+ export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
+ export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
++export KBUILD_KMSG_CHECK KMSG_CHECK
+
+ # When compiling out-of-tree modules, put MODVERDIR in the module
+ # tree rather than in the kernel tree. The kernel tree might
+Index: linux-sles11sp1/scripts/kmsg-doc
+===================================================================
--- /dev/null
-+++ b/scripts/kmsg-doc
++++ linux-sles11sp1/scripts/kmsg-doc
@@ -0,0 +1,479 @@
+#!/usr/bin/perl -w
+#
@@ -8484,3 +8681,41 @@ Acked-by: John Jolly <jjolly@suse.de>
+}
+
+exit($errors);
+Index: linux-sles11sp1/scripts/Makefile.build
+===================================================================
+--- linux-sles11sp1.orig/scripts/Makefile.build
++++ linux-sles11sp1/scripts/Makefile.build
+@@ -227,12 +227,14 @@ endef
+ # Built-in and composite module parts
+ $(obj)/%.o: $(src)/%.c FORCE
+ $(call cmd,force_checksrc)
++ $(call cmd,force_check_kmsg)
+ $(call if_changed_rule,cc_o_c)
+
+ # Single-part modules are special since we need to mark them in $(MODVERDIR)
+
+ $(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
+ $(call cmd,force_checksrc)
++ $(call cmd,force_check_kmsg)
+ $(call if_changed_rule,cc_o_c)
+ @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
+
+@@ -356,6 +358,18 @@ $(multi-used-m) : %.o: $(multi-objs-m) F
+
+ targets += $(multi-used-y) $(multi-used-m)
+
++# kmsg check tool
++ifneq ($(KBUILD_KMSG_CHECK),0)
++ ifeq ($(KBUILD_KMSG_CHECK),2)
++ kmsg_cmd := print
++ quiet_cmd_force_check_kmsg = KMSG_PRINT $<
++ $(shell [ -d $(objtree)/man ] || mkdir -p $(objtree)/man)
++ else
++ kmsg_cmd := check
++ quiet_cmd_force_check_kmsg = KMSG_CHECK $<
++ endif
++ cmd_force_check_kmsg = $(KMSG_CHECK) $(kmsg_cmd) $(CC) $(c_flags) $< ;
++endif
+
+ # Descending
+ # ---------------------------------------------------------------------------
diff --git a/patches.drivers/lpfc-add-raywire-id b/patches.drivers/lpfc-add-raywire-id
new file mode 100644
index 0000000000..4517121d45
--- /dev/null
+++ b/patches.drivers/lpfc-add-raywire-id
@@ -0,0 +1,33 @@
+From: Hannes Reinecke <hare@suse.de>
+Subject: Add missing PCI-ID to lpfc
+
+The lpfc driver is missing some (pre-production) PCI-IDs.
+Adding them until we get confirmation/driver update from Emulex.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
+index ccb2672..b5b8ae3 100644
+--- a/drivers/scsi/lpfc/lpfc_hw.h
++++ b/drivers/scsi/lpfc/lpfc_hw.h
+@@ -1183,6 +1183,7 @@ typedef struct {
+ #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12
+ #define PCI_VENDOR_ID_SERVERENGINE 0x19a2
+ #define PCI_DEVICE_ID_TIGERSHARK 0x0704
++#define PCI_DEVICE_ID_RAYWIRE 0x0214
+
+ #define JEDEC_ID_ADDRESS 0x0080001c
+ #define FIREFLY_JEDEC_ID 0x1ACC
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index f913f1e..80c352a 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -7969,6 +7969,8 @@ static struct pci_device_id lpfc_id_table[] = {
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_S,
+ PCI_ANY_ID, PCI_ANY_ID, },
++ {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_RAYWIRE,
++ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { 0 }
diff --git a/patches.drivers/qla2xxx-8.03.01-k7-update b/patches.drivers/qla2xxx-8.03.01-k7-update
new file mode 100644
index 0000000000..63f5d6a8e3
--- /dev/null
+++ b/patches.drivers/qla2xxx-8.03.01-k7-update
@@ -0,0 +1,684 @@
+From: Andrew Vasquez <andrew.vasquez@qlogic.com>
+Subject: qla2xxx driver update to 8.03.01-k7
+References: bnc#560415
+Patch-Mainline: scsi-misc
+
+This patch updates the qla2xxx driver to version 8.03.01-k7.
+It consists of the following commit IDs from scsi-misc:
+
+0a2a429ed1dd964c115c78e1264464f07f6d4aa3
+[SCSI] qla2xxx: Add firmware-dump kobject uevent notification.
+0e94e844963f32d33a8b5b255adeea07ffe4816b
+[SCSI] qla2xxx: Display additional mailbox registers during AEN handling.
+759b9d2994b4b196cc05e829c72029159c4fd41f
+[SCSI] qla2xxx: Reread firmware versions information after an ISP abort.
+29915d0880aa0224b918c16741b3bbe9d587a37f
+[SCSI] qla2xxx: Set the size of the host buffer used to fetch DCBX and XGMAC parameters t
+c655314e8bdff0c29f8aa1032515aed789b39538
+[SCSI] qla2xxx: Retrieve firmware's maximum number of supported FCFs.
+6a9517c261ccf0bf3f17cc6b70c3902f9a5cae3a
+[SCSI] qla2xxx: Properly check FCP_RSP response-info field after TMF completion.
+302778be3d49f174f648e8f8c0cfa7ccd4892ee4
+[SCSI] qla2xxx: Properly re-register FC4/FDMI after physical and logical link disruptions
+ac3b0219937d85b223598655935dd62e85dcef8f
+[SCSI] qla2xxx: Properly handle UNDERRUN completion statuses.
+
+Acked-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/Documentation/ABI/stable/sysfs-driver-qla2xxx b/Documentation/ABI/stable/sysfs-driver-qla2xxx
+new file mode 100644
+index 0000000..9a59d84
+--- /dev/null
++++ b/Documentation/ABI/stable/sysfs-driver-qla2xxx
+@@ -0,0 +1,8 @@
++What: /sys/bus/pci/drivers/qla2xxx/.../devices/*
++Date: September 2009
++Contact: QLogic Linux Driver <linux-driver@qlogic.com>
++Description: qla2xxx-udev.sh currently looks for uevent CHANGE events to
++ signal a firmware-dump has been generated by the driver and is
++ ready for retrieval.
++Users: qla2xxx-udev.sh. Proposed changes should be mailed to
++ linux-driver@qlogic.com
+diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
+index cca8e4a..cb2eca4 100644
+--- a/drivers/scsi/qla2xxx/qla_dbg.c
++++ b/drivers/scsi/qla2xxx/qla_dbg.c
+@@ -377,6 +377,24 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+ return ptr + sizeof(struct qla2xxx_mq_chain);
+ }
+
++static void
++qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
++{
++ struct qla_hw_data *ha = vha->hw;
++
++ if (rval != QLA_SUCCESS) {
++ qla_printk(KERN_WARNING, ha,
++ "Failed to dump firmware (%x)!!!\n", rval);
++ ha->fw_dumped = 0;
++ } else {
++ qla_printk(KERN_INFO, ha,
++ "Firmware dump saved to temp buffer (%ld/%p).\n",
++ vha->host_no, ha->fw_dump);
++ ha->fw_dumped = 1;
++ qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
++ }
++}
++
+ /**
+ * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
+ * @ha: HA context
+@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+ if (rval == QLA_SUCCESS)
+ qla2xxx_copy_queues(ha, nxt);
+
+- if (rval != QLA_SUCCESS) {
+- qla_printk(KERN_WARNING, ha,
+- "Failed to dump firmware (%x)!!!\n", rval);
+- ha->fw_dumped = 0;
+-
+- } else {
+- qla_printk(KERN_INFO, ha,
+- "Firmware dump saved to temp buffer (%ld/%p).\n",
+- base_vha->host_no, ha->fw_dump);
+- ha->fw_dumped = 1;
+- }
++ qla2xxx_dump_post_process(base_vha, rval);
+
+ qla2300_fw_dump_failed:
+ if (!hardware_locked)
+@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+ if (rval == QLA_SUCCESS)
+ qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
+
+- if (rval != QLA_SUCCESS) {
+- qla_printk(KERN_WARNING, ha,
+- "Failed to dump firmware (%x)!!!\n", rval);
+- ha->fw_dumped = 0;
+-
+- } else {
+- qla_printk(KERN_INFO, ha,
+- "Firmware dump saved to temp buffer (%ld/%p).\n",
+- base_vha->host_no, ha->fw_dump);
+- ha->fw_dumped = 1;
+- }
++ qla2xxx_dump_post_process(base_vha, rval);
+
+ qla2100_fw_dump_failed:
+ if (!hardware_locked)
+@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+ qla24xx_copy_eft(ha, nxt);
+
+ qla24xx_fw_dump_failed_0:
+- if (rval != QLA_SUCCESS) {
+- qla_printk(KERN_WARNING, ha,
+- "Failed to dump firmware (%x)!!!\n", rval);
+- ha->fw_dumped = 0;
+-
+- } else {
+- qla_printk(KERN_INFO, ha,
+- "Firmware dump saved to temp buffer (%ld/%p).\n",
+- base_vha->host_no, ha->fw_dump);
+- ha->fw_dumped = 1;
+- }
++ qla2xxx_dump_post_process(base_vha, rval);
+
+ qla24xx_fw_dump_failed:
+ if (!hardware_locked)
+@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+ }
+
+ qla25xx_fw_dump_failed_0:
+- if (rval != QLA_SUCCESS) {
+- qla_printk(KERN_WARNING, ha,
+- "Failed to dump firmware (%x)!!!\n", rval);
+- ha->fw_dumped = 0;
+-
+- } else {
+- qla_printk(KERN_INFO, ha,
+- "Firmware dump saved to temp buffer (%ld/%p).\n",
+- base_vha->host_no, ha->fw_dump);
+- ha->fw_dumped = 1;
+- }
++ qla2xxx_dump_post_process(base_vha, rval);
+
+ qla25xx_fw_dump_failed:
+ if (!hardware_locked)
+@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+ }
+
+ qla81xx_fw_dump_failed_0:
+- if (rval != QLA_SUCCESS) {
+- qla_printk(KERN_WARNING, ha,
+- "Failed to dump firmware (%x)!!!\n", rval);
+- ha->fw_dumped = 0;
+-
+- } else {
+- qla_printk(KERN_INFO, ha,
+- "Firmware dump saved to temp buffer (%ld/%p).\n",
+- base_vha->host_no, ha->fw_dump);
+- ha->fw_dumped = 1;
+- }
++ qla2xxx_dump_post_process(base_vha, rval);
+
+ qla81xx_fw_dump_failed:
+ if (!hardware_locked)
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 2150618..6b9bf23 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2123,6 +2123,7 @@ enum qla_work_type {
+ QLA_EVT_ASYNC_LOGIN_DONE,
+ QLA_EVT_ASYNC_LOGOUT,
+ QLA_EVT_ASYNC_LOGOUT_DONE,
++ QLA_EVT_UEVENT,
+ };
+
+
+@@ -2146,6 +2147,10 @@ struct qla_work_evt {
+ #define QLA_LOGIO_LOGIN_RETRIED BIT_0
+ u16 data[2];
+ } logio;
++ struct {
++ u32 code;
++#define QLA_UEVENT_CODE_FW_DUMP 0
++ } uevent;
+ } u;
+ };
+
+@@ -2435,11 +2440,11 @@ struct qla_hw_data {
+ dma_addr_t edc_data_dma;
+ uint16_t edc_data_len;
+
+-#define XGMAC_DATA_SIZE PAGE_SIZE
++#define XGMAC_DATA_SIZE 4096
+ void *xgmac_data;
+ dma_addr_t xgmac_data_dma;
+
+-#define DCBX_TLV_DATA_SIZE PAGE_SIZE
++#define DCBX_TLV_DATA_SIZE 4096
+ void *dcbx_tlv;
+ dma_addr_t dcbx_tlv_dma;
+
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index f3d1d1a..e218513 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
+ uint16_t *);
+ extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
+ fc_port_t *, uint16_t *);
++extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
+
+ extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
+
+@@ -246,7 +247,7 @@ qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
+
+ extern int
+ qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
+- uint16_t *, uint16_t *, uint16_t *);
++ uint16_t *, uint16_t *, uint16_t *, uint16_t *);
+
+ extern int
+ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 9e3eaac..b74924b 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -277,7 +277,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
+ vha->marker_needed = 0;
+ ha->isp_abort_cnt = 0;
+ ha->beacon_blink_led = 0;
+- set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
+
+ set_bit(0, ha->req_qid_map);
+ set_bit(0, ha->rsp_qid_map);
+@@ -1203,7 +1202,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
+ }
+ qla2x00_get_resource_cnts(vha, NULL,
+ &ha->fw_xcb_count, NULL, NULL,
+- &ha->max_npiv_vports);
++ &ha->max_npiv_vports, NULL);
+
+ if (!fw_major_version && ql2xallocfwdump)
+ qla2x00_alloc_fw_dump(vha);
+@@ -3573,6 +3572,15 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
+ ha->isp_abort_cnt = 0;
+ clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
+
++ if (IS_QLA81XX(ha))
++ qla2x00_get_fw_version(vha,
++ &ha->fw_major_version,
++ &ha->fw_minor_version,
++ &ha->fw_subminor_version,
++ &ha->fw_attributes, &ha->fw_memory_size,
++ ha->mpi_version, &ha->mpi_capabilities,
++ ha->phy_version);
++
+ if (ha->fce) {
+ ha->flags.fce_enabled = 1;
+ memset(ha->fce, 0,
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index b20a716..8049873 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -313,10 +313,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
+ static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" };
+ char *link_speed;
+ uint16_t handle_cnt;
+- uint16_t cnt;
++ uint16_t cnt, mbx;
+ uint32_t handles[5];
+ struct qla_hw_data *ha = vha->hw;
+ struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
++ struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
+ uint32_t rscn_entry, host_pid;
+ uint8_t rscn_queue_index;
+ unsigned long flags;
+@@ -395,9 +396,10 @@ skip_rio:
+ break;
+
+ case MBA_SYSTEM_ERR: /* System Error */
++ mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
+ qla_printk(KERN_INFO, ha,
+- "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
+- mb[1], mb[2], mb[3]);
++ "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
++ "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
+
+ ha->isp_ops->fw_dump(vha, 1);
+
+@@ -419,9 +421,10 @@ skip_rio:
+ break;
+
+ case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
+- DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
+- vha->host_no));
+- qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
++ DEBUG2(printk("scsi(%ld): ISP Request Transfer Error (%x).\n",
++ vha->host_no, mb[1]));
++ qla_printk(KERN_WARNING, ha,
++ "ISP Request Transfer Error (%x).\n", mb[1]);
+
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ break;
+@@ -485,10 +488,13 @@ skip_rio:
+ break;
+
+ case MBA_LOOP_DOWN: /* Loop Down Event */
++ mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
+ DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
+- "(%x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3]));
+- qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
+- mb[1], mb[2], mb[3]);
++ "(%x %x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3],
++ mbx));
++ qla_printk(KERN_INFO, ha,
++ "LOOP DOWN detected (%x %x %x %x).\n", mb[1], mb[2], mb[3],
++ mbx);
+
+ if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+ atomic_set(&vha->loop_state, LOOP_DOWN);
+@@ -1347,16 +1353,22 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+
+ sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
+ if (IS_FWI2_CAPABLE(ha)) {
+- sense_len = le32_to_cpu(sts24->sense_len);
+- rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
+- resid_len = le32_to_cpu(sts24->rsp_residual_count);
+- fw_resid_len = le32_to_cpu(sts24->residual_len);
++ if (scsi_status & SS_SENSE_LEN_VALID)
++ sense_len = le32_to_cpu(sts24->sense_len);
++ if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
++ rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
++ if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
++ resid_len = le32_to_cpu(sts24->rsp_residual_count);
++ if (comp_status == CS_DATA_UNDERRUN)
++ fw_resid_len = le32_to_cpu(sts24->residual_len);
+ rsp_info = sts24->data;
+ sense_data = sts24->data;
+ host_to_fcp_swap(sts24->data, sizeof(sts24->data));
+ } else {
+- sense_len = le16_to_cpu(sts->req_sense_length);
+- rsp_info_len = le16_to_cpu(sts->rsp_info_len);
++ if (scsi_status & SS_SENSE_LEN_VALID)
++ sense_len = le16_to_cpu(sts->req_sense_length);
++ if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
++ rsp_info_len = le16_to_cpu(sts->rsp_info_len);
+ resid_len = le32_to_cpu(sts->residual_length);
+ rsp_info = sts->rsp_info;
+ sense_data = sts->req_sense_data;
+@@ -1443,38 +1455,62 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+ break;
+
+ case CS_DATA_UNDERRUN:
+- resid = resid_len;
++ DEBUG2(printk(KERN_INFO
++ "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x. "
++ "resid=0x%x fw_resid=0x%x cdb=0x%x os_underflow=0x%x\n",
++ vha->host_no, cp->device->id, cp->device->lun, comp_status,
++ scsi_status, resid_len, fw_resid_len, cp->cmnd[0],
++ cp->underflow));
++
+ /* Use F/W calculated residual length. */
+- if (IS_FWI2_CAPABLE(ha)) {
+- if (!(scsi_status & SS_RESIDUAL_UNDER)) {
+- lscsi_status = 0;
+- } else if (resid != fw_resid_len) {
+- scsi_status &= ~SS_RESIDUAL_UNDER;
+- lscsi_status = 0;
++ resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
++ scsi_set_resid(cp, resid);
++ if (scsi_status & SS_RESIDUAL_UNDER) {
++ if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
++ DEBUG2(printk(
++ "scsi(%ld:%d:%d:%d) Dropped frame(s) "
++ "detected (%x of %x bytes)...residual "
++ "length mismatch...retrying command.\n",
++ vha->host_no, cp->device->channel,
++ cp->device->id, cp->device->lun, resid,
++ scsi_bufflen(cp)));
++
++ cp->result = DID_ERROR << 16 | lscsi_status;
++ break;
+ }
+- resid = fw_resid_len;
+- }
+
+- if (scsi_status & SS_RESIDUAL_UNDER) {
+- scsi_set_resid(cp, resid);
+- } else {
+- DEBUG2(printk(KERN_INFO
+- "scsi(%ld:%d:%d) UNDERRUN status detected "
+- "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
+- "os_underflow=0x%x\n", vha->host_no,
+- cp->device->id, cp->device->lun, comp_status,
+- scsi_status, resid_len, resid, cp->cmnd[0],
+- cp->underflow));
++ if (!lscsi_status &&
++ ((unsigned)(scsi_bufflen(cp) - resid) <
++ cp->underflow)) {
++ qla_printk(KERN_INFO, ha,
++ "scsi(%ld:%d:%d:%d): Mid-layer underflow "
++ "detected (%x of %x bytes)...returning "
++ "error status.\n", vha->host_no,
++ cp->device->channel, cp->device->id,
++ cp->device->lun, resid, scsi_bufflen(cp));
++
++ cp->result = DID_ERROR << 16;
++ break;
++ }
++ } else if (!lscsi_status) {
++ DEBUG2(printk(
++ "scsi(%ld:%d:%d:%d) Dropped frame(s) detected "
++ "(%x of %x bytes)...firmware reported underrun..."
++ "retrying command.\n", vha->host_no,
++ cp->device->channel, cp->device->id,
++ cp->device->lun, resid, scsi_bufflen(cp)));
+
++ cp->result = DID_ERROR << 16;
++ break;
+ }
+
++ cp->result = DID_OK << 16 | lscsi_status;
++
+ /*
+ * Check to see if SCSI Status is non zero. If so report SCSI
+ * Status.
+ */
+ if (lscsi_status != 0) {
+- cp->result = DID_OK << 16 | lscsi_status;
+-
+ if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+ DEBUG2(printk(KERN_INFO
+ "scsi(%ld): QUEUE FULL status detected "
+@@ -1501,42 +1537,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+ break;
+
+ qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
+- } else {
+- /*
+- * If RISC reports underrun and target does not report
+- * it then we must have a lost frame, so tell upper
+- * layer to retry it by reporting an error.
+- */
+- if (!(scsi_status & SS_RESIDUAL_UNDER)) {
+- DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
+- "frame(s) detected (%x of %x bytes)..."
+- "retrying command.\n",
+- vha->host_no, cp->device->channel,
+- cp->device->id, cp->device->lun, resid,
+- scsi_bufflen(cp)));
+-
+- scsi_set_resid(cp, resid);
+- cp->result = DID_ERROR << 16;
+- break;
+- }
+-
+- /* Handle mid-layer underflow */
+- if ((unsigned)(scsi_bufflen(cp) - resid) <
+- cp->underflow) {
+- qla_printk(KERN_INFO, ha,
+- "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+- "detected (%x of %x bytes)...returning "
+- "error status.\n", vha->host_no,
+- cp->device->channel, cp->device->id,
+- cp->device->lun, resid,
+- scsi_bufflen(cp));
+-
+- cp->result = DID_ERROR << 16;
+- break;
+- }
+-
+- /* Everybody online, looking good... */
+- cp->result = DID_OK << 16;
+ }
+ break;
+
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index b6202fe..05d595d 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -2006,7 +2006,7 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
+ int
+ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
+ uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
+- uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports)
++ uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
+ {
+ int rval;
+ mbx_cmd_t mc;
+@@ -2017,6 +2017,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
+ mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
+ mcp->out_mb = MBX_0;
+ mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
++ if (IS_QLA81XX(vha->hw))
++ mcp->in_mb |= MBX_12;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+@@ -2027,9 +2029,10 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
+ vha->host_no, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
+- "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no,
+- mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
+- mcp->mb[10], mcp->mb[11]));
++ "mb7=%x mb10=%x mb11=%x mb12=%x.\n", __func__,
++ vha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3],
++ mcp->mb[6], mcp->mb[7], mcp->mb[10], mcp->mb[11],
++ mcp->mb[12]));
+
+ if (cur_xchg_cnt)
+ *cur_xchg_cnt = mcp->mb[3];
+@@ -2041,6 +2044,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
+ *orig_iocb_cnt = mcp->mb[10];
+ if (vha->hw->flags.npiv_supported && max_npiv_vports)
+ *max_npiv_vports = mcp->mb[11];
++ if (IS_QLA81XX(vha->hw) && max_fcfs)
++ *max_fcfs = mcp->mb[12];
+ }
+
+ return (rval);
+@@ -2313,6 +2318,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
+ {
+ int rval, rval2;
+ struct tsk_mgmt_cmd *tsk;
++ struct sts_entry_24xx *sts;
+ dma_addr_t tsk_dma;
+ scsi_qla_host_t *vha;
+ struct qla_hw_data *ha;
+@@ -2352,20 +2358,37 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
+ sizeof(tsk->p.tsk.lun));
+ }
+
++ sts = &tsk->p.sts;
+ rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
+ "(%x).\n", __func__, vha->host_no, name, rval));
+- } else if (tsk->p.sts.entry_status != 0) {
++ } else if (sts->entry_status != 0) {
+ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+ "-- error status (%x).\n", __func__, vha->host_no,
+- tsk->p.sts.entry_status));
++ sts->entry_status));
+ rval = QLA_FUNCTION_FAILED;
+- } else if (tsk->p.sts.comp_status !=
++ } else if (sts->comp_status !=
+ __constant_cpu_to_le16(CS_COMPLETE)) {
+ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+ "-- completion status (%x).\n", __func__,
+- vha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
++ vha->host_no, le16_to_cpu(sts->comp_status)));
++ rval = QLA_FUNCTION_FAILED;
++ } else if (!(le16_to_cpu(sts->scsi_status) &
++ SS_RESPONSE_INFO_LEN_VALID)) {
++ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
++ "-- no response info (%x).\n", __func__, vha->host_no,
++ le16_to_cpu(sts->scsi_status)));
++ rval = QLA_FUNCTION_FAILED;
++ } else if (le32_to_cpu(sts->rsp_data_len) < 4) {
++ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
++ "-- not enough response info (%d).\n", __func__,
++ vha->host_no, le32_to_cpu(sts->rsp_data_len)));
++ rval = QLA_FUNCTION_FAILED;
++ } else if (sts->data[3]) {
++ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
++ "-- response (%x).\n", __func__,
++ vha->host_no, sts->data[3]));
+ rval = QLA_FUNCTION_FAILED;
+ }
+
+@@ -2759,8 +2782,10 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
+ vp_idx, MSB(stat),
+ rptid_entry->port_id[2], rptid_entry->port_id[1],
+ rptid_entry->port_id[0]));
+- if (vp_idx == 0)
+- return;
++
++ vp = vha;
++ if (vp_idx == 0 && (MSB(stat) != 1))
++ goto reg_needed;
+
+ if (MSB(stat) == 1) {
+ DEBUG2(printk("scsi(%ld): Could not acquire ID for "
+@@ -2783,8 +2808,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
+ * response queue. Handle it in dpc context.
+ */
+ set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
+- set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
+
++reg_needed:
++ set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
++ set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
++ set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ }
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index e07b361..a47d343 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -382,8 +382,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
+ vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
+
+ vha->dpc_flags = 0L;
+- set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
+- set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
+
+ /*
+ * To fix the issue of processing a parent's RSCN for the vport before
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index b79fca7..ecf2a40 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -11,6 +11,7 @@
+ #include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/mutex.h>
++#include <linux/kobject.h>
+
+ #include <scsi/scsi_tcq.h>
+ #include <scsi/scsicam.h>
+@@ -2653,6 +2654,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
+ qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
+ qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
+
++int
++qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
++{
++ struct qla_work_evt *e;
++
++ e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
++ if (!e)
++ return QLA_FUNCTION_FAILED;
++
++ e->u.uevent.code = code;
++ return qla2x00_post_work(vha, e);
++}
++
++static void
++qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
++{
++ char event_string[40];
++ char *envp[] = { event_string, NULL };
++
++ switch (code) {
++ case QLA_UEVENT_CODE_FW_DUMP:
++ snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
++ vha->host_no);
++ break;
++ default:
++ /* do nothing */
++ break;
++ }
++ kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
++}
++
+ void
+ qla2x00_do_work(struct scsi_qla_host *vha)
+ {
+@@ -2690,6 +2722,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
+ qla2x00_async_logout_done(vha, e->u.logio.fcport,
+ e->u.logio.data);
+ break;
++ case QLA_EVT_UEVENT:
++ qla2x00_uevent_emit(vha, e->u.uevent.code);
++ break;
+ }
+ if (e->flags & QLA_EVT_FLAG_FREE)
+ kfree(e);
+diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
+index ac107a2..807e0db 100644
+--- a/drivers/scsi/qla2xxx/qla_version.h
++++ b/drivers/scsi/qla2xxx/qla_version.h
+@@ -7,7 +7,7 @@
+ /*
+ * Driver version
+ */
+-#define QLA2XXX_VERSION "8.03.01-k6"
++#define QLA2XXX_VERSION "8.03.01-k7"
+
+ #define QLA_DRIVER_MAJOR_VER 8
+ #define QLA_DRIVER_MINOR_VER 3
diff --git a/patches.suse/SoN-29-fix-swap_sync_page-race b/patches.suse/SoN-29-fix-swap_sync_page-race
index 948902e4a3..f334a698d7 100644
--- a/patches.suse/SoN-29-fix-swap_sync_page-race
+++ b/patches.suse/SoN-29-fix-swap_sync_page-race
@@ -16,15 +16,20 @@ Acked-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
- mm/page_io.c | 2 ++
+ mm/page_io.c | 5 +++++
mm/swapfile.c | 8 +++++++-
- 2 files changed, 9 insertions(+), 1 deletion(-)
+ 2 files changed, 12 insertions(+), 1 deletion(-)
-Index: linux-2.6.31-master/mm/page_io.c
-===================================================================
---- linux-2.6.31-master.orig/mm/page_io.c
-+++ linux-2.6.31-master/mm/page_io.c
-@@ -151,6 +151,8 @@ int swap_set_page_dirty(struct page *pag
+--- linux-2.6.32-master.orig/mm/page_io.c
++++ linux-2.6.32-master/mm/page_io.c
+@@ -133,10 +133,15 @@ out:
+ return ret;
+ }
+
++/* this comment ensure the patch applies to swap_sync_page
++ * and not swap_set_page_dirty by mistake
++ */
+ void swap_sync_page(struct page *page)
{
struct swap_info_struct *sis = page_swap_info(page);
@@ -33,10 +38,8 @@ Index: linux-2.6.31-master/mm/page_io.c
if (sis->flags & SWP_FILE) {
struct address_space *mapping = sis->swap_file->f_mapping;
-Index: linux-2.6.31-master/mm/swapfile.c
-===================================================================
---- linux-2.6.31-master.orig/mm/swapfile.c
-+++ linux-2.6.31-master/mm/swapfile.c
+--- linux-2.6.32-master.orig/mm/swapfile.c
++++ linux-2.6.32-master/mm/swapfile.c
@@ -2188,7 +2188,13 @@ get_swap_info_struct(unsigned type)
struct swap_info_struct *page_swap_info(struct page *page)
{
diff --git a/patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch b/patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch
new file mode 100644
index 0000000000..59effd63f5
--- /dev/null
+++ b/patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch
@@ -0,0 +1,1744 @@
+From c498af3f0c5406e135eeb8be2a49713f1fbe6595 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Date: Fri, 4 Dec 2009 08:31:49 -0800
+Subject: Revert "USB: remove phidget drivers from kernel tree."
+Patch-mainline: never
+
+Remove this patch for openSUSE 11.3
+
+This reverts commit 77aa2b5878f48d6ab6e0c412cc9214c845483475 which removed
+the phidget drivers from the kernel tree.
+
+For SLE11 SP1, we need to put the driver back as we said we would
+support it for the lifetime of SLE11, despite upstream dropping the
+driver and using a userspace library instead.
+
+The userspace library will still work if anyone wants to use it, and it
+can be found at:
+ http://www.phidgets.com/downloads.php?os_id=3
+and full documentation at:
+ http://www.phidgets.com/documentation/web/cdoc/index.html
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/Kconfig | 39 +
+ drivers/usb/misc/Makefile | 4
+ drivers/usb/misc/phidget.c | 43 +
+ drivers/usb/misc/phidget.h | 12
+ drivers/usb/misc/phidgetkit.c | 740 +++++++++++++++++++++++++++++++++
+ drivers/usb/misc/phidgetmotorcontrol.c | 465 ++++++++++++++++++++
+ drivers/usb/misc/phidgetservo.c | 375 ++++++++++++++++
+ 7 files changed, 1678 insertions(+)
+
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -135,6 +135,45 @@ config USB_CYTHERM
+ To compile this driver as a module, choose M here: the
+ module will be called cytherm.
+
++config USB_PHIDGET
++ tristate "USB Phidgets drivers"
++ depends on USB
++ help
++ Say Y here to enable the various drivers for devices from
++ Phidgets inc.
++
++config USB_PHIDGETKIT
++ tristate "USB PhidgetInterfaceKit support"
++ depends on USB_PHIDGET
++ help
++ Say Y here if you want to connect a PhidgetInterfaceKit USB device
++ from Phidgets Inc.
++
++ To compile this driver as a module, choose M here: the
++ module will be called phidgetkit.
++
++config USB_PHIDGETMOTORCONTROL
++ tristate "USB PhidgetMotorControl support"
++ depends on USB_PHIDGET
++ help
++ Say Y here if you want to connect a PhidgetMotorControl USB device
++ from Phidgets Inc.
++
++ To compile this driver as a module, choose M here: the
++ module will be called phidgetmotorcontrol.
++
++config USB_PHIDGETSERVO
++ tristate "USB PhidgetServo support"
++ depends on USB_PHIDGET
++ help
++ Say Y here if you want to connect an 1 or 4 Motor PhidgetServo
++ servo controller version 2.0 or 3.0.
++
++ Phidgets Inc. has a web page at <http://www.phidgets.com/>.
++
++ To compile this driver as a module, choose M here: the
++ module will be called phidgetservo.
++
+ config USB_IDMOUSE
+ tristate "Siemens ID USB Mouse Fingerprint sensor support"
+ depends on USB
+--- a/drivers/usb/misc/Makefile
++++ b/drivers/usb/misc/Makefile
+@@ -18,6 +18,10 @@ obj-$(CONFIG_USB_LCD) += usblcd.o
+ obj-$(CONFIG_USB_LD) += ldusb.o
+ obj-$(CONFIG_USB_LED) += usbled.o
+ obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
++obj-$(CONFIG_USB_PHIDGET) += phidget.o
++obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o
++obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o
++obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
+ obj-$(CONFIG_USB_RIO500) += rio500.o
+ obj-$(CONFIG_USB_TEST) += usbtest.o
+ obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
+--- /dev/null
++++ b/drivers/usb/misc/phidget.c
+@@ -0,0 +1,43 @@
++/*
++ * USB Phidgets class
++ *
++ * Copyright (C) 2006 Sean Young <sean@mess.org>
++ *
++ * This program 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/device.h>
++
++struct class *phidget_class;
++
++static int __init init_phidget(void)
++{
++ phidget_class = class_create(THIS_MODULE, "phidget");
++
++ if (IS_ERR(phidget_class))
++ return PTR_ERR(phidget_class);
++
++ return 0;
++}
++
++static void __exit cleanup_phidget(void)
++{
++ class_destroy(phidget_class);
++}
++
++EXPORT_SYMBOL_GPL(phidget_class);
++
++module_init(init_phidget);
++module_exit(cleanup_phidget);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Sean Young <sean@mess.org>");
++MODULE_DESCRIPTION("Container module for phidget class");
++
+--- /dev/null
++++ b/drivers/usb/misc/phidget.h
+@@ -0,0 +1,12 @@
++/*
++ * USB Phidgets class
++ *
++ * Copyright (C) 2006 Sean Young <sean@mess.org>
++ *
++ * This program 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.
++ */
++
++extern struct class *phidget_class;
+--- /dev/null
++++ b/drivers/usb/misc/phidgetkit.c
+@@ -0,0 +1,740 @@
++/*
++ * USB PhidgetInterfaceKit driver 1.0
++ *
++ * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
++ * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net>
++ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
++ *
++ * This program 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.
++ *
++ * This is a driver for the USB PhidgetInterfaceKit.
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++
++#include "phidget.h"
++
++#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
++#define DRIVER_DESC "USB PhidgetInterfaceKit Driver"
++
++#define USB_VENDOR_ID_GLAB 0x06c2
++#define USB_DEVICE_ID_INTERFACEKIT004 0x0040
++#define USB_DEVICE_ID_INTERFACEKIT01616 0x0044
++#define USB_DEVICE_ID_INTERFACEKIT888 0x0045
++#define USB_DEVICE_ID_INTERFACEKIT047 0x0051
++#define USB_DEVICE_ID_INTERFACEKIT088 0x0053
++
++#define USB_VENDOR_ID_WISEGROUP 0x0925
++#define USB_DEVICE_ID_INTERFACEKIT884 0x8201
++
++#define MAX_INTERFACES 16
++
++#define URB_INT_SIZE 8
++
++struct driver_interfacekit {
++ int sensors;
++ int inputs;
++ int outputs;
++ int has_lcd;
++ int amnesiac;
++};
++
++#define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac) \
++{ \
++ .sensors = _sensors, \
++ .inputs = _inputs, \
++ .outputs = _outputs, \
++ .has_lcd = _lcd, \
++ .amnesiac = _amnesiac \
++};
++
++static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0);
++static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1);
++static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0);
++static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0);
++static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0);
++static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0);
++static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0);
++
++static unsigned long device_no;
++
++struct interfacekit {
++ struct usb_device *udev;
++ struct usb_interface *intf;
++ struct driver_interfacekit *ifkit;
++ struct device *dev;
++ unsigned long outputs;
++ int dev_no;
++ u8 inputs[MAX_INTERFACES];
++ u16 sensors[MAX_INTERFACES];
++ u8 lcd_files_on;
++
++ struct urb *irq;
++ unsigned char *data;
++ dma_addr_t data_dma;
++
++ struct delayed_work do_notify;
++ struct delayed_work do_resubmit;
++ unsigned long input_events;
++ unsigned long sensor_events;
++};
++
++static struct usb_device_id id_table[] = {
++ {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004),
++ .driver_info = (kernel_ulong_t)&ph_004},
++ {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814),
++ .driver_info = (kernel_ulong_t)&ph_888o},
++ {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff),
++ .driver_info = (kernel_ulong_t)&ph_888n},
++ {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047),
++ .driver_info = (kernel_ulong_t)&ph_047},
++ {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
++ .driver_info = (kernel_ulong_t)&ph_088},
++ {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616),
++ .driver_info = (kernel_ulong_t)&ph_01616},
++ {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884),
++ .driver_info = (kernel_ulong_t)&ph_884},
++ {}
++};
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static int set_outputs(struct interfacekit *kit)
++{
++ u8 *buffer;
++ int retval;
++
++ buffer = kzalloc(4, GFP_KERNEL);
++ if (!buffer) {
++ dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
++ return -ENOMEM;
++ }
++ buffer[0] = (u8)kit->outputs;
++ buffer[1] = (u8)(kit->outputs >> 8);
++
++ dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs);
++
++ retval = usb_control_msg(kit->udev,
++ usb_sndctrlpipe(kit->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2000);
++
++ if (retval != 4)
++ dev_err(&kit->udev->dev, "usb_control_msg returned %d\n",
++ retval);
++ kfree(buffer);
++
++ if (kit->ifkit->amnesiac)
++ schedule_delayed_work(&kit->do_resubmit, HZ / 2);
++
++ return retval < 0 ? retval : 0;
++}
++
++static int change_string(struct interfacekit *kit, const char *display, unsigned char row)
++{
++ unsigned char *buffer;
++ unsigned char *form_buffer;
++ int retval = -ENOMEM;
++ int i,j, len, buf_ptr;
++
++ buffer = kmalloc(8, GFP_KERNEL);
++ form_buffer = kmalloc(30, GFP_KERNEL);
++ if ((!buffer) || (!form_buffer)) {
++ dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
++ goto exit;
++ }
++
++ len = strlen(display);
++ if (len > 20)
++ len = 20;
++
++ dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display);
++
++ form_buffer[0] = row * 0x40 + 0x80;
++ form_buffer[1] = 0x02;
++ buf_ptr = 2;
++ for (i = 0; i<len; i++)
++ form_buffer[buf_ptr++] = display[i];
++
++ for (i = 0; i < (20 - len); i++)
++ form_buffer[buf_ptr++] = 0x20;
++ form_buffer[buf_ptr++] = 0x01;
++ form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display);
++
++ for (i = 0; i < buf_ptr; i += 7) {
++ if ((buf_ptr - i) > 7)
++ len = 7;
++ else
++ len = (buf_ptr - i);
++ for (j = 0; j < len; j++)
++ buffer[j] = form_buffer[i + j];
++ buffer[7] = len;
++
++ retval = usb_control_msg(kit->udev,
++ usb_sndctrlpipe(kit->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
++ if (retval < 0)
++ goto exit;
++ }
++
++ retval = 0;
++exit:
++ kfree(buffer);
++ kfree(form_buffer);
++
++ return retval;
++}
++
++#define set_lcd_line(number) \
++static ssize_t lcd_line_##number(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ struct interfacekit *kit = dev_get_drvdata(dev); \
++ change_string(kit, buf, number - 1); \
++ return count; \
++}
++
++#define lcd_line_attr(number) \
++ __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number)
++
++set_lcd_line(1);
++set_lcd_line(2);
++
++static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct interfacekit *kit = dev_get_drvdata(dev);
++ int enabled;
++ unsigned char *buffer;
++ int retval = -ENOMEM;
++
++ buffer = kzalloc(8, GFP_KERNEL);
++ if (!buffer) {
++ dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
++ goto exit;
++ }
++
++ if (sscanf(buf, "%d", &enabled) < 1) {
++ retval = -EINVAL;
++ goto exit;
++ }
++ if (enabled)
++ buffer[0] = 0x01;
++ buffer[7] = 0x11;
++
++ dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off");
++
++ retval = usb_control_msg(kit->udev,
++ usb_sndctrlpipe(kit->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
++ if (retval < 0)
++ goto exit;
++
++ retval = count;
++exit:
++ kfree(buffer);
++ return retval;
++}
++
++static struct device_attribute dev_lcd_line_attrs[] = {
++ lcd_line_attr(1),
++ lcd_line_attr(2),
++ __ATTR(backlight, S_IWUGO, NULL, set_backlight)
++};
++
++static void remove_lcd_files(struct interfacekit *kit)
++{
++ int i;
++
++ if (kit->lcd_files_on) {
++ dev_dbg(&kit->udev->dev, "Removing lcd files\n");
++
++ for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++)
++ device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
++ }
++}
++
++static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct interfacekit *kit = dev_get_drvdata(dev);
++ int enable;
++ int i, rc;
++
++ if (kit->ifkit->has_lcd == 0)
++ return -ENODEV;
++
++ if (sscanf(buf, "%d", &enable) < 1)
++ return -EINVAL;
++
++ if (enable) {
++ if (!kit->lcd_files_on) {
++ dev_dbg(&kit->udev->dev, "Adding lcd files\n");
++ for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) {
++ rc = device_create_file(kit->dev,
++ &dev_lcd_line_attrs[i]);
++ if (rc)
++ goto out;
++ }
++ kit->lcd_files_on = 1;
++ }
++ } else {
++ if (kit->lcd_files_on) {
++ remove_lcd_files(kit);
++ kit->lcd_files_on = 0;
++ }
++ }
++
++ return count;
++out:
++ while (i-- > 0)
++ device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
++
++ return rc;
++}
++
++static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
++
++static void interfacekit_irq(struct urb *urb)
++{
++ struct interfacekit *kit = urb->context;
++ unsigned char *buffer = kit->data;
++ int i, level, sensor;
++ int retval;
++ int status = urb->status;
++
++ switch (status) {
++ case 0: /* success */
++ break;
++ case -ECONNRESET: /* unlink */
++ case -ENOENT:
++ case -ESHUTDOWN:
++ return;
++ /* -EPIPE: should clear the halt */
++ default: /* error */
++ goto resubmit;
++ }
++
++ /* digital inputs */
++ if (kit->ifkit->inputs == 16) {
++ for (i=0; i < 8; i++) {
++ level = (buffer[0] >> i) & 1;
++ if (kit->inputs[i] != level) {
++ kit->inputs[i] = level;
++ set_bit(i, &kit->input_events);
++ }
++ level = (buffer[1] >> i) & 1;
++ if (kit->inputs[8 + i] != level) {
++ kit->inputs[8 + i] = level;
++ set_bit(8 + i, &kit->input_events);
++ }
++ }
++ }
++ else if (kit->ifkit->inputs == 8) {
++ for (i=0; i < 8; i++) {
++ level = (buffer[1] >> i) & 1;
++ if (kit->inputs[i] != level) {
++ kit->inputs[i] = level;
++ set_bit(i, &kit->input_events);
++ }
++ }
++ }
++
++ /* analog inputs */
++ if (kit->ifkit->sensors) {
++ sensor = (buffer[0] & 1) ? 4 : 0;
++
++ level = buffer[2] + (buffer[3] & 0x0f) * 256;
++ if (level != kit->sensors[sensor]) {
++ kit->sensors[sensor] = level;
++ set_bit(sensor, &kit->sensor_events);
++ }
++ sensor++;
++ level = buffer[4] + (buffer[3] & 0xf0) * 16;
++ if (level != kit->sensors[sensor]) {
++ kit->sensors[sensor] = level;
++ set_bit(sensor, &kit->sensor_events);
++ }
++ sensor++;
++ level = buffer[5] + (buffer[6] & 0x0f) * 256;
++ if (level != kit->sensors[sensor]) {
++ kit->sensors[sensor] = level;
++ set_bit(sensor, &kit->sensor_events);
++ }
++ sensor++;
++ level = buffer[7] + (buffer[6] & 0xf0) * 16;
++ if (level != kit->sensors[sensor]) {
++ kit->sensors[sensor] = level;
++ set_bit(sensor, &kit->sensor_events);
++ }
++ }
++
++ if (kit->input_events || kit->sensor_events)
++ schedule_delayed_work(&kit->do_notify, 0);
++
++resubmit:
++ retval = usb_submit_urb(urb, GFP_ATOMIC);
++ if (retval)
++ err("can't resubmit intr, %s-%s/interfacekit0, retval %d",
++ kit->udev->bus->bus_name,
++ kit->udev->devpath, retval);
++}
++
++static void do_notify(struct work_struct *work)
++{
++ struct interfacekit *kit =
++ container_of(work, struct interfacekit, do_notify.work);
++ int i;
++ char sysfs_file[8];
++
++ for (i=0; i<kit->ifkit->inputs; i++) {
++ if (test_and_clear_bit(i, &kit->input_events)) {
++ sprintf(sysfs_file, "input%d", i + 1);
++ sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
++ }
++ }
++
++ for (i=0; i<kit->ifkit->sensors; i++) {
++ if (test_and_clear_bit(i, &kit->sensor_events)) {
++ sprintf(sysfs_file, "sensor%d", i + 1);
++ sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
++ }
++ }
++}
++
++static void do_resubmit(struct work_struct *work)
++{
++ struct interfacekit *kit =
++ container_of(work, struct interfacekit, do_resubmit.work);
++ set_outputs(kit);
++}
++
++#define show_set_output(value) \
++static ssize_t set_output##value(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ struct interfacekit *kit = dev_get_drvdata(dev); \
++ int enable; \
++ int retval; \
++ \
++ if (sscanf(buf, "%d", &enable) < 1) \
++ return -EINVAL; \
++ \
++ if (enable) \
++ set_bit(value - 1, &kit->outputs); \
++ else \
++ clear_bit(value - 1, &kit->outputs); \
++ \
++ retval = set_outputs(kit); \
++ \
++ return retval ? retval : count; \
++} \
++ \
++static ssize_t show_output##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct interfacekit *kit = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
++}
++
++#define output_attr(value) \
++ __ATTR(output##value, S_IWUGO | S_IRUGO, \
++ show_output##value, set_output##value)
++
++show_set_output(1);
++show_set_output(2);
++show_set_output(3);
++show_set_output(4);
++show_set_output(5);
++show_set_output(6);
++show_set_output(7);
++show_set_output(8);
++show_set_output(9);
++show_set_output(10);
++show_set_output(11);
++show_set_output(12);
++show_set_output(13);
++show_set_output(14);
++show_set_output(15);
++show_set_output(16);
++
++static struct device_attribute dev_output_attrs[] = {
++ output_attr(1), output_attr(2), output_attr(3), output_attr(4),
++ output_attr(5), output_attr(6), output_attr(7), output_attr(8),
++ output_attr(9), output_attr(10), output_attr(11), output_attr(12),
++ output_attr(13), output_attr(14), output_attr(15), output_attr(16)
++};
++
++#define show_input(value) \
++static ssize_t show_input##value(struct device *dev, \
++ struct device_attribute *attr, char *buf) \
++{ \
++ struct interfacekit *kit = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
++}
++
++#define input_attr(value) \
++ __ATTR(input##value, S_IRUGO, show_input##value, NULL)
++
++show_input(1);
++show_input(2);
++show_input(3);
++show_input(4);
++show_input(5);
++show_input(6);
++show_input(7);
++show_input(8);
++show_input(9);
++show_input(10);
++show_input(11);
++show_input(12);
++show_input(13);
++show_input(14);
++show_input(15);
++show_input(16);
++
++static struct device_attribute dev_input_attrs[] = {
++ input_attr(1), input_attr(2), input_attr(3), input_attr(4),
++ input_attr(5), input_attr(6), input_attr(7), input_attr(8),
++ input_attr(9), input_attr(10), input_attr(11), input_attr(12),
++ input_attr(13), input_attr(14), input_attr(15), input_attr(16)
++};
++
++#define show_sensor(value) \
++static ssize_t show_sensor##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct interfacekit *kit = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
++}
++
++#define sensor_attr(value) \
++ __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL)
++
++show_sensor(1);
++show_sensor(2);
++show_sensor(3);
++show_sensor(4);
++show_sensor(5);
++show_sensor(6);
++show_sensor(7);
++show_sensor(8);
++
++static struct device_attribute dev_sensor_attrs[] = {
++ sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4),
++ sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8)
++};
++
++static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++ struct usb_device *dev = interface_to_usbdev(intf);
++ struct usb_host_interface *interface;
++ struct usb_endpoint_descriptor *endpoint;
++ struct interfacekit *kit;
++ struct driver_interfacekit *ifkit;
++ int pipe, maxp, rc = -ENOMEM;
++ int bit, value, i;
++
++ ifkit = (struct driver_interfacekit *)id->driver_info;
++ if (!ifkit)
++ return -ENODEV;
++
++ interface = intf->cur_altsetting;
++ if (interface->desc.bNumEndpoints != 1)
++ return -ENODEV;
++
++ endpoint = &interface->endpoint[0].desc;
++ if (!usb_endpoint_dir_in(endpoint))
++ return -ENODEV;
++ /*
++ * bmAttributes
++ */
++ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
++
++ kit = kzalloc(sizeof(*kit), GFP_KERNEL);
++ if (!kit)
++ goto out;
++
++ kit->dev_no = -1;
++ kit->ifkit = ifkit;
++ kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma);
++ if (!kit->data)
++ goto out;
++
++ kit->irq = usb_alloc_urb(0, GFP_KERNEL);
++ if (!kit->irq)
++ goto out;
++
++ kit->udev = usb_get_dev(dev);
++ kit->intf = intf;
++ INIT_DELAYED_WORK(&kit->do_notify, do_notify);
++ INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit);
++ usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
++ maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
++ interfacekit_irq, kit, endpoint->bInterval);
++ kit->irq->transfer_dma = kit->data_dma;
++ kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++
++ usb_set_intfdata(intf, kit);
++
++ do {
++ bit = find_first_zero_bit(&device_no, sizeof(device_no));
++ value = test_and_set_bit(bit, &device_no);
++ } while(value);
++ kit->dev_no = bit;
++
++ kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
++ kit, "interfacekit%d", kit->dev_no);
++ if (IS_ERR(kit->dev)) {
++ rc = PTR_ERR(kit->dev);
++ kit->dev = NULL;
++ goto out;
++ }
++
++ if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
++ rc = -EIO;
++ goto out;
++ }
++
++ for (i=0; i<ifkit->outputs; i++ ) {
++ rc = device_create_file(kit->dev, &dev_output_attrs[i]);
++ if (rc)
++ goto out2;
++ }
++
++ for (i=0; i<ifkit->inputs; i++ ) {
++ rc = device_create_file(kit->dev, &dev_input_attrs[i]);
++ if (rc)
++ goto out3;
++ }
++
++ for (i=0; i<ifkit->sensors; i++ ) {
++ rc = device_create_file(kit->dev, &dev_sensor_attrs[i]);
++ if (rc)
++ goto out4;
++ }
++
++ if (ifkit->has_lcd) {
++ rc = device_create_file(kit->dev, &dev_attr_lcd);
++ if (rc)
++ goto out4;
++
++ }
++
++ dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
++ ifkit->sensors, ifkit->inputs, ifkit->outputs);
++
++ return 0;
++
++out4:
++ while (i-- > 0)
++ device_remove_file(kit->dev, &dev_sensor_attrs[i]);
++
++ i = ifkit->inputs;
++out3:
++ while (i-- > 0)
++ device_remove_file(kit->dev, &dev_input_attrs[i]);
++
++ i = ifkit->outputs;
++out2:
++ while (i-- > 0)
++ device_remove_file(kit->dev, &dev_output_attrs[i]);
++out:
++ if (kit) {
++ usb_free_urb(kit->irq);
++ if (kit->data)
++ usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
++ if (kit->dev)
++ device_unregister(kit->dev);
++ if (kit->dev_no >= 0)
++ clear_bit(kit->dev_no, &device_no);
++
++ kfree(kit);
++ }
++
++ return rc;
++}
++
++static void interfacekit_disconnect(struct usb_interface *interface)
++{
++ struct interfacekit *kit;
++ int i;
++
++ kit = usb_get_intfdata(interface);
++ usb_set_intfdata(interface, NULL);
++ if (!kit)
++ return;
++
++ usb_kill_urb(kit->irq);
++ usb_free_urb(kit->irq);
++ usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
++
++ cancel_delayed_work(&kit->do_notify);
++ cancel_delayed_work(&kit->do_resubmit);
++
++ for (i=0; i<kit->ifkit->outputs; i++)
++ device_remove_file(kit->dev, &dev_output_attrs[i]);
++
++ for (i=0; i<kit->ifkit->inputs; i++)
++ device_remove_file(kit->dev, &dev_input_attrs[i]);
++
++ for (i=0; i<kit->ifkit->sensors; i++)
++ device_remove_file(kit->dev, &dev_sensor_attrs[i]);
++
++ if (kit->ifkit->has_lcd) {
++ device_remove_file(kit->dev, &dev_attr_lcd);
++ remove_lcd_files(kit);
++ }
++
++ device_unregister(kit->dev);
++
++ dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
++ kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
++
++ usb_put_dev(kit->udev);
++ clear_bit(kit->dev_no, &device_no);
++
++ kfree(kit);
++}
++
++static struct usb_driver interfacekit_driver = {
++ .name = "phidgetkit",
++ .probe = interfacekit_probe,
++ .disconnect = interfacekit_disconnect,
++ .id_table = id_table
++};
++
++static int __init interfacekit_init(void)
++{
++ int retval = 0;
++
++ retval = usb_register(&interfacekit_driver);
++ if (retval)
++ err("usb_register failed. Error number %d", retval);
++
++ return retval;
++}
++
++static void __exit interfacekit_exit(void)
++{
++ usb_deregister(&interfacekit_driver);
++}
++
++module_init(interfacekit_init);
++module_exit(interfacekit_exit);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/usb/misc/phidgetmotorcontrol.c
+@@ -0,0 +1,465 @@
++/*
++ * USB Phidget MotorControl driver
++ *
++ * Copyright (C) 2006 Sean Young <sean@mess.org>
++ *
++ * This program 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++
++#include "phidget.h"
++
++#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
++#define DRIVER_DESC "USB PhidgetMotorControl Driver"
++
++#define USB_VENDOR_ID_GLAB 0x06c2
++#define USB_DEVICE_ID_MOTORCONTROL 0x0058
++
++#define URB_INT_SIZE 8
++
++static unsigned long device_no;
++
++struct motorcontrol {
++ struct usb_device *udev;
++ struct usb_interface *intf;
++ struct device *dev;
++ int dev_no;
++ u8 inputs[4];
++ s8 desired_speed[2];
++ s8 speed[2];
++ s16 _current[2];
++ s8 acceleration[2];
++ struct urb *irq;
++ unsigned char *data;
++ dma_addr_t data_dma;
++
++ struct delayed_work do_notify;
++ unsigned long input_events;
++ unsigned long speed_events;
++ unsigned long exceed_events;
++};
++
++static struct usb_device_id id_table[] = {
++ { USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_MOTORCONTROL) },
++ {}
++};
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static int set_motor(struct motorcontrol *mc, int motor)
++{
++ u8 *buffer;
++ int speed, speed2, acceleration;
++ int retval;
++
++ buffer = kzalloc(8, GFP_KERNEL);
++ if (!buffer) {
++ dev_err(&mc->intf->dev, "%s - out of memory\n", __func__);
++ return -ENOMEM;
++ }
++
++ acceleration = mc->acceleration[motor] * 10;
++ /* -127 <= speed <= 127 */
++ speed = (mc->desired_speed[motor] * 127) / 100;
++ /* -0x7300 <= speed2 <= 0x7300 */
++ speed2 = (mc->desired_speed[motor] * 230 * 128) / 100;
++
++ buffer[0] = motor;
++ buffer[1] = speed;
++ buffer[2] = acceleration >> 8;
++ buffer[3] = acceleration;
++ buffer[4] = speed2 >> 8;
++ buffer[5] = speed2;
++
++ retval = usb_control_msg(mc->udev,
++ usb_sndctrlpipe(mc->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
++
++ if (retval != 8)
++ dev_err(&mc->intf->dev, "usb_control_msg returned %d\n",
++ retval);
++ kfree(buffer);
++
++ return retval < 0 ? retval : 0;
++}
++
++static void motorcontrol_irq(struct urb *urb)
++{
++ struct motorcontrol *mc = urb->context;
++ unsigned char *buffer = mc->data;
++ int i, level;
++ int retval;
++ int status = urb->status;;
++
++ switch (status) {
++ case 0: /* success */
++ break;
++ case -ECONNRESET: /* unlink */
++ case -ENOENT:
++ case -ESHUTDOWN:
++ return;
++ /* -EPIPE: should clear the halt */
++ default: /* error */
++ goto resubmit;
++ }
++
++ /* digital inputs */
++ for (i=0; i<4; i++) {
++ level = (buffer[0] >> i) & 1;
++ if (mc->inputs[i] != level) {
++ mc->inputs[i] = level;
++ set_bit(i, &mc->input_events);
++ }
++ }
++
++ /* motor speed */
++ if (buffer[2] == 0) {
++ for (i=0; i<2; i++) {
++ level = ((s8)buffer[4+i]) * 100 / 127;
++ if (mc->speed[i] != level) {
++ mc->speed[i] = level;
++ set_bit(i, &mc->speed_events);
++ }
++ }
++ } else {
++ int index = buffer[3] & 1;
++
++ level = ((s8)buffer[4] << 8) | buffer[5];
++ level = level * 100 / 29440;
++ if (mc->speed[index] != level) {
++ mc->speed[index] = level;
++ set_bit(index, &mc->speed_events);
++ }
++
++ level = ((s8)buffer[6] << 8) | buffer[7];
++ mc->_current[index] = level * 100 / 1572;
++ }
++
++ if (buffer[1] & 1)
++ set_bit(0, &mc->exceed_events);
++
++ if (buffer[1] & 2)
++ set_bit(1, &mc->exceed_events);
++
++ if (mc->input_events || mc->exceed_events || mc->speed_events)
++ schedule_delayed_work(&mc->do_notify, 0);
++
++resubmit:
++ retval = usb_submit_urb(urb, GFP_ATOMIC);
++ if (retval)
++ dev_err(&mc->intf->dev,
++ "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
++ mc->udev->bus->bus_name,
++ mc->udev->devpath, retval);
++}
++
++static void do_notify(struct work_struct *work)
++{
++ struct motorcontrol *mc =
++ container_of(work, struct motorcontrol, do_notify.work);
++ int i;
++ char sysfs_file[8];
++
++ for (i=0; i<4; i++) {
++ if (test_and_clear_bit(i, &mc->input_events)) {
++ sprintf(sysfs_file, "input%d", i);
++ sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
++ }
++ }
++
++ for (i=0; i<2; i++) {
++ if (test_and_clear_bit(i, &mc->speed_events)) {
++ sprintf(sysfs_file, "speed%d", i);
++ sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
++ }
++ }
++
++ for (i=0; i<2; i++) {
++ if (test_and_clear_bit(i, &mc->exceed_events))
++ dev_warn(&mc->intf->dev,
++ "motor #%d exceeds 1.5 Amp current limit\n", i);
++ }
++}
++
++#define show_set_speed(value) \
++static ssize_t set_speed##value(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ int speed; \
++ int retval; \
++ \
++ if (sscanf(buf, "%d", &speed) < 1) \
++ return -EINVAL; \
++ \
++ if (speed < -100 || speed > 100) \
++ return -EINVAL; \
++ \
++ mc->desired_speed[value] = speed; \
++ \
++ retval = set_motor(mc, value); \
++ \
++ return retval ? retval : count; \
++} \
++ \
++static ssize_t show_speed##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", mc->speed[value]); \
++}
++
++#define speed_attr(value) \
++ __ATTR(speed##value, S_IWUGO | S_IRUGO, \
++ show_speed##value, set_speed##value)
++
++show_set_speed(0);
++show_set_speed(1);
++
++#define show_set_acceleration(value) \
++static ssize_t set_acceleration##value(struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ int acceleration; \
++ int retval; \
++ \
++ if (sscanf(buf, "%d", &acceleration) < 1) \
++ return -EINVAL; \
++ \
++ if (acceleration < 0 || acceleration > 100) \
++ return -EINVAL; \
++ \
++ mc->acceleration[value] = acceleration; \
++ \
++ retval = set_motor(mc, value); \
++ \
++ return retval ? retval : count; \
++} \
++ \
++static ssize_t show_acceleration##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", mc->acceleration[value]); \
++}
++
++#define acceleration_attr(value) \
++ __ATTR(acceleration##value, S_IWUGO | S_IRUGO, \
++ show_acceleration##value, set_acceleration##value)
++
++show_set_acceleration(0);
++show_set_acceleration(1);
++
++#define show_current(value) \
++static ssize_t show_current##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \
++}
++
++#define current_attr(value) \
++ __ATTR(current##value, S_IRUGO, show_current##value, NULL)
++
++show_current(0);
++show_current(1);
++
++#define show_input(value) \
++static ssize_t show_input##value(struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct motorcontrol *mc = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d\n", (int)mc->inputs[value]); \
++}
++
++#define input_attr(value) \
++ __ATTR(input##value, S_IRUGO, show_input##value, NULL)
++
++show_input(0);
++show_input(1);
++show_input(2);
++show_input(3);
++
++static struct device_attribute dev_attrs[] = {
++ input_attr(0),
++ input_attr(1),
++ input_attr(2),
++ input_attr(3),
++ speed_attr(0),
++ speed_attr(1),
++ acceleration_attr(0),
++ acceleration_attr(1),
++ current_attr(0),
++ current_attr(1)
++};
++
++static int motorcontrol_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++ struct usb_device *dev = interface_to_usbdev(intf);
++ struct usb_host_interface *interface;
++ struct usb_endpoint_descriptor *endpoint;
++ struct motorcontrol *mc;
++ int pipe, maxp, rc = -ENOMEM;
++ int bit, value, i;
++
++ interface = intf->cur_altsetting;
++ if (interface->desc.bNumEndpoints != 1)
++ return -ENODEV;
++
++ endpoint = &interface->endpoint[0].desc;
++ if (!usb_endpoint_dir_in(endpoint))
++ return -ENODEV;
++
++ /*
++ * bmAttributes
++ */
++ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
++
++ mc = kzalloc(sizeof(*mc), GFP_KERNEL);
++ if (!mc)
++ goto out;
++
++ mc->dev_no = -1;
++ mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma);
++ if (!mc->data)
++ goto out;
++
++ mc->irq = usb_alloc_urb(0, GFP_KERNEL);
++ if (!mc->irq)
++ goto out;
++
++ mc->udev = usb_get_dev(dev);
++ mc->intf = intf;
++ mc->acceleration[0] = mc->acceleration[1] = 10;
++ INIT_DELAYED_WORK(&mc->do_notify, do_notify);
++ usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data,
++ maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
++ motorcontrol_irq, mc, endpoint->bInterval);
++ mc->irq->transfer_dma = mc->data_dma;
++ mc->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++
++ usb_set_intfdata(intf, mc);
++
++ do {
++ bit = find_first_zero_bit(&device_no, sizeof(device_no));
++ value = test_and_set_bit(bit, &device_no);
++ } while(value);
++ mc->dev_no = bit;
++
++ mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
++ "motorcontrol%d", mc->dev_no);
++ if (IS_ERR(mc->dev)) {
++ rc = PTR_ERR(mc->dev);
++ mc->dev = NULL;
++ goto out;
++ }
++
++ if (usb_submit_urb(mc->irq, GFP_KERNEL)) {
++ rc = -EIO;
++ goto out;
++ }
++
++ for (i=0; i<ARRAY_SIZE(dev_attrs); i++) {
++ rc = device_create_file(mc->dev, &dev_attrs[i]);
++ if (rc)
++ goto out2;
++ }
++
++ dev_info(&intf->dev, "USB PhidgetMotorControl attached\n");
++
++ return 0;
++out2:
++ while (i-- > 0)
++ device_remove_file(mc->dev, &dev_attrs[i]);
++out:
++ if (mc) {
++ usb_free_urb(mc->irq);
++ if (mc->data)
++ usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma);
++ if (mc->dev)
++ device_unregister(mc->dev);
++ if (mc->dev_no >= 0)
++ clear_bit(mc->dev_no, &device_no);
++
++ kfree(mc);
++ }
++
++ return rc;
++}
++
++static void motorcontrol_disconnect(struct usb_interface *interface)
++{
++ struct motorcontrol *mc;
++ int i;
++
++ mc = usb_get_intfdata(interface);
++ usb_set_intfdata(interface, NULL);
++ if (!mc)
++ return;
++
++ usb_kill_urb(mc->irq);
++ usb_free_urb(mc->irq);
++ usb_buffer_free(mc->udev, URB_INT_SIZE, mc->data, mc->data_dma);
++
++ cancel_delayed_work(&mc->do_notify);
++
++ for (i=0; i<ARRAY_SIZE(dev_attrs); i++)
++ device_remove_file(mc->dev, &dev_attrs[i]);
++
++ device_unregister(mc->dev);
++
++ usb_put_dev(mc->udev);
++ clear_bit(mc->dev_no, &device_no);
++ kfree(mc);
++
++ dev_info(&interface->dev, "USB PhidgetMotorControl detached\n");
++}
++
++static struct usb_driver motorcontrol_driver = {
++ .name = "phidgetmotorcontrol",
++ .probe = motorcontrol_probe,
++ .disconnect = motorcontrol_disconnect,
++ .id_table = id_table
++};
++
++static int __init motorcontrol_init(void)
++{
++ int retval = 0;
++
++ retval = usb_register(&motorcontrol_driver);
++ if (retval)
++ err("usb_register failed. Error number %d", retval);
++
++ return retval;
++}
++
++static void __exit motorcontrol_exit(void)
++{
++ usb_deregister(&motorcontrol_driver);
++}
++
++module_init(motorcontrol_init);
++module_exit(motorcontrol_exit);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/usb/misc/phidgetservo.c
+@@ -0,0 +1,375 @@
++/*
++ * USB PhidgetServo driver 1.0
++ *
++ * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
++ *
++ * This program 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.
++ *
++ * This is a driver for the USB PhidgetServo version 2.0 and 3.0 servo
++ * controllers available at: http://www.phidgets.com/
++ *
++ * Note that the driver takes input as: degrees.minutes
++ *
++ * CAUTION: Generally you should use 0 < degrees < 180 as anything else
++ * is probably beyond the range of your servo and may damage it.
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++
++#include "phidget.h"
++
++#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
++#define DRIVER_DESC "USB PhidgetServo Driver"
++
++#define VENDOR_ID_GLAB 0x06c2
++#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038
++#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039
++
++#define VENDOR_ID_WISEGROUP 0x0925
++#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101
++#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104
++
++#define SERVO_VERSION_30 0x01
++#define SERVO_COUNT_QUAD 0x02
++
++static struct usb_device_id id_table[] = {
++ {
++ USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD),
++ .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD
++ },
++ {
++ USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI),
++ .driver_info = SERVO_VERSION_30
++ },
++ {
++ USB_DEVICE(VENDOR_ID_WISEGROUP,
++ VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD),
++ .driver_info = SERVO_COUNT_QUAD
++ },
++ {
++ USB_DEVICE(VENDOR_ID_WISEGROUP,
++ VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI),
++ .driver_info = 0
++ },
++ {}
++};
++
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static int unsigned long device_no;
++
++struct phidget_servo {
++ struct usb_device *udev;
++ struct device *dev;
++ int dev_no;
++ ulong type;
++ int pulse[4];
++ int degrees[4];
++ int minutes[4];
++};
++
++static int
++change_position_v30(struct phidget_servo *servo, int servo_no, int degrees,
++ int minutes)
++{
++ int retval;
++ unsigned char *buffer;
++
++ if (degrees < -23 || degrees > 362)
++ return -EINVAL;
++
++ buffer = kmalloc(6, GFP_KERNEL);
++ if (!buffer) {
++ dev_err(&servo->udev->dev, "%s - out of memory\n",
++ __func__);
++ return -ENOMEM;
++ }
++
++ /*
++ * pulse = 0 - 4095
++ * angle = 0 - 180 degrees
++ *
++ * pulse = angle * 10.6 + 243.8
++ */
++ servo->pulse[servo_no] = ((degrees*60 + minutes)*106 + 2438*60)/600;
++ servo->degrees[servo_no]= degrees;
++ servo->minutes[servo_no]= minutes;
++
++ /*
++ * The PhidgetServo v3.0 is controlled by sending 6 bytes,
++ * 4 * 12 bits for each servo.
++ *
++ * low = lower 8 bits pulse
++ * high = higher 4 bits pulse
++ *
++ * offset bits
++ * +---+-----------------+
++ * | 0 | low 0 |
++ * +---+--------+--------+
++ * | 1 | high 1 | high 0 |
++ * +---+--------+--------+
++ * | 2 | low 1 |
++ * +---+-----------------+
++ * | 3 | low 2 |
++ * +---+--------+--------+
++ * | 4 | high 3 | high 2 |
++ * +---+--------+--------+
++ * | 5 | low 3 |
++ * +---+-----------------+
++ */
++
++ buffer[0] = servo->pulse[0] & 0xff;
++ buffer[1] = (servo->pulse[0] >> 8 & 0x0f)
++ | (servo->pulse[1] >> 4 & 0xf0);
++ buffer[2] = servo->pulse[1] & 0xff;
++ buffer[3] = servo->pulse[2] & 0xff;
++ buffer[4] = (servo->pulse[2] >> 8 & 0x0f)
++ | (servo->pulse[3] >> 4 & 0xf0);
++ buffer[5] = servo->pulse[3] & 0xff;
++
++ dev_dbg(&servo->udev->dev,
++ "data: %02x %02x %02x %02x %02x %02x\n",
++ buffer[0], buffer[1], buffer[2],
++ buffer[3], buffer[4], buffer[5]);
++
++ retval = usb_control_msg(servo->udev,
++ usb_sndctrlpipe(servo->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2000);
++
++ kfree(buffer);
++
++ return retval;
++}
++
++static int
++change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
++ int minutes)
++{
++ int retval;
++ unsigned char *buffer;
++
++ if (degrees < -23 || degrees > 278)
++ return -EINVAL;
++
++ buffer = kmalloc(2, GFP_KERNEL);
++ if (!buffer) {
++ dev_err(&servo->udev->dev, "%s - out of memory\n",
++ __func__);
++ return -ENOMEM;
++ }
++
++ /*
++ * angle = 0 - 180 degrees
++ * pulse = angle + 23
++ */
++ servo->pulse[servo_no]= degrees + 23;
++ servo->degrees[servo_no]= degrees;
++ servo->minutes[servo_no]= 0;
++
++ /*
++ * The PhidgetServo v2.0 is controlled by sending two bytes. The
++ * first byte is the servo number xor'ed with 2:
++ *
++ * servo 0 = 2
++ * servo 1 = 3
++ * servo 2 = 0
++ * servo 3 = 1
++ *
++ * The second byte is the position.
++ */
++
++ buffer[0] = servo_no ^ 2;
++ buffer[1] = servo->pulse[servo_no];
++
++ dev_dbg(&servo->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]);
++
++ retval = usb_control_msg(servo->udev,
++ usb_sndctrlpipe(servo->udev, 0),
++ 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2000);
++
++ kfree(buffer);
++
++ return retval;
++}
++
++#define show_set(value) \
++static ssize_t set_servo##value (struct device *dev, \
++ struct device_attribute *attr, \
++ const char *buf, size_t count) \
++{ \
++ int degrees, minutes, retval; \
++ struct phidget_servo *servo = dev_get_drvdata(dev); \
++ \
++ minutes = 0; \
++ /* must at least convert degrees */ \
++ if (sscanf(buf, "%d.%d", &degrees, &minutes) < 1) { \
++ return -EINVAL; \
++ } \
++ \
++ if (minutes < 0 || minutes > 59) \
++ return -EINVAL; \
++ \
++ if (servo->type & SERVO_VERSION_30) \
++ retval = change_position_v30(servo, value, degrees, \
++ minutes); \
++ else \
++ retval = change_position_v20(servo, value, degrees, \
++ minutes); \
++ \
++ return retval < 0 ? retval : count; \
++} \
++ \
++static ssize_t show_servo##value (struct device *dev, \
++ struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct phidget_servo *servo = dev_get_drvdata(dev); \
++ \
++ return sprintf(buf, "%d.%02d\n", servo->degrees[value], \
++ servo->minutes[value]); \
++}
++
++#define servo_attr(value) \
++ __ATTR(servo##value, S_IWUGO | S_IRUGO, \
++ show_servo##value, set_servo##value)
++show_set(0);
++show_set(1);
++show_set(2);
++show_set(3);
++
++static struct device_attribute dev_attrs[] = {
++ servo_attr(0), servo_attr(1), servo_attr(2), servo_attr(3)
++};
++
++static int
++servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
++{
++ struct usb_device *udev = interface_to_usbdev(interface);
++ struct phidget_servo *dev;
++ int bit, value, rc;
++ int servo_count, i;
++
++ dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL);
++ if (dev == NULL) {
++ dev_err(&interface->dev, "%s - out of memory\n", __func__);
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ dev->udev = usb_get_dev(udev);
++ dev->type = id->driver_info;
++ dev->dev_no = -1;
++ usb_set_intfdata(interface, dev);
++
++ do {
++ bit = find_first_zero_bit(&device_no, sizeof(device_no));
++ value = test_and_set_bit(bit, &device_no);
++ } while (value);
++ dev->dev_no = bit;
++
++ dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
++ dev, "servo%d", dev->dev_no);
++ if (IS_ERR(dev->dev)) {
++ rc = PTR_ERR(dev->dev);
++ dev->dev = NULL;
++ goto out;
++ }
++
++ servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
++
++ for (i=0; i<servo_count; i++) {
++ rc = device_create_file(dev->dev, &dev_attrs[i]);
++ if (rc)
++ goto out2;
++ }
++
++ dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
++ servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
++
++ if (!(dev->type & SERVO_VERSION_30))
++ dev_info(&interface->dev,
++ "WARNING: v2.0 not tested! Please report if it works.\n");
++
++ return 0;
++out2:
++ while (i-- > 0)
++ device_remove_file(dev->dev, &dev_attrs[i]);
++out:
++ if (dev) {
++ if (dev->dev)
++ device_unregister(dev->dev);
++ if (dev->dev_no >= 0)
++ clear_bit(dev->dev_no, &device_no);
++
++ kfree(dev);
++ }
++
++ return rc;
++}
++
++static void
++servo_disconnect(struct usb_interface *interface)
++{
++ struct phidget_servo *dev;
++ int servo_count, i;
++
++ dev = usb_get_intfdata(interface);
++ usb_set_intfdata(interface, NULL);
++
++ if (!dev)
++ return;
++
++ servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
++
++ for (i=0; i<servo_count; i++)
++ device_remove_file(dev->dev, &dev_attrs[i]);
++
++ device_unregister(dev->dev);
++ usb_put_dev(dev->udev);
++
++ dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
++ servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
++
++ clear_bit(dev->dev_no, &device_no);
++ kfree(dev);
++}
++
++static struct usb_driver servo_driver = {
++ .name = "phidgetservo",
++ .probe = servo_probe,
++ .disconnect = servo_disconnect,
++ .id_table = id_table
++};
++
++static int __init
++phidget_servo_init(void)
++{
++ int retval;
++
++ retval = usb_register(&servo_driver);
++ if (retval)
++ err("usb_register failed. Error number %d", retval);
++
++ return retval;
++}
++
++static void __exit
++phidget_servo_exit(void)
++{
++ usb_deregister(&servo_driver);
++}
++
++module_init(phidget_servo_init);
++module_exit(phidget_servo_exit);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
diff --git a/series.conf b/series.conf
index 3ce3bc594f..6556114f49 100644
--- a/series.conf
+++ b/series.conf
@@ -102,6 +102,8 @@
patches.arch/s390-02-05-zcrypt-speed-cex2c.patch
patches.arch/s390-02-06-zcrypt-speed-cex3.patch
+ patches.arch/s390-03-qeth-hs-traffic-analyzer.patch
+
########################################################
# Scheduler / Core
########################################################
@@ -531,6 +533,8 @@
patches.fixes/scsi-check-host-lookup-failure
patches.drivers/aacraid-24701-update
patches.drivers/megaraid-04.12-update
+ patches.drivers/qla2xxx-8.03.01-k7-update
+ patches.drivers/lpfc-add-raywire-id
# Remaining SCSI patches (garloff)
patches.suse/scsi-error-test-unit-ready-timeout
@@ -676,6 +680,9 @@
########################################################
patches.suse/usb-storage-disable-delay.patch
+ # remove this for openSUSE 11.3, it is here only for SLE11 SP1 and later.
+ patches.suse/revert-usb-remove-phidget-drivers-from-kernel-tree.patch
+
########################################################
# I2C
########################################################
@@ -766,9 +773,45 @@
##########################################################
# AppArmor
##########################################################
- patches.apparmor/apparmor.diff
- patches.apparmor/ptrace_may_access-fix
patches.apparmor/security-default-lsm
+ patches.apparmor/apparmor-security-module
+ patches.apparmor/apparmor-correct-mapping-of-file-permissions
+ patches.apparmor/apparmor-turn-auditing-of-ptrace-on
+ patches.apparmor/apparmor-fix-operator-precidence-issue-in-as_path_link
+ patches.apparmor/apparmor-explicitly-include-header-files-to-allow-apparmor-to-build-on-powerpc
+ patches.apparmor/apparmor-ensure-apparmor-enabled-parmater-is-off-if-apparmor-fails-to-initialize
+ patches.apparmor/apparmor-fix-auditing-of-domain-transitions-to-include-target-profile-information
+ patches.apparmor/apparmor-fix-c99-violation
+ patches.apparmor/apparmor-fix-build-failure-on-ia64
+ patches.apparmor/apparmor-revert-reporting-of-create-to-write-permission
+ patches.apparmor/apparmor-fix-null-pointer-dereference-oops-in-profile-attachment
+ patches.apparmor/apparmor-fix-argument-size-missmatch-on-64-bit-builds
+ patches.apparmor/apparmor-fix-change_profile-failing-lpn401931
+ patches.apparmor/apparmor-fix-determination-of-forced-audit-messages
+ patches.apparmor/apparmor-fix-oops-in-auditing-of-the-policy-interface-offset
+ patches.apparmor/apparmor-fix-profile-attachment-for-regexp-based-profile-names
+ patches.apparmor/apparmor-return-the-correct-error-codes-on-profile-addition-removal
+ patches.apparmor/apparmor-fix-oops-in-profile-listing-and-display-full-list
+ patches.apparmor/apparmor-fix-mapping-of-pux-to-new-internal-permission-format
+ patches.apparmor/apparmor-fix-change_profile-failure
+ patches.apparmor/apparmor-fix-profile-namespace-removal
+ patches.apparmor/apparmor-fix-oops-when-auditing-the-addition-of-profile-namespace
+ patches.apparmor/apparmor-fix-mediation-of-created-paths-that-look-like-deleted-paths
+ patches.apparmor/apparmor-fix-file-auditing-when-quiet-is-used
+ patches.apparmor/apparmor-policy-load-and-replacement-can-fail-to-alloc-mem
+ patches.apparmor/apparmor-fix-failure-to-audit-change_hat-correctly
+
+ patches.apparmor/apparmor-allow-truncation-of-deleted-files
+ patches.apparmor/apparmor-fix-oops-after-profile-removal
+ patches.apparmor/apparmor-fix-oops-when-in-apparmor_bprm_set_creds
+ patches.apparmor/apparmor-fix-cap-audit_caching-preemption-disabling
+ patches.apparmor/apparmor-fix-refcounting-bug-causing-leak-of-creds-and-oops
+ patches.apparmor/apparmor-fix-leak-when-profile-transition-table-fails-unpack
+ patches.apparmor/apparmor-fully-close-race-condition-for-deleted-paths
+
+ patches.apparmor/apparmor-missing-unlock
+ patches.apparmor/ptrace_may_access-fix
+ patches.apparmor/apparmor-fix-security_ops-task_setrlimit-api-use
########################################################
# Address space layout randomization
diff --git a/supported.conf b/supported.conf
index 87747fbdb3..5090c82d2e 100644
--- a/supported.conf
+++ b/supported.conf
@@ -43,6 +43,7 @@
kernel/arch/s390/kvm/kvm
kernel/arch/x86/crypto/aes-i586 # Rijndael (AES) Cipher Algorithm (optimized for i586)
kernel/arch/x86/crypto/aes-x86_64
+ kernel/arch/x86/crypto/ghash-clmulni-intel external # fate #306883
kernel/arch/x86/crypto/salsa20-i586
kernel/arch/x86/crypto/salsa20-x86_64
kernel/arch/x86/crypto/twofish-i586
@@ -1343,6 +1344,7 @@
kernel/drivers/net/macvlan
kernel/drivers/net/mii # MII hardware support library
kernel/drivers/net/mlx4/mlx4_core
+ kernel/drivers/net/mlx4/mlx4_en
kernel/drivers/net/mv643xx_eth # gigabit Pegasos2, all chips share the same MAC
kernel/drivers/net/myri10ge/myri10ge
kernel/drivers/net/natsemi # National Semiconductor DP8381x series PCI Ethernet driver
@@ -1458,6 +1460,7 @@
kernel/drivers/net/via-velocity # VIA Networking Velocity Family Gigabit Ethernet Adapter Driver
kernel/drivers/net/virtio_net
+isa kernel/drivers/net/wan/c101
+- kernel/drivers/net/wan/cosa
- kernel/drivers/net/wan/dlci
- kernel/drivers/net/wan/dscc4
- kernel/drivers/net/wan/farsync
@@ -1483,25 +1486,14 @@
+isa kernel/drivers/net/wan/z85230
+isa kernel/drivers/net/wd
kernel/drivers/net/wireless/adm8211
-- kernel/drivers/net/wireless/airo_cs # Support for Cisco/Aironet 802.11 wireless ethernet cards. This is the module that links the PCMCIA card with the airo module.
-- kernel/drivers/net/wireless/airo # Support for Cisco/Aironet 802.11 wireless ethernet cards. Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.
kernel/drivers/net/wireless/airport
kernel/drivers/net/wireless/ath/ath
kernel/drivers/net/wireless/ath5k/ath5k
kernel/drivers/net/wireless/ath9k/ath9k
+ kernel/drivers/net/wireless/atmel # Support for Atmel at76c50x 802.11 wireless ethernet cards.
kernel/drivers/net/wireless/atmel_cs # Support for Atmel at76c50x 802.11 wireless ethernet cards.
kernel/drivers/net/wireless/atmel_pci # Support for Atmel at76c50x 802.11 wireless ethernet cards.
- kernel/drivers/net/wireless/atmel # Support for Atmel at76c50x 802.11 wireless ethernet cards.
-- kernel/drivers/net/wireless/b43/b43
-- kernel/drivers/net/wireless/b43legacy/b43legacy
kernel/drivers/net/wireless/hermes # Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller
-- kernel/drivers/net/wireless/hostap/hostap_cs
-- kernel/drivers/net/wireless/hostap/hostap # Host AP common routines
-- kernel/drivers/net/wireless/hostap/hostap_pci # Support for Intersil Prism2.5-based 802.11 wireless LAN PCI cards.
-- kernel/drivers/net/wireless/hostap/hostap_plx # Support for Intersil Prism2-based 802.11 wireless LAN cards (PLX).
-+external kernel/drivers/net/wireless/ipw2x00/ipw2100
-+external kernel/drivers/net/wireless/ipw2x00/ipw2200
-+external kernel/drivers/net/wireless/ipw2x00/libipw
kernel/drivers/net/wireless/iwlwifi/iwl3945
kernel/drivers/net/wireless/iwlwifi/iwlagn
kernel/drivers/net/wireless/iwlwifi/iwlcore
@@ -1511,8 +1503,8 @@
kernel/drivers/net/wireless/libertas/usb8xxx
kernel/drivers/net/wireless/mac80211_hwsim
kernel/drivers/net/wireless/netwave_cs
- kernel/drivers/net/wireless/orinoco_cs # Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards
kernel/drivers/net/wireless/orinoco # Driver for Lucent Orinoco, Prism II based and similar wireless cards
+ kernel/drivers/net/wireless/orinoco_cs # Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards
kernel/drivers/net/wireless/orinoco_nortel # Nortel specific Orinoco driver
kernel/drivers/net/wireless/orinoco_pci # Driver for wireless LAN cards using direct PCI interface
kernel/drivers/net/wireless/orinoco_plx # Driver for wireless LAN cards using the PLX9052 PCI bridge
@@ -1521,25 +1513,49 @@
kernel/drivers/net/wireless/p54/p54pci
kernel/drivers/net/wireless/p54/p54usb
kernel/drivers/net/wireless/prism54/prism54 # The Prism54 802.11 Wireless LAN adapter
-- kernel/drivers/net/wireless/ray_cs # Raylink/WebGear wireless LAN driver
kernel/drivers/net/wireless/rndis_wlan
+ kernel/drivers/net/wireless/rtl8180
+ kernel/drivers/net/wireless/rtl8187
+ kernel/drivers/net/wireless/strip # Starmode Radio IP (STRIP) Device Driver
+ kernel/drivers/net/wireless/zd1201
+ kernel/drivers/net/wireless/zd1211rw/zd1211rw
++external kernel/drivers/net/wireless/ipw2x00/ipw2100
++external kernel/drivers/net/wireless/ipw2x00/ipw2200
++external kernel/drivers/net/wireless/ipw2x00/libipw
++isa kernel/drivers/net/wireless/wavelan
++review kernel/drivers/net/wireless/spectrum_cs # Driver for 802.11b cards using RAM-loadable Symbol firmwar
+- kernel/drivers/net/wireless/airo # Support for Cisco/Aironet 802.11 wireless ethernet cards. Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.
+- kernel/drivers/net/wireless/airo_cs # Support for Cisco/Aironet 802.11 wireless ethernet cards. This is the module that links the PCMCIA card with the airo module.
+- kernel/drivers/net/wireless/arlan
+- kernel/drivers/net/wireless/at76c50x-usb
+- kernel/drivers/net/wireless/b43/b43
+- kernel/drivers/net/wireless/b43legacy/b43legacy
+- kernel/drivers/net/wireless/hostap/hostap # Host AP common routines
+- kernel/drivers/net/wireless/hostap/hostap_cs
+- kernel/drivers/net/wireless/hostap/hostap_pci # Support for Intersil Prism2.5-based 802.11 wireless LAN PCI cards.
+- kernel/drivers/net/wireless/hostap/hostap_plx # Support for Intersil Prism2-based 802.11 wireless LAN cards (PLX).
+- kernel/drivers/net/wireless/iwmc3200wifi/iwmc3200wifi
+- kernel/drivers/net/wireless/libertas/libertas_spi
+- kernel/drivers/net/wireless/libertas_tf/libertas_tf
+- kernel/drivers/net/wireless/libertas_tf/libertas_tf_usb
+- kernel/drivers/net/wireless/mwl8k
+- kernel/drivers/net/wireless/p54/p54spi
+- kernel/drivers/net/wireless/ray_cs # Raylink/WebGear wireless LAN driver
- kernel/drivers/net/wireless/rt2x00/rt2400pci
- kernel/drivers/net/wireless/rt2x00/rt2500pci
- kernel/drivers/net/wireless/rt2x00/rt2500usb
+- kernel/drivers/net/wireless/rt2x00/rt2800usb
- kernel/drivers/net/wireless/rt2x00/rt2x00lib
- kernel/drivers/net/wireless/rt2x00/rt2x00pci
- kernel/drivers/net/wireless/rt2x00/rt2x00usb
- kernel/drivers/net/wireless/rt2x00/rt61pci
- kernel/drivers/net/wireless/rt2x00/rt73usb
- kernel/drivers/net/wireless/rtl8180
- kernel/drivers/net/wireless/rtl8187
-+review kernel/drivers/net/wireless/spectrum_cs # Driver for 802.11b cards using RAM-loadable Symbol firmwar
- kernel/drivers/net/wireless/strip # Starmode Radio IP (STRIP) Device Driver
-+isa kernel/drivers/net/wireless/wavelan
- kernel/drivers/net/wireless/wavelan_cs
+- kernel/drivers/net/wireless/wl12xx/wl1251
+- kernel/drivers/net/wireless/wl12xx/wl1251_sdio
+- kernel/drivers/net/wireless/wl12xx/wl1251_spi
+- kernel/drivers/net/wireless/wl12xx/wl1271
- kernel/drivers/net/wireless/wl3501_cs # Planet wl3501 wireless driver
- kernel/drivers/net/wireless/zd1201
- kernel/drivers/net/wireless/zd1211rw/zd1211rw
kernel/drivers/net/yellowfin # Packet Engines Yellowfin G-NIC Gigabit Ethernet driver
+isa kernel/drivers/net/znet
kernel/drivers/parport/parport
@@ -1558,6 +1574,7 @@
kernel/drivers/pci/hotplug/pci_hotplug # PCI Hot Plug PCI Core
kernel/drivers/pci/hotplug/sgi_hotplug # SGI's PCI Hotplug controller Driver
kernel/drivers/pci/hotplug/shpchp # Standard Hot Plug PCI Controller Driver
+ kernel/drivers/pci/pcie/aer/aer_inject # fate #306815
kernel/drivers/pcmcia/i82092
+isa kernel/drivers/pcmcia/i82365
kernel/drivers/pcmcia/pcmcia
@@ -2462,8 +2479,12 @@
kernel/net/sunrpc/xprtrdma/svcrdma
kernel/net/sunrpc/xprtrdma/xprtrdma
- kernel/net/wanrouter/wanrouter
+- kernel/net/wimax/wimax
kernel/net/wireless/cfg80211
kernel/net/wireless/lib80211
+ kernel/net/wireless/lib80211_crypt_ccmp
+ kernel/net/wireless/lib80211_crypt_tkip
+ kernel/net/wireless/lib80211_crypt_wep
- kernel/net/x25/x25 # The X.25 Packet Layer network layer protocol
kernel/net/xfrm/xfrm_ipcomp
kernel/net/xfrm/xfrm_user