Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Nov 2018 01:25:17 +0000 (18:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Nov 2018 01:25:17 +0000 (18:25 -0700)
Pull x86 fixes from Ingo Molnar:
 "A number of fixes and some late updates:

   - make in_compat_syscall() behavior on x86-32 similar to other
     platforms, this touches a number of generic files but is not
     intended to impact non-x86 platforms.

   - objtool fixes

   - PAT preemption fix

   - paravirt fixes/cleanups

   - cpufeatures updates for new instructions

   - earlyprintk quirk

   - make microcode version in sysfs world-readable (it is already
     world-readable in procfs)

   - minor cleanups and fixes"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  compat: Cleanup in_compat_syscall() callers
  x86/compat: Adjust in_compat_syscall() to generic code under !COMPAT
  objtool: Support GCC 9 cold subfunction naming scheme
  x86/numa_emulation: Fix uniform-split numa emulation
  x86/paravirt: Remove unused _paravirt_ident_32
  x86/mm/pat: Disable preemption around __flush_tlb_all()
  x86/paravirt: Remove GPL from pv_ops export
  x86/traps: Use format string with panic() call
  x86: Clean up 'sizeof x' => 'sizeof(x)'
  x86/cpufeatures: Enumerate MOVDIR64B instruction
  x86/cpufeatures: Enumerate MOVDIRI instruction
  x86/earlyprintk: Add a force option for pciserial device
  objtool: Support per-function rodata sections
  x86/microcode: Make revision and processor flags world-readable

590 files changed:
Documentation/ABI/testing/sysfs-platform-lg-laptop [new file with mode: 0644]
Documentation/admin-guide/cgroup-v2.rst
Documentation/crypto/asymmetric-keys.txt
Documentation/devicetree/bindings/arm/cpu-capacity.txt
Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt [deleted file]
Documentation/devicetree/bindings/display/panel/simple-panel.txt
Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
Documentation/filesystems/overlayfs.txt
Documentation/filesystems/porting
Documentation/filesystems/vfs.txt
Documentation/kbuild/makefiles.txt
Documentation/laptops/lg-laptop.rst [new file with mode: 0644]
Documentation/networking/ice.rst
Documentation/networking/ip-sysctl.txt
Documentation/process/index.rst
Documentation/process/programming-language.rst [new file with mode: 0644]
Documentation/security/keys/core.rst
Documentation/security/self-protection.rst
Documentation/sysctl/kernel.txt
Documentation/x86/x86_64/mm.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/arm/boot/dts/stm32mp157c.dtsi
arch/arm/configs/multi_v7_defconfig
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/plat-orion/mpp.c
arch/arm64/Makefile
arch/arm64/configs/defconfig
arch/arm64/include/asm/percpu.h
arch/arm64/kernel/crash_dump.c
arch/arm64/kernel/probes/kprobes.c
arch/arm64/kernel/process.c
arch/arm64/mm/dma-mapping.c
arch/csky/Kconfig.debug
arch/csky/Makefile
arch/csky/boot/dts/Makefile
arch/mips/Makefile
arch/mips/vdso/Makefile
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/dts/fsl/t2080rdb.dts
arch/powerpc/boot/dts/mpc885ads.dts
arch/powerpc/include/asm/code-patching.h
arch/powerpc/include/asm/mmu-8xx.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/process.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/emulate.c
arch/powerpc/mm/8xx_mmu.c
arch/powerpc/perf/8xx-pmu.c
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/pseries/lparcfg.c
arch/powerpc/xmon/Makefile
arch/riscv/configs/defconfig
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/systbls_64.S
arch/x86/Kconfig
arch/x86/entry/calling.h
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/entry/entry_64_compat.S
arch/xtensa/Kconfig
arch/xtensa/boot/Makefile
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/mm/init.c
block/bfq-cgroup.c
block/bfq-iosched.c
block/bio.c
block/blk-cgroup.c
block/blk-core.c
block/blk-iolatency.c
block/blk-merge.c
block/blk-sysfs.c
block/blk-throttle.c
block/bounce.c
block/cfq-iosched.c
crypto/asymmetric_keys/Kconfig
crypto/asymmetric_keys/Makefile
crypto/asymmetric_keys/asym_tpm.c [new file with mode: 0644]
crypto/asymmetric_keys/asymmetric_keys.h
crypto/asymmetric_keys/asymmetric_type.c
crypto/asymmetric_keys/pkcs7_parser.c
crypto/asymmetric_keys/pkcs8.asn1 [new file with mode: 0644]
crypto/asymmetric_keys/pkcs8_parser.c [new file with mode: 0644]
crypto/asymmetric_keys/public_key.c
crypto/asymmetric_keys/signature.c
crypto/asymmetric_keys/tpm.asn1 [new file with mode: 0644]
crypto/asymmetric_keys/tpm_parser.c [new file with mode: 0644]
crypto/asymmetric_keys/x509_cert_parser.c
crypto/rsa-pkcs1pad.c
drivers/acpi/device_pm.c
drivers/auxdisplay/panel.c
drivers/block/brd.c
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_receiver.c
drivers/block/loop.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/nbd.c
drivers/edac/Kconfig
drivers/edac/skx_edac.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/dcdbas.c [deleted file]
drivers/firmware/dcdbas.h [deleted file]
drivers/firmware/dell_rbu.c [deleted file]
drivers/fsi/fsi-sbefifo.c
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/os_types.h
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h
drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
drivers/gpu/drm/bridge/ti-sn65dsi86.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/panel/panel-simple.c
drivers/hid/Kconfig
drivers/hid/hid-asus.c
drivers/i2c/i2c-core-base.c
drivers/irqchip/irq-mvebu-sei.c
drivers/isdn/mISDN/l1oip_core.c
drivers/md/raid0.c
drivers/misc/lkdtm/Makefile
drivers/misc/lkdtm/core.c
drivers/misc/lkdtm/lkdtm.h
drivers/misc/lkdtm/stackleak.c [new file with mode: 0644]
drivers/misc/vmw_vmci/vmci_queue_pair.c
drivers/net/bonding/bond_netlink.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h
drivers/net/ethernet/intel/Kconfig
drivers/net/ethernet/intel/fm10k/fm10k_iov.c
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/fm10k/fm10k_type.h
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/igb/igb_ptp.c
drivers/net/ethernet/intel/ixgbe/Makefile
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbevf/Makefile
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/mvpp2/mvpp2.h
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/reg.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
drivers/nvme/host/fc.c
drivers/nvme/host/pci.c
drivers/nvme/target/io-cmd-file.c
drivers/of/base.c
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/acerhdf.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dcdbas.c [new file with mode: 0644]
drivers/platform/x86/dcdbas.h [new file with mode: 0644]
drivers/platform/x86/dell-smbios-smm.c
drivers/platform/x86/dell_rbu.c [new file with mode: 0644]
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-hid.c
drivers/platform/x86/intel-rst.c
drivers/platform/x86/intel-smartconnect.c
drivers/platform/x86/intel-wmi-thunderbolt.c
drivers/platform/x86/intel_atomisp2_pm.c [new file with mode: 0644]
drivers/platform/x86/intel_bxtwc_tmu.c
drivers/platform/x86/intel_cht_int33fe.c
drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
drivers/platform/x86/intel_int0002_vgpio.c
drivers/platform/x86/intel_ips.c
drivers/platform/x86/intel_ips.h
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/intel_mid_powerbtn.c
drivers/platform/x86/intel_mid_thermal.c
drivers/platform/x86/intel_oaktrail.c
drivers/platform/x86/intel_pmc_core.c
drivers/platform/x86/intel_pmc_core.h
drivers/platform/x86/intel_pmc_ipc.c
drivers/platform/x86/intel_punit_ipc.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/intel_scu_ipcutil.c
drivers/platform/x86/intel_telemetry_core.c
drivers/platform/x86/intel_telemetry_debugfs.c
drivers/platform/x86/intel_telemetry_pltdrv.c
drivers/platform/x86/intel_turbo_max_3.c
drivers/platform/x86/lg-laptop.c [new file with mode: 0644]
drivers/platform/x86/mlx-platform.c
drivers/platform/x86/touchscreen_dmi.c
drivers/platform/x86/wmi.c
drivers/pwm/Kconfig
drivers/pwm/pwm-lpss-platform.c
drivers/pwm/pwm-lpss.c
drivers/pwm/pwm-lpss.h
drivers/pwm/pwm-rcar.c
drivers/pwm/pwm-renesas-tpu.c
drivers/pwm/pwm-tegra.c
drivers/pwm/sysfs.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/Kconfig
drivers/scsi/aha152x.c
drivers/scsi/mvsas/mv_sas.c
drivers/scsi/pcmcia/aha152x_core.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mr.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_nx2.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_target.c
drivers/soc/ti/knav_qmss.h
drivers/soc/ti/knav_qmss_acc.c
drivers/soc/ti/knav_qmss_queue.c
drivers/target/iscsi/iscsi_target_util.c
drivers/target/target_core_alua.c
drivers/target/target_core_file.c
drivers/target/target_core_transport.c
drivers/usb/usbip/usbip_common.c
drivers/vhost/scsi.c
drivers/vhost/vhost.c
drivers/virtio/virtio_balloon.c
drivers/xen/pvcalls-back.c
fs/9p/vfs_addr.c
fs/9p/vfs_dir.c
fs/9p/xattr.c
fs/afs/Kconfig
fs/afs/Makefile
fs/afs/addr_list.c
fs/afs/afs.h
fs/afs/cache.c
fs/afs/callback.c
fs/afs/cell.c
fs/afs/cmservice.c
fs/afs/dir.c
fs/afs/dynroot.c
fs/afs/file.c
fs/afs/flock.c
fs/afs/fs_probe.c [new file with mode: 0644]
fs/afs/fsclient.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/mntpt.c
fs/afs/proc.c
fs/afs/protocol_yfs.h [new file with mode: 0644]
fs/afs/rotate.c
fs/afs/rxrpc.c
fs/afs/security.c
fs/afs/server.c
fs/afs/server_list.c
fs/afs/super.c
fs/afs/vl_list.c [new file with mode: 0644]
fs/afs/vl_probe.c [new file with mode: 0644]
fs/afs/vl_rotate.c [new file with mode: 0644]
fs/afs/vlclient.c
fs/afs/volume.c
fs/afs/write.c
fs/afs/xattr.c
fs/afs/yfsclient.c [new file with mode: 0644]
fs/bfs/inode.c
fs/block_dev.c
fs/btrfs/ctree.h
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/buffer.c
fs/ceph/file.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_spnego.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smbdirect.c
fs/cifs/trace.h
fs/cifs/transport.c
fs/direct-io.c
fs/dlm/lowcomms.c
fs/exofs/super.c
fs/ext4/ext4.h
fs/ext4/ialloc.c
fs/ext4/namei.c
fs/ext4/page-io.c
fs/fuse/file.c
fs/ioctl.c
fs/iomap.c
fs/nfs/nfs4file.c
fs/nfsd/vfs.c
fs/ntfs/namei.c
fs/ocfs2/buffer_head_io.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dir.c
fs/ocfs2/dlmglue.c
fs/ocfs2/file.c
fs/ocfs2/journal.c
fs/ocfs2/move_extents.c
fs/ocfs2/refcounttree.c
fs/ocfs2/refcounttree.h
fs/ocfs2/stackglue.c
fs/ocfs2/stackglue.h
fs/orangefs/inode.c
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/file.c
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
fs/overlayfs/util.c
fs/proc/base.c
fs/read_write.c
fs/splice.c
fs/xfs/xfs_file.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_reflink.h
include/crypto/asym_tpm_subtype.h [new file with mode: 0644]
include/crypto/public_key.h
include/drm/drm_connector.h
include/keys/asymmetric-subtype.h
include/keys/trusted.h [new file with mode: 0644]
include/linux/adxl.h
include/linux/avf/virtchnl.h
include/linux/bio.h
include/linux/blk-cgroup.h
include/linux/blk_types.h
include/linux/bpf_verifier.h
include/linux/cgroup.h
include/linux/compiler-clang.h
include/linux/compiler-gcc.h
include/linux/compiler-intel.h
include/linux/compiler.h
include/linux/compiler_attributes.h [new file with mode: 0644]
include/linux/compiler_types.h
include/linux/fs.h
include/linux/gfp.h
include/linux/inetdevice.h
include/linux/key-type.h
include/linux/keyctl.h [new file with mode: 0644]
include/linux/mempolicy.h
include/linux/notifier.h
include/linux/platform_data/x86/asus-wmi.h [new file with mode: 0644]
include/linux/sched.h
include/linux/stackleak.h [new file with mode: 0644]
include/linux/uio.h
include/linux/writeback.h
include/net/af_unix.h
include/trace/events/afs.h
include/uapi/linux/keyctl.h
include/uapi/linux/perf_event.h
include/uapi/linux/virtio_balloon.h
kernel/Makefile
kernel/bpf/verifier.c
kernel/cgroup/cgroup.c
kernel/configs/kvm_guest.config
kernel/events/core.c
kernel/fork.c
kernel/irq/matrix.c
kernel/kexec_file.c
kernel/stackleak.c [new file with mode: 0644]
kernel/sysctl.c
kernel/trace/blktrace.c
kernel/trace/trace_printk.c
lib/iov_iter.c
mm/filemap.c
mm/huge_memory.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/page_io.c
mm/page_poison.c
mm/percpu.c
mm/shmem.c
net/9p/client.c
net/9p/trans_virtio.c
net/bluetooth/6lowpan.c
net/bluetooth/a2mp.c
net/bluetooth/smp.c
net/ceph/messenger.c
net/core/rtnetlink.c
net/ipv4/igmp.c
net/ipv4/tcp_bpf.c
net/netfilter/ipvs/ip_vs_sync.c
net/openvswitch/flow_netlink.c
net/sctp/associola.c
net/sctp/socket.c
net/smc/smc_clc.c
net/socket.c
net/sunrpc/svcsock.c
net/sunrpc/xprtsock.c
net/tipc/topsrv.c
net/tls/tls_device.c
net/tls/tls_sw.c
net/xfrm/Kconfig
scripts/Kbuild.include
scripts/Makefile.extrawarn
scripts/Makefile.gcc-plugins
scripts/gcc-plugins/Kconfig
scripts/gcc-plugins/stackleak_plugin.c [new file with mode: 0644]
scripts/kconfig/Makefile
scripts/kconfig/conf.c
scripts/kconfig/merge_config.sh
security/apparmor/apparmorfs.c
security/apparmor/file.c
security/apparmor/include/cred.h
security/apparmor/include/net.h
security/apparmor/include/policy.h
security/apparmor/include/secid.h
security/apparmor/lib.c
security/apparmor/lsm.c
security/apparmor/net.c
security/apparmor/policy.c
security/apparmor/policy_unpack.c
security/apparmor/secid.c
security/keys/Makefile
security/keys/compat.c
security/keys/internal.h
security/keys/keyctl.c
security/keys/keyctl_pkey.c [new file with mode: 0644]
security/keys/trusted.c
security/keys/trusted.h [deleted file]
sound/firewire/amdtp-stream.c
sound/firewire/dice/dice.c
sound/pci/ca0106/ca0106.h
tools/arch/arm64/include/uapi/asm/unistd.h
tools/arch/powerpc/include/uapi/asm/kvm.h
tools/arch/s390/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/include/uapi/asm-generic/unistd.h
tools/include/uapi/linux/fs.h [new file with mode: 0644]
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/mman.h
tools/include/uapi/linux/netlink.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/sound/asound.h
tools/lib/bpf/libbpf.c
tools/lib/subcmd/parse-options.c
tools/lib/subcmd/parse-options.h
tools/perf/Documentation/build-xed.txt [new file with mode: 0644]
tools/perf/Documentation/intel-pt.txt
tools/perf/Documentation/itrace.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-top.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile.perf
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
tools/perf/arch/sparc/Makefile
tools/perf/arch/sparc/annotate/instructions.c [new file with mode: 0644]
tools/perf/builtin-record.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/check-headers.sh
tools/perf/perf.h
tools/perf/scripts/python/call-graph-from-sql.py [deleted file]
tools/perf/scripts/python/export-to-postgresql.py
tools/perf/scripts/python/export-to-sqlite.py
tools/perf/scripts/python/exported-sql-viewer.py [new file with mode: 0755]
tools/perf/trace/beauty/Build
tools/perf/trace/beauty/beauty.h
tools/perf/trace/beauty/clone.c
tools/perf/trace/beauty/drm_ioctl.sh
tools/perf/trace/beauty/eventfd.c
tools/perf/trace/beauty/fcntl.c
tools/perf/trace/beauty/flock.c
tools/perf/trace/beauty/futex_op.c
tools/perf/trace/beauty/futex_val3.c
tools/perf/trace/beauty/ioctl.c
tools/perf/trace/beauty/kcmp.c
tools/perf/trace/beauty/kcmp_type.sh
tools/perf/trace/beauty/kvm_ioctl.sh
tools/perf/trace/beauty/madvise_behavior.sh
tools/perf/trace/beauty/mmap.c
tools/perf/trace/beauty/mmap_flags.sh [new file with mode: 0755]
tools/perf/trace/beauty/mode_t.c
tools/perf/trace/beauty/mount_flags.c [new file with mode: 0644]
tools/perf/trace/beauty/mount_flags.sh [new file with mode: 0755]
tools/perf/trace/beauty/msg_flags.c
tools/perf/trace/beauty/open_flags.c
tools/perf/trace/beauty/perf_event_open.c
tools/perf/trace/beauty/perf_ioctl.sh
tools/perf/trace/beauty/pid.c
tools/perf/trace/beauty/pkey_alloc.c
tools/perf/trace/beauty/pkey_alloc_access_rights.sh
tools/perf/trace/beauty/prctl.c
tools/perf/trace/beauty/prctl_option.sh
tools/perf/trace/beauty/sched_policy.c
tools/perf/trace/beauty/seccomp.c
tools/perf/trace/beauty/signum.c
tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
tools/perf/trace/beauty/sockaddr.c
tools/perf/trace/beauty/socket.c
tools/perf/trace/beauty/socket_ipproto.sh
tools/perf/trace/beauty/socket_type.c
tools/perf/trace/beauty/statx.c
tools/perf/trace/beauty/vhost_virtio_ioctl.sh
tools/perf/trace/beauty/waitid_options.c
tools/perf/util/annotate.c
tools/perf/util/auxtrace.c
tools/perf/util/auxtrace.h
tools/perf/util/cs-etm.c
tools/perf/util/env.h
tools/perf/util/event.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/genelf.h
tools/perf/util/header.c
tools/perf/util/header.h
tools/perf/util/intel-bts.c
tools/perf/util/intel-pt.c
tools/perf/util/machine.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.l
tools/perf/util/symbol-elf.c
tools/perf/util/symbol.h
tools/perf/util/thread-stack.c
tools/perf/util/thread-stack.h
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/unwind-libdw.c
tools/testing/selftests/bpf/flow_dissector_load.c
tools/testing/selftests/bpf/test_skb_cgroup_id.sh
tools/testing/selftests/bpf/test_sock_addr.sh
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh
tools/testing/selftests/powerpc/cache_shape/Makefile
tools/testing/selftests/powerpc/pmu/ebb/Makefile
tools/testing/selftests/powerpc/ptrace/Makefile
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
tools/testing/selftests/powerpc/security/Makefile
tools/testing/selftests/powerpc/security/rfi_flush.c
tools/testing/selftests/powerpc/signal/Makefile
tools/testing/selftests/powerpc/switch_endian/Makefile
tools/testing/selftests/powerpc/utils.c

diff --git a/Documentation/ABI/testing/sysfs-platform-lg-laptop b/Documentation/ABI/testing/sysfs-platform-lg-laptop
new file mode 100644 (file)
index 0000000..cf47749
--- /dev/null
@@ -0,0 +1,35 @@
+What:          /sys/devices/platform/lg-laptop/reader_mode
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control reader mode. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/lg-laptop/fn_lock
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control FN lock mode. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/lg-laptop/battery_care_limit
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Maximal battery charge level. Accepted values are 80 or 100.
+
+What:          /sys/devices/platform/lg-laptop/fan_mode
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control fan mode. 1 for performance mode, 0 for silent mode.
+
+What:          /sys/devices/platform/lg-laptop/usb_charge
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control USB port charging when device is turned off.
+        1 means on, 0 means off.
index 8384c681a4b2e0cb88595b0e95eb6660ab5d7857..476722b7b6367ca38bf0e3263f3e132b515dcfd6 100644 (file)
@@ -1879,10 +1879,8 @@ following two functions.
 
   wbc_init_bio(@wbc, @bio)
        Should be called for each bio carrying writeback data and
-       associates the bio with the inode's owner cgroup and the
-       corresponding request queue.  This must be called after
-       a queue (device) has been associated with the bio and
-       before submission.
+       associates the bio with the inode's owner cgroup.  Can be
+       called anytime between bio allocation and submission.
 
   wbc_account_io(@wbc, @page, @bytes)
        Should be called for each data segment being written out.
@@ -1901,7 +1899,7 @@ the configuration, the bio may be executed at a lower priority and if
 the writeback session is holding shared resources, e.g. a journal
 entry, may lead to priority inversion.  There is no one easy solution
 for the problem.  Filesystems can try to work around specific problem
-cases by skipping wbc_init_bio() or using bio_associate_create_blkg()
+cases by skipping wbc_init_bio() or using bio_associate_blkcg()
 directly.
 
 
index 5969bf42562a8752535f3183de6a9b66fa07985b..8763866b11cfd0f6af865ed67d8ba6db75a48b60 100644 (file)
@@ -183,6 +183,10 @@ and looks like the following:
 
                void (*describe)(const struct key *key, struct seq_file *m);
                void (*destroy)(void *payload);
+               int (*query)(const struct kernel_pkey_params *params,
+                            struct kernel_pkey_query *info);
+               int (*eds_op)(struct kernel_pkey_params *params,
+                             const void *in, void *out);
                int (*verify_signature)(const struct key *key,
                                        const struct public_key_signature *sig);
        };
@@ -207,12 +211,22 @@ There are a number of operations defined by the subtype:
      asymmetric key will look after freeing the fingerprint and releasing the
      reference on the subtype module.
 
- (3) verify_signature().
+ (3) query().
 
-     Optional.  These are the entry points for the key usage operations.
-     Currently there is only the one defined.  If not set, the caller will be
-     given -ENOTSUPP.  The subtype may do anything it likes to implement an
-     operation, including offloading to hardware.
+     Mandatory.  This is a function for querying the capabilities of a key.
+
+ (4) eds_op().
+
+     Optional.  This is the entry point for the encryption, decryption and
+     signature creation operations (which are distinguished by the operation ID
+     in the parameter struct).  The subtype may do anything it likes to
+     implement an operation, including offloading to hardware.
+
+ (5) verify_signature().
+
+     Optional.  This is the entry point for signature verification.  The
+     subtype may do anything it likes to implement an operation, including
+     offloading to hardware.
 
 
 ==========================
@@ -234,6 +248,8 @@ Examples of blob formats for which parsers could be implemented include:
  - X.509 ASN.1 stream.
  - Pointer to TPM key.
  - Pointer to UEFI key.
+ - PKCS#8 private key [RFC 5208].
+ - PKCS#5 encrypted private key [RFC 2898].
 
 During key instantiation each parser in the list is tried until one doesn't
 return -EBADMSG.
index 9b5685a1d15d9821efb9dd6d34a29ae1f788e31f..84262cdb8d29ae3f95ef94f6e7b9900897774c17 100644 (file)
@@ -59,9 +59,11 @@ mhz values (normalized w.r.t. the highest value found while parsing the DT).
 ===========================================
 
 Example 1 (ARM 64-bit, 6-cpu system, two clusters):
-capacities-dmips-mhz are scaled w.r.t. 1024 (cpu@0 and cpu@1)
-supposing cluster0@max-freq=1100 and custer1@max-freq=850,
-final capacities are 1024 for cluster0 and 446 for cluster1
+The capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024)
+are 1024 and 578 for cluster0 and cluster1. Further normalization
+is done by the operating system based on cluster0@max-freq=1100 and
+custer1@max-freq=850, final capacities are 1024 for cluster0 and
+446 for cluster1 (576*850/1100).
 
 cpus {
        #address-cells = <2>;
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
new file mode 100644 (file)
index 0000000..513f034
--- /dev/null
@@ -0,0 +1,22 @@
+Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
+
+Required properties:
+- compatible: should be "innolux,p120zdg-bf1"
+- power-supply: regulator to provide the supply voltage
+
+Optional properties:
+- enable-gpios: GPIO pin to enable or disable the panel
+- backlight: phandle of the backlight device attached to the panel
+- no-hpd: If HPD isn't hooked up; add this property.
+
+Example:
+       panel_edp: panel-edp {
+               compatible = "innolux,p120zdg-bf1";
+               enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
+               power-supply = <&pm8916_l2>;
+               backlight = <&backlight>;
+               no-hpd;
+       };
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt b/Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt
deleted file mode 100644 (file)
index a9b3526..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Innolux TV123WAM 12.3 inch eDP 2K display panel
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
-
-Required properties:
-- compatible: should be "innolux,tv123wam"
-- power-supply: regulator to provide the supply voltage
-
-Optional properties:
-- enable-gpios: GPIO pin to enable or disable the panel
-- backlight: phandle of the backlight device attached to the panel
-
-Example:
-       panel_edp: panel-edp {
-               compatible = "innolux,tv123wam";
-               enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
-               power-supply = <&pm8916_l2>;
-               backlight = <&backlight>;
-       };
index 45a457ad38f0f078eed709424e1e237ebcfe420f..b2b872c710f24d69996eb3cb4922ba8dd3915a14 100644 (file)
@@ -11,6 +11,9 @@ Optional properties:
 - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
 - enable-gpios: GPIO pin to enable or disable the panel
 - backlight: phandle of the backlight device attached to the panel
+- no-hpd: This panel is supposed to communicate that it's ready via HPD
+  (hot plug detect) signal, but the signal isn't hooked up so we should
+  hardcode the max delay from the panel spec when powering up the panel.
 
 Example:
 
index 091c8dfd322910e14712d4a818e9879538abf3d9..b245363d6d60a0b6a42a6a4d675e1219faedc03d 100644 (file)
@@ -3,6 +3,7 @@
 Required properties:
 - compatible :
   - "fsl,imx7ulp-lpi2c" for LPI2C compatible with the one integrated on i.MX7ULP soc
+  - "fsl,imx8qxp-lpi2c" for LPI2C compatible with the one integrated on i.MX8QXP soc
 - reg : address and length of the lpi2c master registers
 - interrupts : lpi2c interrupt
 - clocks : lpi2c clock specifier
index 06a363d9ccef9069124ae813bfb449d8cab182c7..b9a1d7402128b95437341b1e2d16d516fddfa114 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
   for da850  - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap";
   for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap";
   for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap";
+  for am654  - compatible = "ti,am654-ecap", "ti,am3352-ecap";
 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
   the cells format. The PWM channel index ranges from 0 to 4. The only third
   cell flag supported by this binding is PWM_POLARITY_INVERTED.
index e1ef6afbe3a74a89d9040b9d6642cd2c22aa2a0c..7f31fe7e209348ceb04a471e08be0f60b4fff65d 100644 (file)
@@ -3,7 +3,9 @@
 Required Properties:
 - compatible: should be "renesas,pwm-rcar" and one of the following.
  - "renesas,pwm-r8a7743": for RZ/G1M
+ - "renesas,pwm-r8a7744": for RZ/G1N
  - "renesas,pwm-r8a7745": for RZ/G1E
+ - "renesas,pwm-r8a774a1": for RZ/G2M
  - "renesas,pwm-r8a7778": for R-Car M1A
  - "renesas,pwm-r8a7779": for R-Car H1
  - "renesas,pwm-r8a7790": for R-Car H2
@@ -12,6 +14,8 @@ Required Properties:
  - "renesas,pwm-r8a7795": for R-Car H3
  - "renesas,pwm-r8a7796": for R-Car M3-W
  - "renesas,pwm-r8a77965": for R-Car M3-N
+ - "renesas,pwm-r8a77970": for R-Car V3M
+ - "renesas,pwm-r8a77980": for R-Car V3H
  - "renesas,pwm-r8a77990": for R-Car E3
  - "renesas,pwm-r8a77995": for R-Car D3
 - reg: base address and length of the registers block for the PWM.
index d53a16715da6ac33dea19a4a66ad38310feacc95..848a92b53d810eeb055544cbb037a38a54e05371 100644 (file)
@@ -2,13 +2,19 @@
 
 Required Properties:
 
-  - compatible: should be one of the following.
+  - compatible: must contain one or more of the following:
     - "renesas,tpu-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible PWM controller.
     - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller.
     - "renesas,tpu-r8a7743": for R8A7743 (RZ/G1M) compatible PWM controller.
+    - "renesas,tpu-r8a7744": for R8A7744 (RZ/G1N) compatible PWM controller.
     - "renesas,tpu-r8a7745": for R8A7745 (RZ/G1E) compatible PWM controller.
     - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller.
-    - "renesas,tpu": for generic R-Car and RZ/G1 TPU PWM controller.
+    - "renesas,tpu-r8a77970": for R8A77970 (R-Car V3M) compatible PWM
+                             controller.
+    - "renesas,tpu-r8a77980": for R8A77980 (R-Car V3H) compatible PWM
+                             controller.
+    - "renesas,tpu": for the generic TPU PWM controller; this is a fallback for
+                    the entries listed above.
 
   - reg: Base address and length of each memory resource used by the PWM
     controller hardware module.
index 51c136c821bfb0a190e7daa67ebdc2e6faaf878b..eef7d9d259e8570d102be8c7f1641158950262c2 100644 (file)
@@ -286,6 +286,12 @@ pointed by REDIRECT. This should not be possible on local system as setting
 "trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
 for untrusted layers like from a pen drive.
 
+Note: redirect_dir={off|nofollow|follow(*)} conflicts with metacopy=on, and
+results in an error.
+
+(*) redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
+given.
+
 Sharing and copying layers
 --------------------------
 
index 321d74b73937231d0dbf927ec89689082d14fcce..cf43bc4dbf319b4f642feaea0608d3bd07b075d6 100644 (file)
@@ -623,6 +623,11 @@ in your dentry operations instead.
        On success you get a new struct file sharing the mount/dentry with the
        original, on failure - ERR_PTR().
 --
+[mandatory]
+       ->clone_file_range() and ->dedupe_file_range have been replaced with
+       ->remap_file_range().  See Documentation/filesystems/vfs.txt for more
+       information.
+--
 [recommended]
        ->lookup() instances doing an equivalent of
                if (IS_ERR(inode))
index a6c6a8af48a296cf9b7197c8f065370814efd90d..5f71a252e2e0f52b17c4fb6076baa57ae34e1ec4 100644 (file)
@@ -883,8 +883,9 @@ struct file_operations {
        unsigned (*mmap_capabilities)(struct file *);
 #endif
        ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int);
-       int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
-       int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
+       loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in,
+                                  struct file *file_out, loff_t pos_out,
+                                  loff_t len, unsigned int remap_flags);
        int (*fadvise)(struct file *, loff_t, loff_t, int);
 };
 
@@ -960,11 +961,18 @@ otherwise noted.
 
   copy_file_range: called by the copy_file_range(2) system call.
 
-  clone_file_range: called by the ioctl(2) system call for FICLONERANGE and
-       FICLONE commands.
-
-  dedupe_file_range: called by the ioctl(2) system call for FIDEDUPERANGE
-       command.
+  remap_file_range: called by the ioctl(2) system call for FICLONERANGE and
+       FICLONE and FIDEDUPERANGE commands to remap file ranges.  An
+       implementation should remap len bytes at pos_in of the source file into
+       the dest file at pos_out.  Implementations must handle callers passing
+       in len == 0; this means "remap to the end of the source file".  The
+       return value should the number of bytes remapped, or the usual
+       negative error code if errors occurred before any bytes were remapped.
+       The remap_flags parameter accepts REMAP_FILE_* flags.  If
+       REMAP_FILE_DEDUP is set then the implementation must only remap if the
+       requested file ranges have identical contents.  If REMAP_CAN_SHORTEN is
+       set, the caller is ok with the implementation shortening the request
+       length to satisfy alignment or EOF requirements (or any other reason).
 
   fadvise: possibly called by the fadvise64() system call.
 
index 7b6a2b2bdc98db2e794a261ff7be17dc3df0ae26..8da26c6dd886a9d9006184f4d9d5c5cf43e71b2e 100644 (file)
@@ -537,21 +537,6 @@ more details, with real examples.
        The third parameter may be a text as in this example, but it may also
        be an expanded variable or a macro.
 
-    cc-fullversion
-       cc-fullversion is useful when the exact version of gcc is needed.
-       One typical use-case is when a specific GCC version is broken.
-       cc-fullversion points out a more specific version than cc-version does.
-
-       Example:
-               #arch/powerpc/Makefile
-               $(Q)if test "$(cc-fullversion)" = "040200" ; then \
-                       echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \
-                       false ; \
-               fi
-
-       In this example for a specific GCC version the build will error out
-       explaining to the user why it stops.
-
     cc-cross-prefix
        cc-cross-prefix is used to check if there exists a $(CC) in path with
        one of the listed prefixes. The first prefix where there exist a
diff --git a/Documentation/laptops/lg-laptop.rst b/Documentation/laptops/lg-laptop.rst
new file mode 100644 (file)
index 0000000..e486fe7
--- /dev/null
@@ -0,0 +1,81 @@
+.. SPDX-License-Identifier: GPL-2.0+
+LG Gram laptop extra features
+=============================
+
+By Matan Ziv-Av <matan@svgalib.org>
+
+
+Hotkeys
+-------
+
+The following FN keys are ignored by the kernel without this driver:
+- FN-F1 (LG control panel)   - Generates F15
+- FN-F5 (Touchpad toggle)    - Generates F13
+- FN-F6 (Airplane mode)      - Generates RFKILL
+- FN-F8 (Keyboard backlight) - Generates F16.
+  This key also changes keyboard backlight mode.
+- FN-F9 (Reader mode)        - Generates F14
+
+The rest of the FN key work without a need for a special driver.
+
+
+Reader mode
+-----------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/reader_mode disables/enables
+reader mode. In this mode the screen colors change (blue color reduced),
+and the reader mode indicator LED (on F9 key) turns on.
+
+
+FN Lock
+-------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/fn_lock disables/enables
+FN lock.
+
+
+Battery care limit
+------------------
+
+Writing 80/100 to /sys/devices/platform/lg-laptop/battery_care_limit
+sets the maximum capacity to charge the battery. Limiting the charge
+reduces battery capacity loss over time.
+
+This value is reset to 100 when the kernel boots.
+
+
+Fan mode
+--------
+
+Writing 1/0 to /sys/devices/platform/lg-laptop/fan_mode disables/enables
+the fan silent mode.
+
+
+USB charge
+----------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/usb_charge disables/enables
+charging another device from the USB port while the device is turned off.
+
+This value is reset to 0 when the kernel boots.
+
+
+LEDs
+~~~~
+
+The are two LED devices supported by the driver:
+
+Keyboard backlight
+------------------
+
+A led device named kbd_led controls the keyboard backlight. There are three
+lighting level: off (0), low (127) and high (255).
+
+The keyboard backlight is also controlled by the key combination FN-F8
+which cycles through those levels.
+
+
+Touchpad indicator LED
+----------------------
+
+On the F5 key. Controlled by led device names tpad_led.
index 1e4948c9e9897afb3ac0231a2c1c76ea310968ee..4d118b827bbb7ed1f9e7c221ae1c10ceee7bb779 100644 (file)
@@ -20,7 +20,7 @@ Enabling the driver
 The driver is enabled via the standard kernel configuration system,
 using the make command::
 
-  make oldconfig/silentoldconfig/menuconfig/etc.
+  make oldconfig/menuconfig/etc.
 
 The driver is located in the menu structure at:
 
index 163b5ff1073cd0a852d9ed32e06c599cefcfdd75..32b21571adfeb5bc4b5aec9b25ec14ecebc8e0e5 100644 (file)
@@ -316,6 +316,17 @@ tcp_frto - INTEGER
 
        By default it's enabled with a non-zero value. 0 disables F-RTO.
 
+tcp_fwmark_accept - BOOLEAN
+       If set, incoming connections to listening sockets that do not have a
+       socket mark will set the mark of the accepting socket to the fwmark of
+       the incoming SYN packet. This will cause all packets on that connection
+       (starting from the first SYNACK) to be sent with that fwmark. The
+       listening socket's mark is unchanged. Listening sockets that already
+       have a fwmark set via setsockopt(SOL_SOCKET, SO_MARK, ...) are
+       unaffected.
+
+       Default: 0
+
 tcp_invalid_ratelimit - INTEGER
        Limit the maximal rate for sending duplicate acknowledgments
        in response to incoming TCP packets that are for an existing
index 757808526d9a8bbb2197dc54a532ea766e5c4be3..878ebfda7eeff378a2fee48e3b361aa6b3587896 100644 (file)
@@ -25,6 +25,7 @@ Below are the essential guides that every developer should read.
    code-of-conduct-interpretation
    development-process
    submitting-patches
+   programming-language
    coding-style
    maintainer-pgp-guide
    email-clients
diff --git a/Documentation/process/programming-language.rst b/Documentation/process/programming-language.rst
new file mode 100644 (file)
index 0000000..e5f5f06
--- /dev/null
@@ -0,0 +1,45 @@
+.. _programming_language:
+
+Programming Language
+====================
+
+The kernel is written in the C programming language [c-language]_.
+More precisely, the kernel is typically compiled with ``gcc`` [gcc]_
+under ``-std=gnu89`` [gcc-c-dialect-options]_: the GNU dialect of ISO C90
+(including some C99 features).
+
+This dialect contains many extensions to the language [gnu-extensions]_,
+and many of them are used within the kernel as a matter of course.
+
+There is some support for compiling the kernel with ``clang`` [clang]_
+and ``icc`` [icc]_ for several of the architectures, although at the time
+of writing it is not completed, requiring third-party patches.
+
+Attributes
+----------
+
+One of the common extensions used throughout the kernel are attributes
+[gcc-attribute-syntax]_. Attributes allow to introduce
+implementation-defined semantics to language entities (like variables,
+functions or types) without having to make significant syntactic changes
+to the language (e.g. adding a new keyword) [n2049]_.
+
+In some cases, attributes are optional (i.e. a compiler not supporting them
+should still produce proper code, even if it is slower or does not perform
+as many compile-time checks/diagnostics).
+
+The kernel defines pseudo-keywords (e.g. ``__pure``) instead of using
+directly the GNU attribute syntax (e.g. ``__attribute__((__pure__))``)
+in order to feature detect which ones can be used and/or to shorten the code.
+
+Please refer to ``include/linux/compiler_attributes.h`` for more information.
+
+.. [c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
+.. [gcc] https://gcc.gnu.org
+.. [clang] https://clang.llvm.org
+.. [icc] https://software.intel.com/en-us/c-compilers
+.. [gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
+.. [gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
+.. [gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
+.. [n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
+
index 9ce7256c6edba8b605e9928a42159d717f6d7cf5..9521c4207f014d11f4edd33bcefdc788d0299d6a 100644 (file)
@@ -859,6 +859,7 @@ The keyctl syscall functions are:
      and either the buffer length or the OtherInfo length exceeds the
      allowed length.
 
+
   *  Restrict keyring linkage::
 
        long keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring,
@@ -890,6 +891,116 @@ The keyctl syscall functions are:
      applicable to the asymmetric key type.
 
 
+  *  Query an asymmetric key::
+
+       long keyctl(KEYCTL_PKEY_QUERY,
+                   key_serial_t key_id, unsigned long reserved,
+                   struct keyctl_pkey_query *info);
+
+     Get information about an asymmetric key.  The information is returned in
+     the keyctl_pkey_query struct::
+
+       __u32   supported_ops;
+       __u32   key_size;
+       __u16   max_data_size;
+       __u16   max_sig_size;
+       __u16   max_enc_size;
+       __u16   max_dec_size;
+       __u32   __spare[10];
+
+     ``supported_ops`` contains a bit mask of flags indicating which ops are
+     supported.  This is constructed from a bitwise-OR of::
+
+       KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+     ``key_size`` indicated the size of the key in bits.
+
+     ``max_*_size`` indicate the maximum sizes in bytes of a blob of data to be
+     signed, a signature blob, a blob to be encrypted and a blob to be
+     decrypted.
+
+     ``__spare[]`` must be set to 0.  This is intended for future use to hand
+     over one or more passphrases needed unlock a key.
+
+     If successful, 0 is returned.  If the key is not an asymmetric key,
+     EOPNOTSUPP is returned.
+
+
+  *  Encrypt, decrypt, sign or verify a blob using an asymmetric key::
+
+       long keyctl(KEYCTL_PKEY_ENCRYPT,
+                   const struct keyctl_pkey_params *params,
+                   const char *info,
+                   const void *in,
+                   void *out);
+
+       long keyctl(KEYCTL_PKEY_DECRYPT,
+                   const struct keyctl_pkey_params *params,
+                   const char *info,
+                   const void *in,
+                   void *out);
+
+       long keyctl(KEYCTL_PKEY_SIGN,
+                   const struct keyctl_pkey_params *params,
+                   const char *info,
+                   const void *in,
+                   void *out);
+
+       long keyctl(KEYCTL_PKEY_VERIFY,
+                   const struct keyctl_pkey_params *params,
+                   const char *info,
+                   const void *in,
+                   const void *in2);
+
+     Use an asymmetric key to perform a public-key cryptographic operation a
+     blob of data.  For encryption and verification, the asymmetric key may
+     only need the public parts to be available, but for decryption and signing
+     the private parts are required also.
+
+     The parameter block pointed to by params contains a number of integer
+     values::
+
+       __s32           key_id;
+       __u32           in_len;
+       __u32           out_len;
+       __u32           in2_len;
+
+     ``key_id`` is the ID of the asymmetric key to be used.  ``in_len`` and
+     ``in2_len`` indicate the amount of data in the in and in2 buffers and
+     ``out_len`` indicates the size of the out buffer as appropriate for the
+     above operations.
+
+     For a given operation, the in and out buffers are used as follows::
+
+       Operation ID            in,in_len       out,out_len     in2,in2_len
+       ======================= =============== =============== ===============
+       KEYCTL_PKEY_ENCRYPT     Raw data        Encrypted data  -
+       KEYCTL_PKEY_DECRYPT     Encrypted data  Raw data        -
+       KEYCTL_PKEY_SIGN        Raw data        Signature       -
+       KEYCTL_PKEY_VERIFY      Raw data        -               Signature
+
+     ``info`` is a string of key=value pairs that supply supplementary
+     information.  These include:
+
+       ``enc=<encoding>`` The encoding of the encrypted/signature blob.  This
+                       can be "pkcs1" for RSASSA-PKCS1-v1.5 or
+                       RSAES-PKCS1-v1.5; "pss" for "RSASSA-PSS"; "oaep" for
+                       "RSAES-OAEP".  If omitted or is "raw", the raw output
+                       of the encryption function is specified.
+
+       ``hash=<algo>`` If the data buffer contains the output of a hash
+                       function and the encoding includes some indication of
+                       which hash function was used, the hash function can be
+                       specified with this, eg. "hash=sha256".
+
+     The ``__spare[]`` space in the parameter block must be set to 0.  This is
+     intended, amongst other things, to allow the passing of passphrases
+     required to unlock a key.
+
+     If successful, encrypt, decrypt and sign all return the amount of data
+     written into the output buffer.  Verification returns 0 on success.
+
+
 Kernel Services
 ===============
 
@@ -1483,6 +1594,112 @@ The structure has a number of fields, some of which are mandatory:
      attempted key link operation. If there is no match, -EINVAL is returned.
 
 
+  *  ``int (*asym_eds_op)(struct kernel_pkey_params *params,
+                         const void *in, void *out);``
+     ``int (*asym_verify_signature)(struct kernel_pkey_params *params,
+                                   const void *in, const void *in2);``
+
+     These methods are optional.  If provided the first allows a key to be
+     used to encrypt, decrypt or sign a blob of data, and the second allows a
+     key to verify a signature.
+
+     In all cases, the following information is provided in the params block::
+
+       struct kernel_pkey_params {
+               struct key      *key;
+               const char      *encoding;
+               const char      *hash_algo;
+               char            *info;
+               __u32           in_len;
+               union {
+                       __u32   out_len;
+                       __u32   in2_len;
+               };
+               enum kernel_pkey_operation op : 8;
+       };
+
+     This includes the key to be used; a string indicating the encoding to use
+     (for instance, "pkcs1" may be used with an RSA key to indicate
+     RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding or "raw" if no encoding);
+     the name of the hash algorithm used to generate the data for a signature
+     (if appropriate); the sizes of the input and output (or second input)
+     buffers; and the ID of the operation to be performed.
+
+     For a given operation ID, the input and output buffers are used as
+     follows::
+
+       Operation ID            in,in_len       out,out_len     in2,in2_len
+       ======================= =============== =============== ===============
+       kernel_pkey_encrypt     Raw data        Encrypted data  -
+       kernel_pkey_decrypt     Encrypted data  Raw data        -
+       kernel_pkey_sign        Raw data        Signature       -
+       kernel_pkey_verify      Raw data        -               Signature
+
+     asym_eds_op() deals with encryption, decryption and signature creation as
+     specified by params->op.  Note that params->op is also set for
+     asym_verify_signature().
+
+     Encrypting and signature creation both take raw data in the input buffer
+     and return the encrypted result in the output buffer.  Padding may have
+     been added if an encoding was set.  In the case of signature creation,
+     depending on the encoding, the padding created may need to indicate the
+     digest algorithm - the name of which should be supplied in hash_algo.
+
+     Decryption takes encrypted data in the input buffer and returns the raw
+     data in the output buffer.  Padding will get checked and stripped off if
+     an encoding was set.
+
+     Verification takes raw data in the input buffer and the signature in the
+     second input buffer and checks that the one matches the other.  Padding
+     will be validated.  Depending on the encoding, the digest algorithm used
+     to generate the raw data may need to be indicated in hash_algo.
+
+     If successful, asym_eds_op() should return the number of bytes written
+     into the output buffer.  asym_verify_signature() should return 0.
+
+     A variety of errors may be returned, including EOPNOTSUPP if the operation
+     is not supported; EKEYREJECTED if verification fails; ENOPKG if the
+     required crypto isn't available.
+
+
+  *  ``int (*asym_query)(const struct kernel_pkey_params *params,
+                        struct kernel_pkey_query *info);``
+
+     This method is optional.  If provided it allows information about the
+     public or asymmetric key held in the key to be determined.
+
+     The parameter block is as for asym_eds_op() and co. but in_len and out_len
+     are unused.  The encoding and hash_algo fields should be used to reduce
+     the returned buffer/data sizes as appropriate.
+
+     If successful, the following information is filled in::
+
+       struct kernel_pkey_query {
+               __u32           supported_ops;
+               __u32           key_size;
+               __u16           max_data_size;
+               __u16           max_sig_size;
+               __u16           max_enc_size;
+               __u16           max_dec_size;
+       };
+
+     The supported_ops field will contain a bitmask indicating what operations
+     are supported by the key, including encryption of a blob, decryption of a
+     blob, signing a blob and verifying the signature on a blob.  The following
+     constants are defined for this::
+
+       KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+     The key_size field is the size of the key in bits.  max_data_size and
+     max_sig_size are the maximum raw data and signature sizes for creation and
+     verification of a signature; max_enc_size and max_dec_size are the maximum
+     raw data and signature sizes for encryption and decryption.  The
+     max_*_size fields are measured in bytes.
+
+     If successful, 0 will be returned.  If the key doesn't support this,
+     EOPNOTSUPP will be returned.
+
+
 Request-Key Callback Service
 ============================
 
index e1ca698e000639720e9c718ec28613177cad189e..f584fb74b4ff2852eead1a46df316f14d3aeef69 100644 (file)
@@ -302,11 +302,11 @@ sure structure holes are cleared.
 Memory poisoning
 ----------------
 
-When releasing memory, it is best to poison the contents (clear stack on
-syscall return, wipe heap memory on a free), to avoid reuse attacks that
-rely on the old contents of memory. This frustrates many uninitialized
-variable attacks, stack content exposures, heap content exposures, and
-use-after-free attacks.
+When releasing memory, it is best to poison the contents, to avoid reuse
+attacks that rely on the old contents of memory. E.g., clear stack on a
+syscall return (``CONFIG_GCC_PLUGIN_STACKLEAK``), wipe heap memory on a
+free. This frustrates many uninitialized variable attacks, stack content
+exposures, heap content exposures, and use-after-free attacks.
 
 Destination tracking
 --------------------
index 37a679501ddc68bc0ab26c58444794c0d30c8f40..1b8775298cf7a0223c04aa7098cf1d1e4d24fefd 100644 (file)
@@ -89,6 +89,7 @@ show up in /proc/sys/kernel:
 - shmmni
 - softlockup_all_cpu_backtrace
 - soft_watchdog
+- stack_erasing
 - stop-a                      [ SPARC only ]
 - sysrq                       ==> Documentation/admin-guide/sysrq.rst
 - sysctl_writes_strict
@@ -987,6 +988,23 @@ detect a hard lockup condition.
 
 ==============================================================
 
+stack_erasing
+
+This parameter can be used to control kernel stack erasing at the end
+of syscalls for kernels built with CONFIG_GCC_PLUGIN_STACKLEAK.
+
+That erasing reduces the information which kernel stack leak bugs
+can reveal and blocks some uninitialized stack variable attacks.
+The tradeoff is the performance impact: on a single CPU system kernel
+compilation sees a 1% slowdown, other systems and workloads may vary.
+
+  0: kernel stack erasing is disabled, STACKLEAK_METRICS are not updated.
+
+  1: kernel stack erasing is enabled (default), it is performed before
+     returning to the userspace at the end of syscalls.
+
+==============================================================
+
 tainted:
 
 Non-zero if the kernel has been tainted. Numeric values, which can be
index 702898633b0007a1e50670fd05c7c24d58123c6c..73aaaa3da4369e39b41bf360b24b820061a15df9 100644 (file)
@@ -146,3 +146,6 @@ Their order is preserved but their base will be offset early at boot time.
 Be very careful vs. KASLR when changing anything here. The KASLR address
 range must not overlap with anything except the KASAN shadow area, which is
 correct as KASAN disables KASLR.
+
+For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB
+hole: ffffffffffff4111
index 1c0f771b859ec24b6123efc7a511525613d86199..f4855974f325063c1e5fea88d9d755ce75ee3b66 100644 (file)
@@ -376,7 +376,7 @@ F:  drivers/platform/x86/i2c-multi-instantiate.c
 ACPI PMIC DRIVERS
 M:     "Rafael J. Wysocki" <rjw@rjwysocki.net>
 M:     Len Brown <lenb@kernel.org>
-R:     Andy Shevchenko <andy@infradead.org>
+R:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 R:     Mika Westerberg <mika.westerberg@linux.intel.com>
 L:     linux-acpi@vger.kernel.org
 Q:     https://patchwork.kernel.org/project/linux-acpi/list/
@@ -3737,6 +3737,11 @@ L:       platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     drivers/platform/x86/compal-laptop.c
 
+COMPILER ATTRIBUTES
+M:     Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
+S:     Maintained
+F:     include/linux/compiler_attributes.h
+
 CONEXANT ACCESSRUNNER USB DRIVER
 L:     accessrunner-general@lists.sourceforge.net
 W:     http://accessrunner.sourceforge.net/
@@ -4207,6 +4212,12 @@ M:       Pali Rohár <pali.rohar@gmail.com>
 S:     Maintained
 F:     drivers/platform/x86/dell-rbtn.*
 
+DELL REMOTE BIOS UPDATE DRIVER
+M:     Stuart Hayes <stuart.w.hayes@gmail.com>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     drivers/platform/x86/dell_rbu.c
+
 DELL LAPTOP SMM DRIVER
 M:     Pali Rohár <pali.rohar@gmail.com>
 S:     Maintained
@@ -4214,10 +4225,11 @@ F:      drivers/hwmon/dell-smm-hwmon.c
 F:     include/uapi/linux/i8k.h
 
 DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
-M:     Doug Warzecha <Douglas_Warzecha@dell.com>
+M:     Stuart Hayes <stuart.w.hayes@gmail.com>
+L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     Documentation/dcdbas.txt
-F:     drivers/firmware/dcdbas.*
+F:     drivers/platform/x86/dcdbas.*
 
 DELL WMI NOTIFICATIONS DRIVER
 M:     Matthew Garrett <mjg59@srcf.ucam.org>
@@ -5871,6 +5883,14 @@ L:       linux-i2c@vger.kernel.org
 S:     Maintained
 F:     drivers/i2c/busses/i2c-cpm.c
 
+FREESCALE IMX LPI2C DRIVER
+M:     Dong Aisheng <aisheng.dong@nxp.com>
+L:     linux-i2c@vger.kernel.org
+L:     linux-imx@nxp.com
+S:     Maintained
+F:     drivers/i2c/busses/i2c-imx-lpi2c.c
+F:     Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
+
 FREESCALE IMX / MXC FEC DRIVER
 M:     Fugang Duan <fugang.duan@nxp.com>
 L:     netdev@vger.kernel.org
@@ -7347,6 +7367,12 @@ L:       alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
 F:     sound/soc/intel/
 
+INTEL ATOMISP2 DUMMY / POWER-MANAGEMENT DRIVER
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     drivers/platform/x86/intel_atomisp2_pm.c
+
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
 M:     Artur Paszkiewicz <artur.paszkiewicz@intel.com>
@@ -7533,7 +7559,6 @@ M:        Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
 M:     Vishwanath Somayaji <vishwanath.somayaji@intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     arch/x86/include/asm/pmc_core.h
 F:     drivers/platform/x86/intel_pmc_core*
 
 INTEL PMC/P-Unit IPC DRIVER
@@ -7577,7 +7602,8 @@ F:        drivers/infiniband/hw/i40iw/
 F:     include/uapi/rdma/i40iw-abi.h
 
 INTEL TELEMETRY DRIVER
-M:     Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
+M:     Rajneesh Bhardwaj <rajneesh.bhardwaj@linux.intel.com>
+M:     "David E. Box" <david.e.box@linux.intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     arch/x86/include/asm/intel_telemetry.h
@@ -8310,6 +8336,14 @@ W:       http://legousb.sourceforge.net/
 S:     Maintained
 F:     drivers/usb/misc/legousbtower.c
 
+LG LAPTOP EXTRAS
+M:     Matan Ziv-Av <matan@svgalib.org>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     Documentation/ABI/testing/sysfs-platform-lg-laptop
+F:     Documentation/laptops/lg-laptop.rst
+F:     drivers/platform/x86/lg-laptop.c
+
 LG2160 MEDIA DRIVER
 M:     Michael Krufky <mkrufky@linuxtv.org>
 L:     linux-media@vger.kernel.org
@@ -15829,7 +15863,6 @@ F:      net/vmw_vsock/virtio_transport_common.c
 F:     net/vmw_vsock/virtio_transport.c
 F:     drivers/net/vsockmon.c
 F:     drivers/vhost/vsock.c
-F:     drivers/vhost/vsock.h
 F:     tools/testing/vsock/
 
 VIRTIO CONSOLE DRIVER
index 9aa352b38815801e37fd3cb04c66fa96511443f5..bce41f4180fcba293c99e135c0468d95c961a208 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -485,7 +485,7 @@ ifneq ($(KBUILD_SRC),)
        $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile $(srctree)
 endif
 
-ifeq ($(cc-name),clang)
+ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
 ifneq ($(CROSS_COMPILE),)
 CLANG_TARGET   := --target=$(notdir $(CROSS_COMPILE:%-=%))
 GCC_TOOLCHAIN_DIR := $(dir $(shell which $(LD)))
@@ -702,7 +702,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG)      := -fstack-protector-strong
 
 KBUILD_CFLAGS += $(stackp-flags-y)
 
-ifeq ($(cc-name),clang)
+ifdef CONFIG_CC_IS_CLANG
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
 KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
index ed27fd26262764fc44092d639030aa7b19f53ea8..e1e540ffa9793d5279c68d9bca412e8a3ef115ae 100644 (file)
@@ -429,6 +429,13 @@ config SECCOMP_FILTER
 
          See Documentation/userspace-api/seccomp_filter.rst for details.
 
+config HAVE_ARCH_STACKLEAK
+       bool
+       help
+         An architecture should select this if it has the code which
+         fills the used part of the kernel stack with the STACKLEAK_POISON
+         value before returning from system calls.
+
 config HAVE_STACKPROTECTOR
        bool
        help
index c50c36baba758f4364aac78e7f973c2c0b1a65b0..8bf1c17f8cefb6b368c40c4376a7ad918c8fde10 100644 (file)
                        interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&rcc HASH1>;
                        resets = <&rcc HASH1_R>;
-                       dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0>;
+                       dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>;
                        dma-names = "in";
                        dma-maxburst = <2>;
                        status = "disabled";
index 63af6234c1b69a20b763470a8a73a989e1d7f747..1c7616815a86ab80fa81ffacbb509a2408554cfa 100644 (file)
@@ -1,6 +1,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EMBEDDED=y
index af318d958fd2a7c9796ad2384c8c122ca04358e2..3d191fd52910f154d08b97432efc2f1701e58503 100644 (file)
@@ -773,7 +773,7 @@ static struct plat_serial8250_port ams_delta_modem_ports[] = {
        {
                .membase        = IOMEM(MODEM_VIRT),
                .mapbase        = MODEM_PHYS,
-               .irq            = -EINVAL, /* changed later */
+               .irq            = IRQ_NOTCONNECTED, /* changed later */
                .flags          = UPF_BOOT_AUTOCONF,
                .irqflags       = IRQF_TRIGGER_RISING,
                .iotype         = UPIO_MEM,
@@ -864,8 +864,7 @@ static int __init modem_nreset_init(void)
 
 
 /*
- * This function expects MODEM IRQ number already assigned to the port
- * and fails if it's not.
+ * This function expects MODEM IRQ number already assigned to the port.
  * The MODEM device requires its RESET# pin kept high during probe.
  * That requirement can be fulfilled in several ways:
  * - with a descriptor of already functional modem_nreset regulator
@@ -888,9 +887,6 @@ static int __init ams_delta_modem_init(void)
        if (!machine_is_ams_delta())
                return -ENODEV;
 
-       if (ams_delta_modem_ports[0].irq < 0)
-               return ams_delta_modem_ports[0].irq;
-
        omap_cfg_reg(M14_1510_GPIO2);
 
        /* Initialize the modem_nreset regulator consumer before use */
index 5b4ff9373c894515ee211a3ce47f745e021a7ed6..8a6880d528b6f1175bd275b7ed0946b6029718bd 100644 (file)
@@ -28,10 +28,15 @@ void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
                           unsigned int mpp_max, void __iomem *dev_bus)
 {
        unsigned int mpp_nr_regs = (1 + mpp_max/8);
-       u32 mpp_ctrl[mpp_nr_regs];
+       u32 mpp_ctrl[8];
        int i;
 
        printk(KERN_DEBUG "initial MPP regs:");
+       if (mpp_nr_regs > ARRAY_SIZE(mpp_ctrl)) {
+               printk(KERN_ERR "orion_mpp_conf: invalid mpp_max\n");
+               return;
+       }
+
        for (i = 0; i < mpp_nr_regs; i++) {
                mpp_ctrl[i] = readl(mpp_ctrl_addr(i, dev_bus));
                printk(" %08x", mpp_ctrl[i]);
index b4e994cd3a421d2b0ebe988b227b670039ba6bc5..6cb9fc7e9382d7f48f1b9d98f00be6b8d9df1f4a 100644 (file)
@@ -134,6 +134,7 @@ vdso_install:
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
+ifeq ($(KBUILD_EXTMOD),)
 # We need to generate vdso-offsets.h before compiling certain files in kernel/.
 # In order to do that, we should use the archprepare target, but we can't since
 # asm-offsets.h is included in some files used to generate vdso-offsets.h, and
@@ -143,6 +144,7 @@ archclean:
 prepare: vdso_prepare
 vdso_prepare: prepare0
        $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h
+endif
 
 define archhelp
   echo  '* Image.gz      - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
index 3cb995606e605badbc58d977201eb10801ec3fdc..c9a57d11330b85eeb5b965ab67e2e5b8b95e3a46 100644 (file)
@@ -308,6 +308,9 @@ CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
 CONFIG_SERIAL_MVEBU_UART=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
 CONFIG_TCG_TPM=y
 CONFIG_TCG_TIS_I2C_INFINEON=y
 CONFIG_I2C_CHARDEV=y
index 9234013e759e56a9ebd5c326cab49bd7c66df323..21a81b59a0ccd5419be92ec6e661a3e05e5820ff 100644 (file)
@@ -96,6 +96,7 @@ static inline unsigned long __percpu_##op(void *ptr,                  \
                : [val] "Ir" (val));                                    \
                break;                                                  \
        default:                                                        \
+               ret = 0;                                                \
                BUILD_BUG();                                            \
        }                                                               \
                                                                        \
@@ -125,6 +126,7 @@ static inline unsigned long __percpu_read(void *ptr, int size)
                ret = READ_ONCE(*(u64 *)ptr);
                break;
        default:
+               ret = 0;
                BUILD_BUG();
        }
 
@@ -194,6 +196,7 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
                : [val] "r" (val));
                break;
        default:
+               ret = 0;
                BUILD_BUG();
        }
 
index f46d57c31443062c626e6062f4925d6206ee832b..6b5037ed15b288872d7956f58f576ab4c47424f4 100644 (file)
@@ -58,7 +58,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 /**
  * elfcorehdr_read - read from ELF core header
  * @buf: buffer where the data is placed
- * @csize: number of bytes to read
+ * @count: number of bytes to read
  * @ppos: address in the memory
  *
  * This function reads @count bytes from elf core header which exists
index 9b65132e789a5572917b7577244b008793f6ff79..2a5b338b254240c8af9d552632214df144a1215a 100644 (file)
@@ -23,7 +23,9 @@
 #include <linux/slab.h>
 #include <linux/stop_machine.h>
 #include <linux/sched/debug.h>
+#include <linux/set_memory.h>
 #include <linux/stringify.h>
+#include <linux/vmalloc.h>
 #include <asm/traps.h>
 #include <asm/ptrace.h>
 #include <asm/cacheflush.h>
@@ -42,10 +44,21 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 static void __kprobes
 post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
 
+static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
+{
+       void *addrs[1];
+       u32 insns[1];
+
+       addrs[0] = addr;
+       insns[0] = opcode;
+
+       return aarch64_insn_patch_text(addrs, insns, 1);
+}
+
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
        /* prepare insn slot */
-       p->ainsn.api.insn[0] = cpu_to_le32(p->opcode);
+       patch_text(p->ainsn.api.insn, p->opcode);
 
        flush_icache_range((uintptr_t) (p->ainsn.api.insn),
                           (uintptr_t) (p->ainsn.api.insn) +
@@ -118,15 +131,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        return 0;
 }
 
-static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
+void *alloc_insn_page(void)
 {
-       void *addrs[1];
-       u32 insns[1];
+       void *page;
 
-       addrs[0] = (void *)addr;
-       insns[0] = (u32)opcode;
+       page = vmalloc_exec(PAGE_SIZE);
+       if (page)
+               set_memory_ro((unsigned long)page, 1);
 
-       return aarch64_insn_patch_text(addrs, insns, 1);
+       return page;
 }
 
 /* arm kprobe: install breakpoint in text */
index ce99c58cd1f1d2081355a7f4420072a31b43ca71..d9a4c2d6dd8b8b8031e6b552067690797eed6b6e 100644 (file)
@@ -497,25 +497,3 @@ void arch_setup_new_exec(void)
 {
        current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
 }
-
-#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
-void __used stackleak_check_alloca(unsigned long size)
-{
-       unsigned long stack_left;
-       unsigned long current_sp = current_stack_pointer;
-       struct stack_info info;
-
-       BUG_ON(!on_accessible_stack(current, current_sp, &info));
-
-       stack_left = current_sp - info.low;
-
-       /*
-        * There's a good chance we're almost out of stack space if this
-        * is true. Using panic() over BUG() is more likely to give
-        * reliable debugging output.
-        */
-       if (size >= stack_left)
-               panic("alloca() over the kernel stack boundary\n");
-}
-EXPORT_SYMBOL(stackleak_check_alloca);
-#endif
index 3a703e5d4e3237f9844d09e871ef1eaa62b781cc..a3ac262848451ae49535c37a6997a211b0f5e914 100644 (file)
@@ -160,6 +160,7 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
        __dma_unmap_area(phys_to_virt(paddr), size, dir);
 }
 
+#ifdef CONFIG_IOMMU_DMA
 static int __swiotlb_get_sgtable_page(struct sg_table *sgt,
                                      struct page *page, size_t size)
 {
@@ -188,6 +189,7 @@ static int __swiotlb_mmap_pfn(struct vm_area_struct *vma,
 
        return ret;
 }
+#endif /* CONFIG_IOMMU_DMA */
 
 static int __init atomic_pool_init(void)
 {
index 48cf6ff9df4a36885db042048ce2aa8761c58a58..22a162cd99e8112b37681afd8934c3c3eb490f99 100644 (file)
@@ -1,9 +1 @@
-menu "C-SKY Debug Options"
-config CSKY_BUILTIN_DTB
-       string "Use kernel builtin dtb"
-       help
-         User could define the dtb instead of the one which is passed from
-         bootloader.
-         Sometimes for debug, we want to use a built-in dtb and then we needn't
-         modify bootloader at all.
-endmenu
+# dummy file, do not delete
index 67a4ae1fba2ba4601f689404e52d5ec3dd901ce1..c639fc167895d7a2f00909bf079e5ea2e6b0558c 100644 (file)
@@ -65,26 +65,15 @@ libs-y += arch/csky/lib/ \
        $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
 
 boot := arch/csky/boot
-ifneq '$(CONFIG_CSKY_BUILTIN_DTB)' '""'
 core-y += $(boot)/dts/
-endif
 
 all: zImage
 
-
-dtbs: scripts
-       $(Q)$(MAKE) $(build)=$(boot)/dts
-
-%.dtb %.dtb.S %.dtb.o: scripts
-       $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
-
-zImage Image uImage: vmlinux dtbs
+zImage Image uImage: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
-       $(Q)$(MAKE) $(clean)=$(boot)/dts
-       rm -rf arch/csky/include/generated
 
 define archhelp
   echo  '* zImage       - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
index 305e81a5e91e1e5a0d622f2f399e3511fe61ca07..c57ad3c880bfb933c227fa32141b57b938be3706 100644 (file)
@@ -1,13 +1,3 @@
 dtstree        := $(srctree)/$(src)
 
-ifneq '$(CONFIG_CSKY_BUILTIN_DTB)' '""'
-builtindtb-y := $(patsubst "%",%,$(CONFIG_CSKY_BUILTIN_DTB))
-dtb-y += $(builtindtb-y).dtb
-obj-y += $(builtindtb-y).dtb.o
-.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
-else
 dtb-y := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
-endif
-
-always += $(dtb-y)
-clean-files += *.dtb *.dtb.S
index 15a84cfd07191f95dcaa83744f76feaae3a37af2..68410490e12fdc2497104c3eeb7cdf64a8e84b8e 100644 (file)
@@ -128,7 +128,7 @@ cflags-y += -ffreestanding
 # clang's output will be based upon the build machine. So for clang we simply
 # unconditionally specify -EB or -EL as appropriate.
 #
-ifeq ($(cc-name),clang)
+ifdef CONFIG_CC_IS_CLANG
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += -EB
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -EL
 else
index 34605ca214984c7257507fa2fb5925eb48bd9f92..58a0315ad743d5bcf965814fd17431f3f2f2bf03 100644 (file)
@@ -10,7 +10,7 @@ ccflags-vdso := \
        $(filter -march=%,$(KBUILD_CFLAGS)) \
        -D__VDSO__
 
-ifeq ($(cc-name),clang)
+ifdef CONFIG_CC_IS_CLANG
 ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS))
 endif
 
index 2d51b2bd4aa132992f2f28be908b0571a79ae4d3..8be31261aec83190a65927854d214d613244c164 100644 (file)
@@ -930,10 +930,6 @@ config FSL_GTM
        help
          Freescale General-purpose Timers support
 
-# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
-config MCA
-       bool
-
 # Platforms that what PCI turned unconditionally just do select PCI
 # in their config node.  Platforms that want to choose at config
 # time should select PPC_PCI_CHOICE
@@ -944,7 +940,6 @@ config PCI
        bool "PCI support" if PPC_PCI_CHOICE
        default y if !40x && !CPM2 && !PPC_8xx && !PPC_83xx \
                && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
-       default PCI_QSPAN if PPC_8xx
        select GENERIC_PCI_IOMAP
        help
          Find out whether your system includes a PCI bus. PCI is the name of
@@ -958,14 +953,6 @@ config PCI_DOMAINS
 config PCI_SYSCALL
        def_bool PCI
 
-config PCI_QSPAN
-       bool "QSpan PCI"
-       depends on PPC_8xx
-       select PPC_I8259
-       help
-         Say Y here if you have a system based on a Motorola 8xx-series
-         embedded processor with a QSPAN PCI interface, otherwise say N.
-
 config PCI_8260
        bool
        depends on PCI && 8260
index 17be664dafa2f2166d12025c8ee536d49c593b14..8a2ce14d68d077b2d62771070b40ac931d8a975a 100644 (file)
@@ -96,7 +96,7 @@ aflags-$(CONFIG_CPU_BIG_ENDIAN)               += $(call cc-option,-mabi=elfv1)
 aflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -mabi=elfv2
 endif
 
-ifneq ($(cc-name),clang)
+ifndef CONFIG_CC_IS_CLANG
   cflags-$(CONFIG_CPU_LITTLE_ENDIAN)   += -mno-strict-align
 endif
 
@@ -175,7 +175,7 @@ endif
 # Work around gcc code-gen bugs with -pg / -fno-omit-frame-pointer in gcc <= 4.8
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44199
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52828
-ifneq ($(cc-name),clang)
+ifndef CONFIG_CC_IS_CLANG
 CC_FLAGS_FTRACE        += $(call cc-ifversion, -lt, 0409, -mno-sched-epilog)
 endif
 endif
index 55c0210a771d1f6e45bdd85a174d31efc2c99acd..092a400740f84ecfe11344fae29e7fb0927477d0 100644 (file)
                };
 
                ethernet@f0000 {
-                       phy-handle = <&xg_cs4315_phy1>;
+                       phy-handle = <&xg_cs4315_phy2>;
                        phy-connection-type = "xgmii";
                };
 
                ethernet@f2000 {
-                       phy-handle = <&xg_cs4315_phy2>;
+                       phy-handle = <&xg_cs4315_phy1>;
                        phy-connection-type = "xgmii";
                };
 
index 5b037f51741df177cfb26ea11dd1a1e9bb093290..3aa300afbbca4a4c3e07b4079a3b4b43d1ff7def 100644 (file)
@@ -72,7 +72,7 @@
                #address-cells = <1>;
                #size-cells = <1>;
                device_type = "soc";
-               ranges = <0x0 0xff000000 0x4000>;
+               ranges = <0x0 0xff000000 0x28000>;
                bus-frequency = <0>;
 
                // Temporary -- will go away once kernel uses ranges for get_immrbase().
                                #size-cells = <0>;
                        };
                };
+
+               crypto@20000 {
+                       compatible = "fsl,sec1.2", "fsl,sec1.0";
+                       reg = <0x20000 0x8000>;
+                       interrupts = <1 1>;
+                       interrupt-parent = <&PIC>;
+                       fsl,num-channels = <1>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0x4c>;
+                       fsl,descriptor-types-mask = <0x05000154>;
+               };
        };
 
        chosen {
index 31733a95bbd052bda1038f8160b127181d3cffc2..3d5acd2b113a2d64b12f5f8a1487483c2cc24159 100644 (file)
@@ -36,6 +36,11 @@ int raw_patch_instruction(unsigned int *addr, unsigned int instr);
 int patch_instruction_site(s32 *addr, unsigned int instr);
 int patch_branch_site(s32 *site, unsigned long target, int flags);
 
+static inline unsigned long patch_site_addr(s32 *site)
+{
+       return (unsigned long)site + *site;
+}
+
 int instr_is_relative_branch(unsigned int instr);
 int instr_is_relative_link_branch(unsigned int instr);
 int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
index 4f547752ae79595086c9ad55a44281ea68b52505..fa05aa566ece422971533399c8921ada1af35aec 100644 (file)
  * respectively NA for All or X for Supervisor and no access for User.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MI_APG_INIT    0xf4f4f4f4
-#else
 #define MI_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MI_RPN is written, bits in
  * Supervisor and no access for user and NA for ALL.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MD_APG_INIT    0xf4f4f4f4
-#else
 #define MD_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MD_RPN is written, bits in
  */
 #define SPRN_M_TW      799
 
-/* APGs */
-#define M_APG0         0x00000000
-#define M_APG1         0x00000020
-#define M_APG2         0x00000040
-#define M_APG3         0x00000060
-
 #ifdef CONFIG_PPC_MM_SLICES
 #include <asm/nohash/32/slice.h>
 #define SLICE_ARRAY_SIZE       (1 << (32 - SLICE_LOW_SHIFT - 1))
@@ -251,6 +229,15 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
        BUG();
 }
 
+/* patch sites */
+extern s32 patch__itlbmiss_linmem_top;
+extern s32 patch__dtlbmiss_linmem_top, patch__dtlbmiss_immr_jmp;
+extern s32 patch__fixupdar_linmem_top;
+
+extern s32 patch__itlbmiss_exit_1, patch__itlbmiss_exit_2;
+extern s32 patch__dtlbmiss_exit_1, patch__dtlbmiss_exit_2, patch__dtlbmiss_exit_3;
+extern s32 patch__itlbmiss_perf, patch__dtlbmiss_perf;
+
 #endif /* !__ASSEMBLY__ */
 
 #if defined(CONFIG_PPC_4K_PAGES)
index bb38dd67d47ddba7d730eb57b5d0cf1aac30093a..1b06add4f092adb5811be46bc4b6011e5537c591 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/spinlock.h>
 #include <asm/page.h>
 #include <linux/time.h>
+#include <linux/cpumask.h>
 
 /*
  * Definitions for talking to the RTAS on CHRP machines.
index 134a573a9f2d0c61f7bf0d789826b6bdccb989f0..3b67b9533c82fe1cfee4f279cdfd1a3897f873d7 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/ptrace.h>
 #include <asm/export.h>
+#include <asm/code-patching-asm.h>
 
 #if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
 /* By simply checking Address >= 0x80000000, we know if its a kernel address */
@@ -318,8 +319,8 @@ InstructionTLBMiss:
        cmpli   cr0, r11, PAGE_OFFSET@h
 #ifndef CONFIG_PIN_TLB_TEXT
        /* It is assumed that kernel code fits into the first 8M page */
-_ENTRY(ITLBMiss_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x0800000)@h
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x0800000)@h
+       patch_site      0b, patch__itlbmiss_linmem_top
 #endif
 #endif
 #endif
@@ -353,13 +354,14 @@ _ENTRY(ITLBMiss_cmp)
 #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
        mtcr    r12
 #endif
-
-#ifdef CONFIG_SWAP
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        /* Load the MI_TWC with the attributes for this "segment." */
        mtspr   SPRN_MI_TWC, r11        /* Set segment attributes */
 
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        li      r11, RPN_PATTERN | 0x200
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 20 and 23 must be clear.
@@ -372,16 +374,17 @@ _ENTRY(ITLBMiss_cmp)
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
        /* Restore registers */
-_ENTRY(itlb_miss_exit_1)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
 #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
        mfspr   r12, SPRN_SPRG_SCRATCH2
 #endif
        rfi
+       patch_site      0b, patch__itlbmiss_exit_1
+
 #ifdef CONFIG_PERF_EVENTS
-_ENTRY(itlb_miss_perf)
-       lis     r10, (itlb_miss_counter - PAGE_OFFSET)@ha
+       patch_site      0f, patch__itlbmiss_perf
+0:     lis     r10, (itlb_miss_counter - PAGE_OFFSET)@ha
        lwz     r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
        addi    r11, r11, 1
        stw     r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
@@ -435,11 +438,11 @@ DataStoreTLBMiss:
 #ifndef CONFIG_PIN_TLB_IMMR
        cmpli   cr0, r11, VIRT_IMMR_BASE@h
 #endif
-_ENTRY(DTLBMiss_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+       patch_site      0b, patch__dtlbmiss_linmem_top
 #ifndef CONFIG_PIN_TLB_IMMR
-_ENTRY(DTLBMiss_jmp)
-       beq-    DTLBMissIMMR
+0:     beq-    DTLBMissIMMR
+       patch_site      0b, patch__dtlbmiss_immr_jmp
 #endif
        blt     cr7, DTLBMissLinear
        lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
@@ -470,14 +473,22 @@ _ENTRY(DTLBMiss_jmp)
         * above.
         */
        rlwimi  r11, r10, 0, _PAGE_GUARDED
-#ifdef CONFIG_SWAP
-       /* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
-        * on that bit will represent a Non Access group
-        */
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        mtspr   SPRN_MD_TWC, r11
 
+       /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
+        * We also need to know if the insn is a load/store, so:
+        * Clear _PAGE_PRESENT and load that which will
+        * trap into DTLB Error with store bit set accordinly.
+        */
+       /* PRESENT=0x1, ACCESSED=0x20
+        * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
+        * r10 = (r10 & ~PRESENT) | r11;
+        */
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 24, 25, 26, and 27 must be
         * set.  All other Linux PTE bits control the behavior
@@ -489,14 +500,16 @@ _ENTRY(DTLBMiss_jmp)
 
        /* Restore registers */
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_1)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_1
+
 #ifdef CONFIG_PERF_EVENTS
-_ENTRY(dtlb_miss_perf)
-       lis     r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
+       patch_site      0f, patch__dtlbmiss_perf
+0:     lis     r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
        lwz     r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
        addi    r11, r11, 1
        stw     r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
@@ -637,8 +650,8 @@ InstructionBreakpoint:
  */
 DTLBMissIMMR:
        mtcr    r12
-       /* Set 512k byte guarded page and mark it valid and accessed */
-       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
+       /* Set 512k byte guarded page and mark it valid */
+       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
        mtspr   SPRN_MD_TWC, r10
        mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
        rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
@@ -648,16 +661,17 @@ DTLBMissIMMR:
 
        li      r11, RPN_PATTERN
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_2)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_2
 
 DTLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid and accessed */
-       li      r11, MD_PS8MEG | MD_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MD_PS8MEG | MD_SVALID
        mtspr   SPRN_MD_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
@@ -666,28 +680,29 @@ DTLBMissLinear:
 
        li      r11, RPN_PATTERN
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_3)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_3
 
 #ifndef CONFIG_PIN_TLB_TEXT
 ITLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid,accessed */
-       li      r11, MI_PS8MEG | MI_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MI_PS8MEG | MI_SVALID
        mtspr   SPRN_MI_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
                          _PAGE_PRESENT
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
-_ENTRY(itlb_miss_exit_2)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__itlbmiss_exit_2
 #endif
 
 /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
@@ -705,8 +720,10 @@ FixupDAR:/* Entry point for dcbx workaround. */
        mfspr   r11, SPRN_M_TW  /* Get level 1 table */
        blt+    3f
        rlwinm  r11, r10, 16, 0xfff8
-_ENTRY(FixupDAR_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+       patch_site      0b, patch__fixupdar_linmem_top
+
        /* create physical page address from effective address */
        tophys(r11, r10)
        blt-    cr7, 201f
@@ -960,7 +977,7 @@ initial_mmu:
        ori     r8, r8, MI_EVALID       /* Mark it valid */
        mtspr   SPRN_MI_EPN, r8
        li      r8, MI_PS8MEG /* Set 8M byte page */
-       ori     r8, r8, MI_SVALID | M_APG2      /* Make it valid, APG 2 */
+       ori     r8, r8, MI_SVALID       /* Make it valid */
        mtspr   SPRN_MI_TWC, r8
        li      r8, MI_BOOTINIT         /* Create RPN for address 0 */
        mtspr   SPRN_MI_RPN, r8         /* Store TLB entry */
@@ -987,7 +1004,7 @@ initial_mmu:
        ori     r8, r8, MD_EVALID       /* Mark it valid */
        mtspr   SPRN_MD_EPN, r8
        li      r8, MD_PS512K | MD_GUARDED      /* Set 512k byte page */
-       ori     r8, r8, MD_SVALID | M_APG2      /* Make it valid and accessed */
+       ori     r8, r8, MD_SVALID       /* Make it valid */
        mtspr   SPRN_MD_TWC, r8
        mr      r8, r9                  /* Create paddr for TLB */
        ori     r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
index 4d5322cfad25c7b543cc2e80c1f355f2d75030fc..96f34730010fe3f5f778400a14a7a470d4d38142 100644 (file)
@@ -590,12 +590,11 @@ void flush_all_to_thread(struct task_struct *tsk)
        if (tsk->thread.regs) {
                preempt_disable();
                BUG_ON(tsk != current);
-               save_all(tsk);
-
 #ifdef CONFIG_SPE
                if (tsk->thread.regs->msr & MSR_SPE)
                        tsk->thread.spefscr = mfspr(SPRN_SPEFSCR);
 #endif
+               save_all(tsk);
 
                preempt_enable();
        }
index bf8def2159c31e3e921394464e1491a5097f23b4..d65b961661fbf6d9075b34c523269bb1261845fe 100644 (file)
@@ -2337,8 +2337,7 @@ static void kvmppc_set_timer(struct kvm_vcpu *vcpu)
                kvmppc_core_prepare_to_enter(vcpu);
                return;
        }
-       dec_nsec = (vcpu->arch.dec_expires - now) * NSEC_PER_SEC
-                  / tb_ticks_per_sec;
+       dec_nsec = tb_to_ns(vcpu->arch.dec_expires - now);
        hrtimer_start(&vcpu->arch.dec_timer, dec_nsec, HRTIMER_MODE_REL);
        vcpu->arch.timer_running = 1;
 }
index fa888bfc347e6e6e10055cd7b2e36a6c5c4ecf2b..9f5b8c01c4e165a969d3317be6b5c5b9ae71b2f9 100644 (file)
@@ -61,11 +61,10 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
 
        dec_time = vcpu->arch.dec;
        /*
-        * Guest timebase ticks at the same frequency as host decrementer.
-        * So use the host decrementer calculations for decrementer emulation.
+        * Guest timebase ticks at the same frequency as host timebase.
+        * So use the host timebase calculations for decrementer emulation.
         */
-       dec_time = dec_time << decrementer_clockevent.shift;
-       do_div(dec_time, decrementer_clockevent.mult);
+       dec_time = tb_to_ns(dec_time);
        dec_nsec = do_div(dec_time, NSEC_PER_SEC);
        hrtimer_start(&vcpu->arch.dec_timer,
                ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
index 36484a2ef9158e39b8a0fb46f84e7d070753f090..01b7f5107c3a32d0b4d4e627b10ecd0fbd380bec 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/memblock.h>
+#include <linux/mmu_context.h>
 #include <asm/fixmap.h>
 #include <asm/code-patching.h>
 
@@ -79,7 +80,7 @@ void __init MMU_init_hw(void)
        for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
                mtspr(SPRN_MD_CTR, ctr | (i << 8));
                mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
-               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID | M_APG2);
+               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
                mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
                addr += LARGE_PAGE_SIZE_8M;
                mem -= LARGE_PAGE_SIZE_8M;
@@ -97,22 +98,13 @@ static void __init mmu_mapin_immr(void)
                map_kernel_page(v + offset, p + offset, PAGE_KERNEL_NCG);
 }
 
-/* Address of instructions to patch */
-#ifndef CONFIG_PIN_TLB_IMMR
-extern unsigned int DTLBMiss_jmp;
-#endif
-extern unsigned int DTLBMiss_cmp, FixupDAR_cmp;
-#ifndef CONFIG_PIN_TLB_TEXT
-extern unsigned int ITLBMiss_cmp;
-#endif
-
-static void __init mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped)
+static void __init mmu_patch_cmp_limit(s32 *site, unsigned long mapped)
 {
-       unsigned int instr = *addr;
+       unsigned int instr = *(unsigned int *)patch_site_addr(site);
 
        instr &= 0xffff0000;
        instr |= (unsigned long)__va(mapped) >> 16;
-       patch_instruction(addr, instr);
+       patch_instruction_site(site, instr);
 }
 
 unsigned long __init mmu_mapin_ram(unsigned long top)
@@ -123,17 +115,17 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
                mapped = 0;
                mmu_mapin_immr();
 #ifndef CONFIG_PIN_TLB_IMMR
-               patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP);
+               patch_instruction_site(&patch__dtlbmiss_immr_jmp, PPC_INST_NOP);
 #endif
 #ifndef CONFIG_PIN_TLB_TEXT
-               mmu_patch_cmp_limit(&ITLBMiss_cmp, 0);
+               mmu_patch_cmp_limit(&patch__itlbmiss_linmem_top, 0);
 #endif
        } else {
                mapped = top & ~(LARGE_PAGE_SIZE_8M - 1);
        }
 
-       mmu_patch_cmp_limit(&DTLBMiss_cmp, mapped);
-       mmu_patch_cmp_limit(&FixupDAR_cmp, mapped);
+       mmu_patch_cmp_limit(&patch__dtlbmiss_linmem_top, mapped);
+       mmu_patch_cmp_limit(&patch__fixupdar_linmem_top, mapped);
 
        /* If the size of RAM is not an exact power of two, we may not
         * have covered RAM in its entirety with 8 MiB
index 6c0020d1c5614c6610faa359ef87254e3a4c8107..e38f74e9e7a4aec85166bdcd0eeefe529c731bc9 100644 (file)
@@ -31,9 +31,6 @@
 
 extern unsigned long itlb_miss_counter, dtlb_miss_counter;
 extern atomic_t instruction_counter;
-extern unsigned int itlb_miss_perf, dtlb_miss_perf;
-extern unsigned int itlb_miss_exit_1, itlb_miss_exit_2;
-extern unsigned int dtlb_miss_exit_1, dtlb_miss_exit_2, dtlb_miss_exit_3;
 
 static atomic_t insn_ctr_ref;
 static atomic_t itlb_miss_ref;
@@ -103,22 +100,22 @@ static int mpc8xx_pmu_add(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_ITLB_LOAD_MISS:
                if (atomic_inc_return(&itlb_miss_ref) == 1) {
-                       unsigned long target = (unsigned long)&itlb_miss_perf;
+                       unsigned long target = patch_site_addr(&patch__itlbmiss_perf);
 
-                       patch_branch(&itlb_miss_exit_1, target, 0);
+                       patch_branch_site(&patch__itlbmiss_exit_1, target, 0);
 #ifndef CONFIG_PIN_TLB_TEXT
-                       patch_branch(&itlb_miss_exit_2, target, 0);
+                       patch_branch_site(&patch__itlbmiss_exit_2, target, 0);
 #endif
                }
                val = itlb_miss_counter;
                break;
        case PERF_8xx_ID_DTLB_LOAD_MISS:
                if (atomic_inc_return(&dtlb_miss_ref) == 1) {
-                       unsigned long target = (unsigned long)&dtlb_miss_perf;
+                       unsigned long target = patch_site_addr(&patch__dtlbmiss_perf);
 
-                       patch_branch(&dtlb_miss_exit_1, target, 0);
-                       patch_branch(&dtlb_miss_exit_2, target, 0);
-                       patch_branch(&dtlb_miss_exit_3, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_1, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_2, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_3, target, 0);
                }
                val = dtlb_miss_counter;
                break;
@@ -180,17 +177,17 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_ITLB_LOAD_MISS:
                if (atomic_dec_return(&itlb_miss_ref) == 0) {
-                       patch_instruction(&itlb_miss_exit_1, insn);
+                       patch_instruction_site(&patch__itlbmiss_exit_1, insn);
 #ifndef CONFIG_PIN_TLB_TEXT
-                       patch_instruction(&itlb_miss_exit_2, insn);
+                       patch_instruction_site(&patch__itlbmiss_exit_2, insn);
 #endif
                }
                break;
        case PERF_8xx_ID_DTLB_LOAD_MISS:
                if (atomic_dec_return(&dtlb_miss_ref) == 0) {
-                       patch_instruction(&dtlb_miss_exit_1, insn);
-                       patch_instruction(&dtlb_miss_exit_2, insn);
-                       patch_instruction(&dtlb_miss_exit_3, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_1, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_2, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_3, insn);
                }
                break;
        }
index 2a9d66254ffc58c92b9d86f663719d646734f342..5326ece361204054992c503b3540465bc6bda512 100644 (file)
@@ -29,6 +29,7 @@ config KILAUEA
        select 405EX
        select PPC40x_SIMPLE
        select PPC4xx_PCI_EXPRESS
+       select PCI
        select PCI_MSI
        select PPC4xx_MSI
        help
index f024efd5a4c2061b6989beaa4d4cda98f5e65f9e..9a85d350b1b6c7b36418b661d4fb81ccc742fa58 100644 (file)
@@ -21,6 +21,7 @@ config BLUESTONE
        depends on 44x
        select PPC44x_SIMPLE
        select APM821xx
+       select PCI
        select PCI_MSI
        select PPC4xx_MSI
        select PPC4xx_PCI_EXPRESS
@@ -200,6 +201,7 @@ config AKEBONO
        select SWIOTLB
        select 476FPE
        select PPC4xx_PCI_EXPRESS
+       select PCI
        select PCI_MSI
        select PPC4xx_HSTA_MSI
        select I2C
index 8bd590af488a1a1c379476a77dae5eb3809c44e3..794487313cc8d252af91e3ed113e51c624cff3d9 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/hugetlb.h>
 #include <asm/lppaca.h>
 #include <asm/hvcall.h>
 #include <asm/firmware.h>
@@ -36,6 +37,7 @@
 #include <asm/vio.h>
 #include <asm/mmu.h>
 #include <asm/machdep.h>
+#include <asm/drmem.h>
 
 #include "pseries.h"
 
@@ -433,6 +435,16 @@ static void parse_em_data(struct seq_file *m)
                seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
 }
 
+static void maxmem_data(struct seq_file *m)
+{
+       unsigned long maxmem = 0;
+
+       maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
+       maxmem += hugetlb_total_pages() * PAGE_SIZE;
+
+       seq_printf(m, "MaxMem=%ld\n", maxmem);
+}
+
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
        int partition_potential_processors;
@@ -491,6 +503,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
        seq_printf(m, "slb_size=%d\n", mmu_slb_size);
 #endif
        parse_em_data(m);
+       maxmem_data(m);
 
        return 0;
 }
index 69e7fb47bcaa3e39c81f017214e388e450b2ac2d..878f9c1d36150c80a021413f23ac36577ef881c0 100644 (file)
@@ -11,6 +11,12 @@ UBSAN_SANITIZE := n
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS))
 
+ifdef CONFIG_CC_IS_CLANG
+# clang stores addresses on the stack causing the frame size to blow
+# out. See https://github.com/ClangBuiltLinux/linux/issues/252
+KBUILD_CFLAGS += -Wframe-larger-than=4096
+endif
+
 ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
 
 obj-y                  += xmon.o nonstdio.o spr_access.o
index 36473d7dbaac4a602096414e20d2cad2ed296358..07fa9ea75fea1f1c72caaa6f246c28df86b6a532 100644 (file)
@@ -1,6 +1,3 @@
-CONFIG_SMP=y
-CONFIG_PCI=y
-CONFIG_PCIE_XILINX=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_IKCONFIG=y
@@ -11,10 +8,15 @@ CONFIG_CFS_BANDWIDTH=y
 CONFIG_CGROUP_BPF=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
+CONFIG_SMP=y
+CONFIG_PCI=y
+CONFIG_PCIE_XILINX=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -59,6 +61,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_UAS=y
 CONFIG_VIRTIO_MMIO=y
+CONFIG_SIFIVE_PLIC=y
 CONFIG_RAS=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -72,8 +75,5 @@ CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
-# CONFIG_RCU_TRACE is not set
 CONFIG_CRYPTO_USER_API_HASH=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_SIFIVE_PLIC=y
+# CONFIG_RCU_TRACE is not set
index 67b3e6b3ce5d7cf8b417d361c5bbaadce92cc1e0..47c871394ccb1602d59bca5a3459a7e088df98e0 100644 (file)
@@ -1849,16 +1849,12 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 {
        u64 saved_fault_address = current_thread_info()->fault_address;
        u8 saved_fault_code = get_thread_fault_code();
-       mm_segment_t old_fs;
 
        perf_callchain_store(entry, regs->tpc);
 
        if (!current->mm)
                return;
 
-       old_fs = get_fs();
-       set_fs(USER_DS);
-
        flushw_user();
 
        pagefault_disable();
@@ -1870,7 +1866,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 
        pagefault_enable();
 
-       set_fs(old_fs);
        set_thread_fault_code(saved_fault_code);
        current_thread_info()->fault_address = saved_fault_address;
 }
index bb68c805b891855e18af6397ce534f74d5550a4d..ff9389a1c9f3f68c5acaa32123d65c5fedbf9846 100644 (file)
@@ -47,9 +47,9 @@ sys_call_table32:
        .word sys_recvfrom, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate
 /*130*/        .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_sendto, sys_shutdown
        .word sys_socketpair, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
-/*140*/        .word sys_sendfile64, sys_nis_syscall, compat_sys_futex, sys_gettid, compat_sys_getrlimit
+/*140*/        .word sys_sendfile64, sys_getpeername, compat_sys_futex, sys_gettid, compat_sys_getrlimit
        .word compat_sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/        .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+/*150*/        .word sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
        .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
 /*160*/        .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
        .word sys_quotactl, sys_set_tid_address, compat_sys_mount, compat_sys_ustat, sys_setxattr
index c51c989c19c08da99155d354cc11558c1cdb36d4..ba7e3464ee9235fe43f0edd66034d670b2fc4ffd 100644 (file)
@@ -129,6 +129,7 @@ config X86
        select HAVE_ARCH_PREL32_RELOCATIONS
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_THREAD_STRUCT_WHITELIST
+       select HAVE_ARCH_STACKLEAK
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64
index 708b46a54578d8722fc1c9fa07e58d74f7ff49d8..25e5a6bda8c3a971609dff93919ccab27d6a3aa9 100644 (file)
@@ -329,8 +329,22 @@ For 32-bit we have the following conventions - kernel is built with
 
 #endif
 
+.macro STACKLEAK_ERASE_NOCLOBBER
+#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
+       PUSH_AND_CLEAR_REGS
+       call stackleak_erase
+       POP_REGS
+#endif
+.endm
+
 #endif /* CONFIG_X86_64 */
 
+.macro STACKLEAK_ERASE
+#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
+       call stackleak_erase
+#endif
+.endm
+
 /*
  * This does 'call enter_from_user_mode' unless we can avoid it based on
  * kernel config or using the static jump infrastructure.
index 687e47f8a796621d4effcac9a055965969a81dc2..d309f30cf7af84e67ac38910eff4256da9c25a11 100644 (file)
@@ -46,6 +46,8 @@
 #include <asm/frame.h>
 #include <asm/nospec-branch.h>
 
+#include "calling.h"
+
        .section .entry.text, "ax"
 
 /*
@@ -712,6 +714,7 @@ ENTRY(ret_from_fork)
        /* When we fork, we trace the syscall return in the child, too. */
        movl    %esp, %eax
        call    syscall_return_slowpath
+       STACKLEAK_ERASE
        jmp     restore_all
 
        /* kernel thread */
@@ -886,6 +889,8 @@ ENTRY(entry_SYSENTER_32)
        ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
                    "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
 
+       STACKLEAK_ERASE
+
 /* Opportunistic SYSEXIT */
        TRACE_IRQS_ON                   /* User mode traces as IRQs on. */
 
@@ -997,6 +1002,8 @@ ENTRY(entry_INT80_32)
        call    do_int80_syscall_32
 .Lsyscall_32_done:
 
+       STACKLEAK_ERASE
+
 restore_all:
        TRACE_IRQS_IRET
        SWITCH_TO_ENTRY_STACK
index 4d7a2d9d44cfec5928b902cef1bca9bca29093a6..ce25d84023c021ce25f041cd81497500f20c3a60 100644 (file)
@@ -266,6 +266,8 @@ syscall_return_via_sysret:
         * We are on the trampoline stack.  All regs except RDI are live.
         * We can do future final exit work right here.
         */
+       STACKLEAK_ERASE_NOCLOBBER
+
        SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi
 
        popq    %rdi
@@ -625,6 +627,7 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode)
         * We are on the trampoline stack.  All regs except RDI are live.
         * We can do future final exit work right here.
         */
+       STACKLEAK_ERASE_NOCLOBBER
 
        SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi
 
index 7d0df78db727296d1c4451e3a930033669f47aa3..8eaf8952c408cd619124f9696b4888fae2f529ad 100644 (file)
@@ -261,6 +261,11 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
 
        /* Opportunistic SYSRET */
 sysret32_from_system_call:
+       /*
+        * We are not going to return to userspace from the trampoline
+        * stack. So let's erase the thread stack right now.
+        */
+       STACKLEAK_ERASE
        TRACE_IRQS_ON                   /* User mode traces as IRQs on. */
        movq    RBX(%rsp), %rbx         /* pt_regs->rbx */
        movq    RBP(%rsp), %rbp         /* pt_regs->rbp */
index 60c141af222bc5e05c426e6c0edf976e93c036d0..d29b7365da8d9facd71a887a071b34bbb68ec5fc 100644 (file)
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-config ZONE_DMA
-       def_bool y
-
 config XTENSA
        def_bool y
        select ARCH_HAS_SG_CHAIN
index dc9e0ba7122cad1e982ac33eb5c9d60d9a1db48a..294846117fc2c5527e297ccd50eb55c31c3f3228 100644 (file)
@@ -33,7 +33,7 @@ uImage: $(obj)/uImage
 boot-elf boot-redboot: $(addprefix $(obj)/,$(subdir-y))
        $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
 
-OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary
+OBJCOPYFLAGS = --strip-all -R .comment -R .notes -O binary
 
 vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
index b727b18a68acd9ff639d9da228fc70d94dc657ff..b80a430453b1cb7d76b8598db8eb0b06f039df8d 100644 (file)
@@ -131,6 +131,7 @@ SECTIONS
   .fixup   : { *(.fixup) }
 
   EXCEPTION_TABLE(16)
+  NOTES
   /* Data section */
 
   _sdata = .;
@@ -296,38 +297,11 @@ SECTIONS
 
   _end = .;
 
-  .xt.lit : { *(.xt.lit) }
-  .xt.prop : { *(.xt.prop) }
-
-  .debug  0 :  { *(.debug) }
-  .line  0 :  { *(.line) }
-  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
-  .debug_sfnames  0 :  { *(.debug_sfnames) }
-  .debug_aranges  0 :  { *(.debug_aranges) }
-  .debug_pubnames  0 :  { *(.debug_pubnames) }
-  .debug_info  0 :  { *(.debug_info) }
-  .debug_abbrev  0 :  { *(.debug_abbrev) }
-  .debug_line  0 :  { *(.debug_line) }
-  .debug_frame  0 :  { *(.debug_frame) }
-  .debug_str  0 :  { *(.debug_str) }
-  .debug_loc  0 :  { *(.debug_loc) }
-  .debug_macinfo  0 :  { *(.debug_macinfo) }
-  .debug_weaknames  0 :  { *(.debug_weaknames) }
-  .debug_funcnames  0 :  { *(.debug_funcnames) }
-  .debug_typenames  0 :  { *(.debug_typenames) }
-  .debug_varnames  0 :  { *(.debug_varnames) }
-
-  .xt.insn 0 :
-  {
-    *(.xt.insn)
-    *(.gnu.linkonce.x*)
-  }
+  DWARF_DEBUG
 
-  .xt.lit 0 :
-  {
-    *(.xt.lit)
-    *(.gnu.linkonce.p*)
-  }
+  .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
+  .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) }
+  .xt.lit  0 : { KEEP(*(.xt.lit  .xt.lit.*  .gnu.linkonce.p*)) }
 
   /* Sections to be discarded */
   DISCARDS
index 9750a48f491b19c087b8b1013b4614eaf61e4cac..30a48bba4a47372b81ce5f0e6e40aec8ca564dcd 100644 (file)
@@ -71,7 +71,7 @@ void __init zones_init(void)
 {
        /* All pages are DMA-able, so we put them all in the DMA zone. */
        unsigned long zones_size[MAX_NR_ZONES] = {
-               [ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET,
+               [ZONE_NORMAL] = max_low_pfn - ARCH_PFN_OFFSET,
 #ifdef CONFIG_HIGHMEM
                [ZONE_HIGHMEM] = max_pfn - max_low_pfn,
 #endif
index d9a7916ff0ab6474a6f4abac2873a6685ad4d467..9fe5952d117d553f12f32055fde8683c554b06a8 100644 (file)
@@ -642,7 +642,7 @@ void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
        uint64_t serial_nr;
 
        rcu_read_lock();
-       serial_nr = __bio_blkcg(bio)->css.serial_nr;
+       serial_nr = bio_blkcg(bio)->css.serial_nr;
 
        /*
         * Check whether blkcg has changed.  The condition may trigger
@@ -651,7 +651,7 @@ void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
        if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr))
                goto out;
 
-       bfqg = __bfq_bic_change_cgroup(bfqd, bic, __bio_blkcg(bio));
+       bfqg = __bfq_bic_change_cgroup(bfqd, bic, bio_blkcg(bio));
        /*
         * Update blkg_path for bfq_log_* functions. We cache this
         * path, and update it here, for the following
index 6075100f03a50a73da838b19891b923d0ad422a7..3a27d31fcda60250854ced98c68fe3db32ac587c 100644 (file)
@@ -4384,7 +4384,7 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
 
        rcu_read_lock();
 
-       bfqg = bfq_find_set_group(bfqd, __bio_blkcg(bio));
+       bfqg = bfq_find_set_group(bfqd, bio_blkcg(bio));
        if (!bfqg) {
                bfqq = &bfqd->oom_bfqq;
                goto out;
index bbfeb4ee2892fcbd9d51de450c41fab7dc466ce5..d5368a4455613452972e0b8b06ea3e1ceacb335e 100644 (file)
@@ -609,9 +609,7 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
        bio->bi_iter = bio_src->bi_iter;
        bio->bi_io_vec = bio_src->bi_io_vec;
 
-       bio_clone_blkg_association(bio, bio_src);
-
-       blkcg_bio_issue_init(bio);
+       bio_clone_blkcg_association(bio, bio_src);
 }
 EXPORT_SYMBOL(__bio_clone_fast);
 
@@ -1256,7 +1254,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
        /*
         * success
         */
-       if (((iter->type & WRITE) && (!map_data || !map_data->null_mapped)) ||
+       if ((iov_iter_rw(iter) == WRITE && (!map_data || !map_data->null_mapped)) ||
            (map_data && map_data->from_user)) {
                ret = bio_copy_from_iter(bio, iter);
                if (ret)
@@ -1956,151 +1954,69 @@ EXPORT_SYMBOL(bioset_init_from_src);
 
 #ifdef CONFIG_BLK_CGROUP
 
-/**
- * bio_associate_blkg - associate a bio with the a blkg
- * @bio: target bio
- * @blkg: the blkg to associate
- *
- * This tries to associate @bio with the specified blkg.  Association failure
- * is handled by walking up the blkg tree.  Therefore, the blkg associated can
- * be anything between @blkg and the root_blkg.  This situation only happens
- * when a cgroup is dying and then the remaining bios will spill to the closest
- * alive blkg.
- *
- * A reference will be taken on the @blkg and will be released when @bio is
- * freed.
- */
-int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
-{
-       if (unlikely(bio->bi_blkg))
-               return -EBUSY;
-       bio->bi_blkg = blkg_tryget_closest(blkg);
-       return 0;
-}
-
-/**
- * __bio_associate_blkg_from_css - internal blkg association function
- *
- * This in the core association function that all association paths rely on.
- * A blkg reference is taken which is released upon freeing of the bio.
- */
-static int __bio_associate_blkg_from_css(struct bio *bio,
-                                        struct cgroup_subsys_state *css)
-{
-       struct request_queue *q = bio->bi_disk->queue;
-       struct blkcg_gq *blkg;
-       int ret;
-
-       rcu_read_lock();
-
-       if (!css || !css->parent)
-               blkg = q->root_blkg;
-       else
-               blkg = blkg_lookup_create(css_to_blkcg(css), q);
-
-       ret = bio_associate_blkg(bio, blkg);
-
-       rcu_read_unlock();
-       return ret;
-}
-
-/**
- * bio_associate_blkg_from_css - associate a bio with a specified css
- * @bio: target bio
- * @css: target css
- *
- * Associate @bio with the blkg found by combining the css's blkg and the
- * request_queue of the @bio.  This falls back to the queue's root_blkg if
- * the association fails with the css.
- */
-int bio_associate_blkg_from_css(struct bio *bio,
-                               struct cgroup_subsys_state *css)
-{
-       if (unlikely(bio->bi_blkg))
-               return -EBUSY;
-       return __bio_associate_blkg_from_css(bio, css);
-}
-EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css);
-
 #ifdef CONFIG_MEMCG
 /**
- * bio_associate_blkg_from_page - associate a bio with the page's blkg
+ * bio_associate_blkcg_from_page - associate a bio with the page's blkcg
  * @bio: target bio
  * @page: the page to lookup the blkcg from
  *
- * Associate @bio with the blkg from @page's owning memcg and the respective
- * request_queue.  If cgroup_e_css returns NULL, fall back to the queue's
- * root_blkg.
- *
- * Note: this must be called after bio has an associated device.
+ * Associate @bio with the blkcg from @page's owning memcg.  This works like
+ * every other associate function wrt references.
  */
-int bio_associate_blkg_from_page(struct bio *bio, struct page *page)
+int bio_associate_blkcg_from_page(struct bio *bio, struct page *page)
 {
-       struct cgroup_subsys_state *css;
-       int ret;
+       struct cgroup_subsys_state *blkcg_css;
 
-       if (unlikely(bio->bi_blkg))
+       if (unlikely(bio->bi_css))
                return -EBUSY;
        if (!page->mem_cgroup)
                return 0;
-
-       rcu_read_lock();
-
-       css = cgroup_e_css(page->mem_cgroup->css.cgroup, &io_cgrp_subsys);
-
-       ret = __bio_associate_blkg_from_css(bio, css);
-
-       rcu_read_unlock();
-       return ret;
+       blkcg_css = cgroup_get_e_css(page->mem_cgroup->css.cgroup,
+                                    &io_cgrp_subsys);
+       bio->bi_css = blkcg_css;
+       return 0;
 }
 #endif /* CONFIG_MEMCG */
 
 /**
- * bio_associate_create_blkg - associate a bio with a blkg from q
- * @q: request_queue where bio is going
+ * bio_associate_blkcg - associate a bio with the specified blkcg
  * @bio: target bio
+ * @blkcg_css: css of the blkcg to associate
+ *
+ * Associate @bio with the blkcg specified by @blkcg_css.  Block layer will
+ * treat @bio as if it were issued by a task which belongs to the blkcg.
  *
- * Associate @bio with the blkg found from the bio's css and the request_queue.
- * If one is not found, bio_lookup_blkg creates the blkg.  This falls back to
- * the queue's root_blkg if association fails.
+ * This function takes an extra reference of @blkcg_css which will be put
+ * when @bio is released.  The caller must own @bio and is responsible for
+ * synchronizing calls to this function.
  */
-int bio_associate_create_blkg(struct request_queue *q, struct bio *bio)
+int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css)
 {
-       struct cgroup_subsys_state *css;
-       int ret = 0;
-
-       /* someone has already associated this bio with a blkg */
-       if (bio->bi_blkg)
-               return ret;
-
-       rcu_read_lock();
-
-       css = blkcg_css();
-
-       ret = __bio_associate_blkg_from_css(bio, css);
-
-       rcu_read_unlock();
-       return ret;
+       if (unlikely(bio->bi_css))
+               return -EBUSY;
+       css_get(blkcg_css);
+       bio->bi_css = blkcg_css;
+       return 0;
 }
+EXPORT_SYMBOL_GPL(bio_associate_blkcg);
 
 /**
- * bio_reassociate_blkg - reassociate a bio with a blkg from q
- * @q: request_queue where bio is going
+ * bio_associate_blkg - associate a bio with the specified blkg
  * @bio: target bio
+ * @blkg: the blkg to associate
  *
- * When submitting a bio, multiple recursive calls to make_request() may occur.
- * This causes the initial associate done in blkcg_bio_issue_check() to be
- * incorrect and reference the prior request_queue.  This performs reassociation
- * when this situation happens.
+ * Associate @bio with the blkg specified by @blkg.  This is the queue specific
+ * blkcg information associated with the @bio, a reference will be taken on the
+ * @blkg and will be freed when the bio is freed.
  */
-int bio_reassociate_blkg(struct request_queue *q, struct bio *bio)
+int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
 {
-       if (bio->bi_blkg) {
-               blkg_put(bio->bi_blkg);
-               bio->bi_blkg = NULL;
-       }
-
-       return bio_associate_create_blkg(q, bio);
+       if (unlikely(bio->bi_blkg))
+               return -EBUSY;
+       if (!blkg_try_get(blkg))
+               return -ENODEV;
+       bio->bi_blkg = blkg;
+       return 0;
 }
 
 /**
@@ -2113,6 +2029,10 @@ void bio_disassociate_task(struct bio *bio)
                put_io_context(bio->bi_ioc);
                bio->bi_ioc = NULL;
        }
+       if (bio->bi_css) {
+               css_put(bio->bi_css);
+               bio->bi_css = NULL;
+       }
        if (bio->bi_blkg) {
                blkg_put(bio->bi_blkg);
                bio->bi_blkg = NULL;
@@ -2120,16 +2040,16 @@ void bio_disassociate_task(struct bio *bio)
 }
 
 /**
- * bio_clone_blkg_association - clone blkg association from src to dst bio
+ * bio_clone_blkcg_association - clone blkcg association from src to dst bio
  * @dst: destination bio
  * @src: source bio
  */
-void bio_clone_blkg_association(struct bio *dst, struct bio *src)
+void bio_clone_blkcg_association(struct bio *dst, struct bio *src)
 {
-       if (src->bi_blkg)
-               bio_associate_blkg(dst, src->bi_blkg);
+       if (src->bi_css)
+               WARN_ON(bio_associate_blkcg(dst, src->bi_css));
 }
-EXPORT_SYMBOL_GPL(bio_clone_blkg_association);
+EXPORT_SYMBOL_GPL(bio_clone_blkcg_association);
 #endif /* CONFIG_BLK_CGROUP */
 
 static void __init biovec_init_slabs(void)
index 992da5592c6ed14208116b794975c75c2b3986a1..c630e02836a80d7d406778208c659aebda8fcf06 100644 (file)
@@ -84,37 +84,6 @@ static void blkg_free(struct blkcg_gq *blkg)
        kfree(blkg);
 }
 
-static void __blkg_release(struct rcu_head *rcu)
-{
-       struct blkcg_gq *blkg = container_of(rcu, struct blkcg_gq, rcu_head);
-
-       percpu_ref_exit(&blkg->refcnt);
-
-       /* release the blkcg and parent blkg refs this blkg has been holding */
-       css_put(&blkg->blkcg->css);
-       if (blkg->parent)
-               blkg_put(blkg->parent);
-
-       wb_congested_put(blkg->wb_congested);
-
-       blkg_free(blkg);
-}
-
-/*
- * A group is RCU protected, but having an rcu lock does not mean that one
- * can access all the fields of blkg and assume these are valid.  For
- * example, don't try to follow throtl_data and request queue links.
- *
- * Having a reference to blkg under an rcu allows accesses to only values
- * local to groups like group stats and group rate limits.
- */
-static void blkg_release(struct percpu_ref *ref)
-{
-       struct blkcg_gq *blkg = container_of(ref, struct blkcg_gq, refcnt);
-
-       call_rcu(&blkg->rcu_head, __blkg_release);
-}
-
 /**
  * blkg_alloc - allocate a blkg
  * @blkcg: block cgroup the new blkg is associated with
@@ -141,6 +110,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
        blkg->q = q;
        INIT_LIST_HEAD(&blkg->q_node);
        blkg->blkcg = blkcg;
+       atomic_set(&blkg->refcnt, 1);
 
        /* root blkg uses @q->root_rl, init rl only for !root blkgs */
        if (blkcg != &blkcg_root) {
@@ -247,11 +217,6 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
                blkg_get(blkg->parent);
        }
 
-       ret = percpu_ref_init(&blkg->refcnt, blkg_release, 0,
-                             GFP_NOWAIT | __GFP_NOWARN);
-       if (ret)
-               goto err_cancel_ref;
-
        /* invoke per-policy init */
        for (i = 0; i < BLKCG_MAX_POLS; i++) {
                struct blkcg_policy *pol = blkcg_policy[i];
@@ -284,8 +249,6 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
        blkg_put(blkg);
        return ERR_PTR(ret);
 
-err_cancel_ref:
-       percpu_ref_exit(&blkg->refcnt);
 err_put_congested:
        wb_congested_put(wb_congested);
 err_put_css:
@@ -296,7 +259,7 @@ err_free_blkg:
 }
 
 /**
- * __blkg_lookup_create - lookup blkg, try to create one if not there
+ * blkg_lookup_create - lookup blkg, try to create one if not there
  * @blkcg: blkcg of interest
  * @q: request_queue of interest
  *
@@ -305,11 +268,12 @@ err_free_blkg:
  * that all non-root blkg's have access to the parent blkg.  This function
  * should be called under RCU read lock and @q->queue_lock.
  *
- * Returns the blkg or the closest blkg if blkg_create fails as it walks
- * down from root.
+ * Returns pointer to the looked up or created blkg on success, ERR_PTR()
+ * value on error.  If @q is dead, returns ERR_PTR(-EINVAL).  If @q is not
+ * dead and bypassing, returns ERR_PTR(-EBUSY).
  */
-struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
-                                     struct request_queue *q)
+struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
+                                   struct request_queue *q)
 {
        struct blkcg_gq *blkg;
 
@@ -321,7 +285,7 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
         * we shouldn't allow anything to go through for a bypassing queue.
         */
        if (unlikely(blk_queue_bypass(q)))
-               return q->root_blkg;
+               return ERR_PTR(blk_queue_dying(q) ? -ENODEV : -EBUSY);
 
        blkg = __blkg_lookup(blkcg, q, true);
        if (blkg)
@@ -329,58 +293,23 @@ struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
 
        /*
         * Create blkgs walking down from blkcg_root to @blkcg, so that all
-        * non-root blkgs have access to their parents.  Returns the closest
-        * blkg to the intended blkg should blkg_create() fail.
+        * non-root blkgs have access to their parents.
         */
        while (true) {
                struct blkcg *pos = blkcg;
                struct blkcg *parent = blkcg_parent(blkcg);
-               struct blkcg_gq *ret_blkg = q->root_blkg;
-
-               while (parent) {
-                       blkg = __blkg_lookup(parent, q, false);
-                       if (blkg) {
-                               /* remember closest blkg */
-                               ret_blkg = blkg;
-                               break;
-                       }
+
+               while (parent && !__blkg_lookup(parent, q, false)) {
                        pos = parent;
                        parent = blkcg_parent(parent);
                }
 
                blkg = blkg_create(pos, q, NULL);
-               if (IS_ERR(blkg))
-                       return ret_blkg;
-               if (pos == blkcg)
+               if (pos == blkcg || IS_ERR(blkg))
                        return blkg;
        }
 }
 
-/**
- * blkg_lookup_create - find or create a blkg
- * @blkcg: target block cgroup
- * @q: target request_queue
- *
- * This looks up or creates the blkg representing the unique pair
- * of the blkcg and the request_queue.
- */
-struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
-                                   struct request_queue *q)
-{
-       struct blkcg_gq *blkg = blkg_lookup(blkcg, q);
-       unsigned long flags;
-
-       if (unlikely(!blkg)) {
-               spin_lock_irqsave(q->queue_lock, flags);
-
-               blkg = __blkg_lookup_create(blkcg, q);
-
-               spin_unlock_irqrestore(q->queue_lock, flags);
-       }
-
-       return blkg;
-}
-
 static void blkg_destroy(struct blkcg_gq *blkg)
 {
        struct blkcg *blkcg = blkg->blkcg;
@@ -424,7 +353,7 @@ static void blkg_destroy(struct blkcg_gq *blkg)
         * Put the reference taken at the time of creation so that when all
         * queues are gone, group can be destroyed.
         */
-       percpu_ref_kill(&blkg->refcnt);
+       blkg_put(blkg);
 }
 
 /**
@@ -451,6 +380,29 @@ static void blkg_destroy_all(struct request_queue *q)
        q->root_rl.blkg = NULL;
 }
 
+/*
+ * A group is RCU protected, but having an rcu lock does not mean that one
+ * can access all the fields of blkg and assume these are valid.  For
+ * example, don't try to follow throtl_data and request queue links.
+ *
+ * Having a reference to blkg under an rcu allows accesses to only values
+ * local to groups like group stats and group rate limits.
+ */
+void __blkg_release_rcu(struct rcu_head *rcu_head)
+{
+       struct blkcg_gq *blkg = container_of(rcu_head, struct blkcg_gq, rcu_head);
+
+       /* release the blkcg and parent blkg refs this blkg has been holding */
+       css_put(&blkg->blkcg->css);
+       if (blkg->parent)
+               blkg_put(blkg->parent);
+
+       wb_congested_put(blkg->wb_congested);
+
+       blkg_free(blkg);
+}
+EXPORT_SYMBOL_GPL(__blkg_release_rcu);
+
 /*
  * The next function used by blk_queue_for_each_rl().  It's a bit tricky
  * because the root blkg uses @q->root_rl instead of its own rl.
@@ -1796,7 +1748,8 @@ void blkcg_maybe_throttle_current(void)
        blkg = blkg_lookup(blkcg, q);
        if (!blkg)
                goto out;
-       if (!blkg_tryget(blkg))
+       blkg = blkg_try_get(blkg);
+       if (!blkg)
                goto out;
        rcu_read_unlock();
 
index bc6ea87d10e02cffcaedec7cc9d4567d88cdd6b6..ce12515f9b9b9930da4515ed8f70a4cf5f5b946f 100644 (file)
@@ -785,6 +785,9 @@ void blk_cleanup_queue(struct request_queue *q)
         * prevent that q->request_fn() gets invoked after draining finished.
         */
        blk_freeze_queue(q);
+
+       rq_qos_exit(q);
+
        spin_lock_irq(lock);
        queue_flag_set(QUEUE_FLAG_DEAD, q);
        spin_unlock_irq(lock);
@@ -2432,7 +2435,6 @@ blk_qc_t generic_make_request(struct bio *bio)
                        if (q)
                                blk_queue_exit(q);
                        q = bio->bi_disk->queue;
-                       bio_reassociate_blkg(q, bio);
                        flags = 0;
                        if (bio->bi_opf & REQ_NOWAIT)
                                flags = BLK_MQ_REQ_NOWAIT;
index 28f80d22752858a2b1fcdfefb5f079469ec480ee..38c35c32aff2dcf3fc0e9ac294a649f0be4a1cb1 100644 (file)
@@ -482,12 +482,34 @@ static void blkcg_iolatency_throttle(struct rq_qos *rqos, struct bio *bio,
                                     spinlock_t *lock)
 {
        struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
-       struct blkcg_gq *blkg = bio->bi_blkg;
+       struct blkcg *blkcg;
+       struct blkcg_gq *blkg;
+       struct request_queue *q = rqos->q;
        bool issue_as_root = bio_issue_as_root_blkg(bio);
 
        if (!blk_iolatency_enabled(blkiolat))
                return;
 
+       rcu_read_lock();
+       blkcg = bio_blkcg(bio);
+       bio_associate_blkcg(bio, &blkcg->css);
+       blkg = blkg_lookup(blkcg, q);
+       if (unlikely(!blkg)) {
+               if (!lock)
+                       spin_lock_irq(q->queue_lock);
+               blkg = blkg_lookup_create(blkcg, q);
+               if (IS_ERR(blkg))
+                       blkg = NULL;
+               if (!lock)
+                       spin_unlock_irq(q->queue_lock);
+       }
+       if (!blkg)
+               goto out;
+
+       bio_issue_init(&bio->bi_issue, bio_sectors(bio));
+       bio_associate_blkg(bio, blkg);
+out:
+       rcu_read_unlock();
        while (blkg && blkg->parent) {
                struct iolatency_grp *iolat = blkg_to_lat(blkg);
                if (!iolat) {
@@ -708,7 +730,7 @@ static void blkiolatency_timer_fn(struct timer_list *t)
                 * We could be exiting, don't access the pd unless we have a
                 * ref on the blkg.
                 */
-               if (!blkg_tryget(blkg))
+               if (!blkg_try_get(blkg))
                        continue;
 
                iolat = blkg_to_lat(blkg);
index 42a46744c11b45e4970bbe8a918fcf8b29d895d8..6b5ad275ed565de274746b1ef473f46a3a20a621 100644 (file)
@@ -714,6 +714,31 @@ static void blk_account_io_merge(struct request *req)
                part_stat_unlock();
        }
 }
+/*
+ * Two cases of handling DISCARD merge:
+ * If max_discard_segments > 1, the driver takes every bio
+ * as a range and send them to controller together. The ranges
+ * needn't to be contiguous.
+ * Otherwise, the bios/requests will be handled as same as
+ * others which should be contiguous.
+ */
+static inline bool blk_discard_mergable(struct request *req)
+{
+       if (req_op(req) == REQ_OP_DISCARD &&
+           queue_max_discard_segments(req->q) > 1)
+               return true;
+       return false;
+}
+
+enum elv_merge blk_try_req_merge(struct request *req, struct request *next)
+{
+       if (blk_discard_mergable(req))
+               return ELEVATOR_DISCARD_MERGE;
+       else if (blk_rq_pos(req) + blk_rq_sectors(req) == blk_rq_pos(next))
+               return ELEVATOR_BACK_MERGE;
+
+       return ELEVATOR_NO_MERGE;
+}
 
 /*
  * For non-mq, this has to be called with the request spinlock acquired.
@@ -731,12 +756,6 @@ static struct request *attempt_merge(struct request_queue *q,
        if (req_op(req) != req_op(next))
                return NULL;
 
-       /*
-        * not contiguous
-        */
-       if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next))
-               return NULL;
-
        if (rq_data_dir(req) != rq_data_dir(next)
            || req->rq_disk != next->rq_disk
            || req_no_special_merge(next))
@@ -760,11 +779,19 @@ static struct request *attempt_merge(struct request_queue *q,
         * counts here. Handle DISCARDs separately, as they
         * have separate settings.
         */
-       if (req_op(req) == REQ_OP_DISCARD) {
+
+       switch (blk_try_req_merge(req, next)) {
+       case ELEVATOR_DISCARD_MERGE:
                if (!req_attempt_discard_merge(q, req, next))
                        return NULL;
-       } else if (!ll_merge_requests_fn(q, req, next))
+               break;
+       case ELEVATOR_BACK_MERGE:
+               if (!ll_merge_requests_fn(q, req, next))
+                       return NULL;
+               break;
+       default:
                return NULL;
+       }
 
        /*
         * If failfast settings disagree or any of the two is already
@@ -888,8 +915,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 
 enum elv_merge blk_try_merge(struct request *rq, struct bio *bio)
 {
-       if (req_op(rq) == REQ_OP_DISCARD &&
-           queue_max_discard_segments(rq->q) > 1)
+       if (blk_discard_mergable(rq))
                return ELEVATOR_DISCARD_MERGE;
        else if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector)
                return ELEVATOR_BACK_MERGE;
index 0641533597f1b2cc389e6579a986d6df17115646..844a454a7b3a60a0c3186b589ab12daad0e9b3b8 100644 (file)
@@ -1007,8 +1007,6 @@ void blk_unregister_queue(struct gendisk *disk)
        kobject_del(&q->kobj);
        blk_trace_remove_sysfs(disk_to_dev(disk));
 
-       rq_qos_exit(q);
-
        mutex_lock(&q->sysfs_lock);
        if (q->request_fn || (q->mq_ops && q->elevator))
                elv_unregister_queue(q);
index 4bda70e8db48a9150880dc04a8a1f3fcb8844ac6..db1a3a2ae00617fbe1e4804bbfd327e37ce55737 100644 (file)
@@ -2115,11 +2115,21 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td)
 }
 #endif
 
+static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
+{
+#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
+       /* fallback to root_blkg if we fail to get a blkg ref */
+       if (bio->bi_css && (bio_associate_blkg(bio, tg_to_blkg(tg)) == -ENODEV))
+               bio_associate_blkg(bio, bio->bi_disk->queue->root_blkg);
+       bio_issue_init(&bio->bi_issue, bio_sectors(bio));
+#endif
+}
+
 bool blk_throtl_bio(struct request_queue *q, struct blkcg_gq *blkg,
                    struct bio *bio)
 {
        struct throtl_qnode *qn = NULL;
-       struct throtl_grp *tg = blkg_to_tg(blkg);
+       struct throtl_grp *tg = blkg_to_tg(blkg ?: q->root_blkg);
        struct throtl_service_queue *sq;
        bool rw = bio_data_dir(bio);
        bool throttled = false;
@@ -2138,6 +2148,7 @@ bool blk_throtl_bio(struct request_queue *q, struct blkcg_gq *blkg,
        if (unlikely(blk_queue_bypass(q)))
                goto out_unlock;
 
+       blk_throtl_assoc_bio(tg, bio);
        blk_throtl_update_idletime(tg);
 
        sq = &tg->service_queue;
index cf49fe02f65cd017eb2132fd3475ba29a5d3cf75..36869afc258ccf6ea609e0e74db6cea56e6d2c34 100644 (file)
@@ -276,9 +276,7 @@ static struct bio *bounce_clone_bio(struct bio *bio_src, gfp_t gfp_mask,
                }
        }
 
-       bio_clone_blkg_association(bio, bio_src);
-
-       blkcg_bio_issue_init(bio);
+       bio_clone_blkcg_association(bio, bio_src);
 
        return bio;
 }
index 6a3d87dd3c1ac42abf04223ea14eb673e7c5ec5c..ed41aa978c4abc66cd2845f4c18177c97387a881 100644 (file)
@@ -3759,7 +3759,7 @@ static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
        uint64_t serial_nr;
 
        rcu_read_lock();
-       serial_nr = __bio_blkcg(bio)->css.serial_nr;
+       serial_nr = bio_blkcg(bio)->css.serial_nr;
        rcu_read_unlock();
 
        /*
@@ -3824,7 +3824,7 @@ cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct cfq_io_cq *cic,
        struct cfq_group *cfqg;
 
        rcu_read_lock();
-       cfqg = cfq_lookup_cfqg(cfqd, __bio_blkcg(bio));
+       cfqg = cfq_lookup_cfqg(cfqd, bio_blkcg(bio));
        if (!cfqg) {
                cfqq = &cfqd->oom_cfqq;
                goto out;
index f3702e533ff41044694625aad813abc58b8af4dd..be70ca6c85d31e89329b032ce7445aa1c2b85f32 100644 (file)
@@ -21,6 +21,18 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
          appropriate hash algorithms (such as SHA-1) must be available.
          ENOPKG will be reported if the requisite algorithm is unavailable.
 
+config ASYMMETRIC_TPM_KEY_SUBTYPE
+       tristate "Asymmetric TPM backed private key subtype"
+       depends on TCG_TPM
+       depends on TRUSTED_KEYS
+       select CRYPTO_HMAC
+       select CRYPTO_SHA1
+       select CRYPTO_HASH_INFO
+       help
+         This option provides support for TPM backed private key type handling.
+         Operations such as sign, verify, encrypt, decrypt are performed by
+         the TPM after the private key is loaded.
+
 config X509_CERTIFICATE_PARSER
        tristate "X.509 certificate parser"
        depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
@@ -31,6 +43,25 @@ config X509_CERTIFICATE_PARSER
          data and provides the ability to instantiate a crypto key from a
          public key packet found inside the certificate.
 
+config PKCS8_PRIVATE_KEY_PARSER
+       tristate "PKCS#8 private key parser"
+       depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+       select ASN1
+       select OID_REGISTRY
+       help
+         This option provides support for parsing PKCS#8 format blobs for
+         private key data and provides the ability to instantiate a crypto key
+         from that data.
+
+config TPM_KEY_PARSER
+       tristate "TPM private key parser"
+       depends on ASYMMETRIC_TPM_KEY_SUBTYPE
+       select ASN1
+       help
+         This option provides support for parsing TPM format blobs for
+         private key data and provides the ability to instantiate a crypto key
+         from that data.
+
 config PKCS7_MESSAGE_PARSER
        tristate "PKCS#7 message parser"
        depends on X509_CERTIFICATE_PARSER
index d4b2e1b2dc650837ae98489799a3431ee1ce70d4..28b91adba2aed35f830e6c6f7d356004f1d5248c 100644 (file)
@@ -11,6 +11,7 @@ asymmetric_keys-y := \
        signature.o
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
+obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o
 
 #
 # X.509 Certificate handling
@@ -29,6 +30,19 @@ $(obj)/x509_cert_parser.o: \
 $(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h
 $(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h
 
+#
+# PKCS#8 private key handling
+#
+obj-$(CONFIG_PKCS8_PRIVATE_KEY_PARSER) += pkcs8_key_parser.o
+pkcs8_key_parser-y := \
+       pkcs8.asn1.o \
+       pkcs8_parser.o
+
+$(obj)/pkcs8_parser.o: $(obj)/pkcs8.asn1.h
+$(obj)/pkcs8-asn1.o: $(obj)/pkcs8.asn1.c $(obj)/pkcs8.asn1.h
+
+clean-files    += pkcs8.asn1.c pkcs8.asn1.h
+
 #
 # PKCS#7 message handling
 #
@@ -61,3 +75,14 @@ verify_signed_pefile-y := \
 
 $(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h
 $(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h
+
+#
+# TPM private key parsing
+#
+obj-$(CONFIG_TPM_KEY_PARSER) += tpm_key_parser.o
+tpm_key_parser-y := \
+       tpm.asn1.o \
+       tpm_parser.o
+
+$(obj)/tpm_parser.o: $(obj)/tpm.asn1.h
+$(obj)/tpm.asn1.o: $(obj)/tpm.asn1.c $(obj)/tpm.asn1.h
diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c
new file mode 100644 (file)
index 0000000..5d4c270
--- /dev/null
@@ -0,0 +1,988 @@
+// SPDX-License-Identifier: GPL-2.0
+#define pr_fmt(fmt) "ASYM-TPM: "fmt
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <linux/scatterlist.h>
+#include <linux/tpm.h>
+#include <linux/tpm_command.h>
+#include <crypto/akcipher.h>
+#include <crypto/hash.h>
+#include <crypto/sha.h>
+#include <asm/unaligned.h>
+#include <keys/asymmetric-subtype.h>
+#include <keys/trusted.h>
+#include <crypto/asym_tpm_subtype.h>
+#include <crypto/public_key.h>
+
+#define TPM_ORD_FLUSHSPECIFIC  186
+#define TPM_ORD_LOADKEY2       65
+#define TPM_ORD_UNBIND         30
+#define TPM_ORD_SIGN           60
+#define TPM_LOADKEY2_SIZE              59
+#define TPM_FLUSHSPECIFIC_SIZE         18
+#define TPM_UNBIND_SIZE                        63
+#define TPM_SIGN_SIZE                  63
+
+#define TPM_RT_KEY                      0x00000001
+
+/*
+ * Load a TPM key from the blob provided by userspace
+ */
+static int tpm_loadkey2(struct tpm_buf *tb,
+                       uint32_t keyhandle, unsigned char *keyauth,
+                       const unsigned char *keyblob, int keybloblen,
+                       uint32_t *newhandle)
+{
+       unsigned char nonceodd[TPM_NONCE_SIZE];
+       unsigned char enonce[TPM_NONCE_SIZE];
+       unsigned char authdata[SHA1_DIGEST_SIZE];
+       uint32_t authhandle = 0;
+       unsigned char cont = 0;
+       uint32_t ordinal;
+       int ret;
+
+       ordinal = htonl(TPM_ORD_LOADKEY2);
+
+       /* session for loading the key */
+       ret = oiap(tb, &authhandle, enonce);
+       if (ret < 0) {
+               pr_info("oiap failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* generate odd nonce */
+       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
+       if (ret < 0) {
+               pr_info("tpm_get_random failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* calculate authorization HMAC value */
+       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
+                          nonceodd, cont, sizeof(uint32_t), &ordinal,
+                          keybloblen, keyblob, 0, 0);
+       if (ret < 0)
+               return ret;
+
+       /* build the request buffer */
+       INIT_BUF(tb);
+       store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
+       store32(tb, TPM_LOADKEY2_SIZE + keybloblen);
+       store32(tb, TPM_ORD_LOADKEY2);
+       store32(tb, keyhandle);
+       storebytes(tb, keyblob, keybloblen);
+       store32(tb, authhandle);
+       storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+       store8(tb, cont);
+       storebytes(tb, authdata, SHA1_DIGEST_SIZE);
+
+       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       if (ret < 0) {
+               pr_info("authhmac failed (%d)\n", ret);
+               return ret;
+       }
+
+       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
+                            SHA1_DIGEST_SIZE, 0, 0);
+       if (ret < 0) {
+               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
+               return ret;
+       }
+
+       *newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
+       return 0;
+}
+
+/*
+ * Execute the FlushSpecific TPM command
+ */
+static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
+{
+       INIT_BUF(tb);
+       store16(tb, TPM_TAG_RQU_COMMAND);
+       store32(tb, TPM_FLUSHSPECIFIC_SIZE);
+       store32(tb, TPM_ORD_FLUSHSPECIFIC);
+       store32(tb, handle);
+       store32(tb, TPM_RT_KEY);
+
+       return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+}
+
+/*
+ * Decrypt a blob provided by userspace using a specific key handle.
+ * The handle is a well known handle or previously loaded by e.g. LoadKey2
+ */
+static int tpm_unbind(struct tpm_buf *tb,
+                       uint32_t keyhandle, unsigned char *keyauth,
+                       const unsigned char *blob, uint32_t bloblen,
+                       void *out, uint32_t outlen)
+{
+       unsigned char nonceodd[TPM_NONCE_SIZE];
+       unsigned char enonce[TPM_NONCE_SIZE];
+       unsigned char authdata[SHA1_DIGEST_SIZE];
+       uint32_t authhandle = 0;
+       unsigned char cont = 0;
+       uint32_t ordinal;
+       uint32_t datalen;
+       int ret;
+
+       ordinal = htonl(TPM_ORD_UNBIND);
+       datalen = htonl(bloblen);
+
+       /* session for loading the key */
+       ret = oiap(tb, &authhandle, enonce);
+       if (ret < 0) {
+               pr_info("oiap failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* generate odd nonce */
+       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
+       if (ret < 0) {
+               pr_info("tpm_get_random failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* calculate authorization HMAC value */
+       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
+                          nonceodd, cont, sizeof(uint32_t), &ordinal,
+                          sizeof(uint32_t), &datalen,
+                          bloblen, blob, 0, 0);
+       if (ret < 0)
+               return ret;
+
+       /* build the request buffer */
+       INIT_BUF(tb);
+       store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
+       store32(tb, TPM_UNBIND_SIZE + bloblen);
+       store32(tb, TPM_ORD_UNBIND);
+       store32(tb, keyhandle);
+       store32(tb, bloblen);
+       storebytes(tb, blob, bloblen);
+       store32(tb, authhandle);
+       storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+       store8(tb, cont);
+       storebytes(tb, authdata, SHA1_DIGEST_SIZE);
+
+       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       if (ret < 0) {
+               pr_info("authhmac failed (%d)\n", ret);
+               return ret;
+       }
+
+       datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
+
+       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
+                            keyauth, SHA1_DIGEST_SIZE,
+                            sizeof(uint32_t), TPM_DATA_OFFSET,
+                            datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
+                            0, 0);
+       if (ret < 0) {
+               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
+               return ret;
+       }
+
+       memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
+              min(outlen, datalen));
+
+       return datalen;
+}
+
+/*
+ * Sign a blob provided by userspace (that has had the hash function applied)
+ * using a specific key handle.  The handle is assumed to have been previously
+ * loaded by e.g. LoadKey2.
+ *
+ * Note that the key signature scheme of the used key should be set to
+ * TPM_SS_RSASSAPKCS1v15_DER.  This allows the hashed input to be of any size
+ * up to key_length_in_bytes - 11 and not be limited to size 20 like the
+ * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
+ */
+static int tpm_sign(struct tpm_buf *tb,
+                   uint32_t keyhandle, unsigned char *keyauth,
+                   const unsigned char *blob, uint32_t bloblen,
+                   void *out, uint32_t outlen)
+{
+       unsigned char nonceodd[TPM_NONCE_SIZE];
+       unsigned char enonce[TPM_NONCE_SIZE];
+       unsigned char authdata[SHA1_DIGEST_SIZE];
+       uint32_t authhandle = 0;
+       unsigned char cont = 0;
+       uint32_t ordinal;
+       uint32_t datalen;
+       int ret;
+
+       ordinal = htonl(TPM_ORD_SIGN);
+       datalen = htonl(bloblen);
+
+       /* session for loading the key */
+       ret = oiap(tb, &authhandle, enonce);
+       if (ret < 0) {
+               pr_info("oiap failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* generate odd nonce */
+       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
+       if (ret < 0) {
+               pr_info("tpm_get_random failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* calculate authorization HMAC value */
+       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
+                          nonceodd, cont, sizeof(uint32_t), &ordinal,
+                          sizeof(uint32_t), &datalen,
+                          bloblen, blob, 0, 0);
+       if (ret < 0)
+               return ret;
+
+       /* build the request buffer */
+       INIT_BUF(tb);
+       store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
+       store32(tb, TPM_SIGN_SIZE + bloblen);
+       store32(tb, TPM_ORD_SIGN);
+       store32(tb, keyhandle);
+       store32(tb, bloblen);
+       storebytes(tb, blob, bloblen);
+       store32(tb, authhandle);
+       storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+       store8(tb, cont);
+       storebytes(tb, authdata, SHA1_DIGEST_SIZE);
+
+       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       if (ret < 0) {
+               pr_info("authhmac failed (%d)\n", ret);
+               return ret;
+       }
+
+       datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
+
+       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
+                            keyauth, SHA1_DIGEST_SIZE,
+                            sizeof(uint32_t), TPM_DATA_OFFSET,
+                            datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
+                            0, 0);
+       if (ret < 0) {
+               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
+               return ret;
+       }
+
+       memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
+              min(datalen, outlen));
+
+       return datalen;
+}
+/*
+ * Maximum buffer size for the BER/DER encoded public key.  The public key
+ * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
+ * bit key and e is usually 65537
+ * The encoding overhead is:
+ * - max 4 bytes for SEQUENCE
+ *   - max 4 bytes for INTEGER n type/length
+ *     - 257 bytes of n
+ *   - max 2 bytes for INTEGER e type/length
+ *     - 3 bytes of e
+ */
+#define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3)
+
+/*
+ * Provide a part of a description of the key for /proc/keys.
+ */
+static void asym_tpm_describe(const struct key *asymmetric_key,
+                             struct seq_file *m)
+{
+       struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];
+
+       if (!tk)
+               return;
+
+       seq_printf(m, "TPM1.2/Blob");
+}
+
+static void asym_tpm_destroy(void *payload0, void *payload3)
+{
+       struct tpm_key *tk = payload0;
+
+       if (!tk)
+               return;
+
+       kfree(tk->blob);
+       tk->blob_len = 0;
+
+       kfree(tk);
+}
+
+/* How many bytes will it take to encode the length */
+static inline uint32_t definite_length(uint32_t len)
+{
+       if (len <= 127)
+               return 1;
+       if (len <= 255)
+               return 2;
+       return 3;
+}
+
+static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
+                                        uint32_t len)
+{
+       *buf++ = tag;
+
+       if (len <= 127) {
+               buf[0] = len;
+               return buf + 1;
+       }
+
+       if (len <= 255) {
+               buf[0] = 0x81;
+               buf[1] = len;
+               return buf + 2;
+       }
+
+       buf[0] = 0x82;
+       put_unaligned_be16(len, buf + 1);
+       return buf + 3;
+}
+
+static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
+{
+       uint8_t *cur = buf;
+       uint32_t n_len = definite_length(len) + 1 + len + 1;
+       uint32_t e_len = definite_length(3) + 1 + 3;
+       uint8_t e[3] = { 0x01, 0x00, 0x01 };
+
+       /* SEQUENCE */
+       cur = encode_tag_length(cur, 0x30, n_len + e_len);
+       /* INTEGER n */
+       cur = encode_tag_length(cur, 0x02, len + 1);
+       cur[0] = 0x00;
+       memcpy(cur + 1, pub_key, len);
+       cur += len + 1;
+       cur = encode_tag_length(cur, 0x02, sizeof(e));
+       memcpy(cur, e, sizeof(e));
+       cur += sizeof(e);
+
+       return cur - buf;
+}
+
+/*
+ * Determine the crypto algorithm name.
+ */
+static int determine_akcipher(const char *encoding, const char *hash_algo,
+                             char alg_name[CRYPTO_MAX_ALG_NAME])
+{
+       if (strcmp(encoding, "pkcs1") == 0) {
+               if (!hash_algo) {
+                       strcpy(alg_name, "pkcs1pad(rsa)");
+                       return 0;
+               }
+
+               if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
+                            hash_algo) >= CRYPTO_MAX_ALG_NAME)
+                       return -EINVAL;
+
+               return 0;
+       }
+
+       if (strcmp(encoding, "raw") == 0) {
+               strcpy(alg_name, "rsa");
+               return 0;
+       }
+
+       return -ENOPKG;
+}
+
+/*
+ * Query information about a key.
+ */
+static int tpm_key_query(const struct kernel_pkey_params *params,
+                        struct kernel_pkey_query *info)
+{
+       struct tpm_key *tk = params->key->payload.data[asym_crypto];
+       int ret;
+       char alg_name[CRYPTO_MAX_ALG_NAME];
+       struct crypto_akcipher *tfm;
+       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
+       uint32_t der_pub_key_len;
+       int len;
+
+       /* TPM only works on private keys, public keys still done in software */
+       ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
+       if (ret < 0)
+               return ret;
+
+       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
+                                        der_pub_key);
+
+       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+       if (ret < 0)
+               goto error_free_tfm;
+
+       len = crypto_akcipher_maxsize(tfm);
+
+       info->key_size = tk->key_len;
+       info->max_data_size = tk->key_len / 8;
+       info->max_sig_size = len;
+       info->max_enc_size = len;
+       info->max_dec_size = tk->key_len / 8;
+
+       info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
+                             KEYCTL_SUPPORTS_DECRYPT |
+                             KEYCTL_SUPPORTS_VERIFY |
+                             KEYCTL_SUPPORTS_SIGN;
+
+       ret = 0;
+error_free_tfm:
+       crypto_free_akcipher(tfm);
+       pr_devel("<==%s() = %d\n", __func__, ret);
+       return ret;
+}
+
+/*
+ * Encryption operation is performed with the public key.  Hence it is done
+ * in software
+ */
+static int tpm_key_encrypt(struct tpm_key *tk,
+                          struct kernel_pkey_params *params,
+                          const void *in, void *out)
+{
+       char alg_name[CRYPTO_MAX_ALG_NAME];
+       struct crypto_akcipher *tfm;
+       struct akcipher_request *req;
+       struct crypto_wait cwait;
+       struct scatterlist in_sg, out_sg;
+       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
+       uint32_t der_pub_key_len;
+       int ret;
+
+       pr_devel("==>%s()\n", __func__);
+
+       ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
+       if (ret < 0)
+               return ret;
+
+       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
+                                        der_pub_key);
+
+       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+       if (ret < 0)
+               goto error_free_tfm;
+
+       req = akcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req)
+               goto error_free_tfm;
+
+       sg_init_one(&in_sg, in, params->in_len);
+       sg_init_one(&out_sg, out, params->out_len);
+       akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
+                                  params->out_len);
+       crypto_init_wait(&cwait);
+       akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+                                     CRYPTO_TFM_REQ_MAY_SLEEP,
+                                     crypto_req_done, &cwait);
+
+       ret = crypto_akcipher_encrypt(req);
+       ret = crypto_wait_req(ret, &cwait);
+
+       if (ret == 0)
+               ret = req->dst_len;
+
+       akcipher_request_free(req);
+error_free_tfm:
+       crypto_free_akcipher(tfm);
+       pr_devel("<==%s() = %d\n", __func__, ret);
+       return ret;
+}
+
+/*
+ * Decryption operation is performed with the private key in the TPM.
+ */
+static int tpm_key_decrypt(struct tpm_key *tk,
+                          struct kernel_pkey_params *params,
+                          const void *in, void *out)
+{
+       struct tpm_buf *tb;
+       uint32_t keyhandle;
+       uint8_t srkauth[SHA1_DIGEST_SIZE];
+       uint8_t keyauth[SHA1_DIGEST_SIZE];
+       int r;
+
+       pr_devel("==>%s()\n", __func__);
+
+       if (params->hash_algo)
+               return -ENOPKG;
+
+       if (strcmp(params->encoding, "pkcs1"))
+               return -ENOPKG;
+
+       tb = kzalloc(sizeof(*tb), GFP_KERNEL);
+       if (!tb)
+               return -ENOMEM;
+
+       /* TODO: Handle a non-all zero SRK authorization */
+       memset(srkauth, 0, sizeof(srkauth));
+
+       r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
+                               tk->blob, tk->blob_len, &keyhandle);
+       if (r < 0) {
+               pr_devel("loadkey2 failed (%d)\n", r);
+               goto error;
+       }
+
+       /* TODO: Handle a non-all zero key authorization */
+       memset(keyauth, 0, sizeof(keyauth));
+
+       r = tpm_unbind(tb, keyhandle, keyauth,
+                      in, params->in_len, out, params->out_len);
+       if (r < 0)
+               pr_devel("tpm_unbind failed (%d)\n", r);
+
+       if (tpm_flushspecific(tb, keyhandle) < 0)
+               pr_devel("flushspecific failed (%d)\n", r);
+
+error:
+       kzfree(tb);
+       pr_devel("<==%s() = %d\n", __func__, r);
+       return r;
+}
+
+/*
+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
+ */
+static const u8 digest_info_md5[] = {
+       0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
+       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
+       0x05, 0x00, 0x04, 0x10
+};
+
+static const u8 digest_info_sha1[] = {
+       0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+       0x2b, 0x0e, 0x03, 0x02, 0x1a,
+       0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 digest_info_rmd160[] = {
+       0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+       0x2b, 0x24, 0x03, 0x02, 0x01,
+       0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 digest_info_sha224[] = {
+       0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+       0x05, 0x00, 0x04, 0x1c
+};
+
+static const u8 digest_info_sha256[] = {
+       0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+       0x05, 0x00, 0x04, 0x20
+};
+
+static const u8 digest_info_sha384[] = {
+       0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+       0x05, 0x00, 0x04, 0x30
+};
+
+static const u8 digest_info_sha512[] = {
+       0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+       0x05, 0x00, 0x04, 0x40
+};
+
+static const struct asn1_template {
+       const char      *name;
+       const u8        *data;
+       size_t          size;
+} asn1_templates[] = {
+#define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
+       _(md5),
+       _(sha1),
+       _(rmd160),
+       _(sha256),
+       _(sha384),
+       _(sha512),
+       _(sha224),
+       { NULL }
+#undef _
+};
+
+static const struct asn1_template *lookup_asn1(const char *name)
+{
+       const struct asn1_template *p;
+
+       for (p = asn1_templates; p->name; p++)
+               if (strcmp(name, p->name) == 0)
+                       return p;
+       return NULL;
+}
+
+/*
+ * Sign operation is performed with the private key in the TPM.
+ */
+static int tpm_key_sign(struct tpm_key *tk,
+                       struct kernel_pkey_params *params,
+                       const void *in, void *out)
+{
+       struct tpm_buf *tb;
+       uint32_t keyhandle;
+       uint8_t srkauth[SHA1_DIGEST_SIZE];
+       uint8_t keyauth[SHA1_DIGEST_SIZE];
+       void *asn1_wrapped = NULL;
+       uint32_t in_len = params->in_len;
+       int r;
+
+       pr_devel("==>%s()\n", __func__);
+
+       if (strcmp(params->encoding, "pkcs1"))
+               return -ENOPKG;
+
+       if (params->hash_algo) {
+               const struct asn1_template *asn1 =
+                                               lookup_asn1(params->hash_algo);
+
+               if (!asn1)
+                       return -ENOPKG;
+
+               /* request enough space for the ASN.1 template + input hash */
+               asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
+               if (!asn1_wrapped)
+                       return -ENOMEM;
+
+               /* Copy ASN.1 template, then the input */
+               memcpy(asn1_wrapped, asn1->data, asn1->size);
+               memcpy(asn1_wrapped + asn1->size, in, in_len);
+
+               in = asn1_wrapped;
+               in_len += asn1->size;
+       }
+
+       if (in_len > tk->key_len / 8 - 11) {
+               r = -EOVERFLOW;
+               goto error_free_asn1_wrapped;
+       }
+
+       r = -ENOMEM;
+       tb = kzalloc(sizeof(*tb), GFP_KERNEL);
+       if (!tb)
+               goto error_free_asn1_wrapped;
+
+       /* TODO: Handle a non-all zero SRK authorization */
+       memset(srkauth, 0, sizeof(srkauth));
+
+       r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
+                        tk->blob, tk->blob_len, &keyhandle);
+       if (r < 0) {
+               pr_devel("loadkey2 failed (%d)\n", r);
+               goto error_free_tb;
+       }
+
+       /* TODO: Handle a non-all zero key authorization */
+       memset(keyauth, 0, sizeof(keyauth));
+
+       r = tpm_sign(tb, keyhandle, keyauth, in, in_len, out, params->out_len);
+       if (r < 0)
+               pr_devel("tpm_sign failed (%d)\n", r);
+
+       if (tpm_flushspecific(tb, keyhandle) < 0)
+               pr_devel("flushspecific failed (%d)\n", r);
+
+error_free_tb:
+       kzfree(tb);
+error_free_asn1_wrapped:
+       kfree(asn1_wrapped);
+       pr_devel("<==%s() = %d\n", __func__, r);
+       return r;
+}
+
+/*
+ * Do encryption, decryption and signing ops.
+ */
+static int tpm_key_eds_op(struct kernel_pkey_params *params,
+                         const void *in, void *out)
+{
+       struct tpm_key *tk = params->key->payload.data[asym_crypto];
+       int ret = -EOPNOTSUPP;
+
+       /* Perform the encryption calculation. */
+       switch (params->op) {
+       case kernel_pkey_encrypt:
+               ret = tpm_key_encrypt(tk, params, in, out);
+               break;
+       case kernel_pkey_decrypt:
+               ret = tpm_key_decrypt(tk, params, in, out);
+               break;
+       case kernel_pkey_sign:
+               ret = tpm_key_sign(tk, params, in, out);
+               break;
+       default:
+               BUG();
+       }
+
+       return ret;
+}
+
+/*
+ * Verify a signature using a public key.
+ */
+static int tpm_key_verify_signature(const struct key *key,
+                                   const struct public_key_signature *sig)
+{
+       const struct tpm_key *tk = key->payload.data[asym_crypto];
+       struct crypto_wait cwait;
+       struct crypto_akcipher *tfm;
+       struct akcipher_request *req;
+       struct scatterlist sig_sg, digest_sg;
+       char alg_name[CRYPTO_MAX_ALG_NAME];
+       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
+       uint32_t der_pub_key_len;
+       void *output;
+       unsigned int outlen;
+       int ret;
+
+       pr_devel("==>%s()\n", __func__);
+
+       BUG_ON(!tk);
+       BUG_ON(!sig);
+       BUG_ON(!sig->s);
+
+       if (!sig->digest)
+               return -ENOPKG;
+
+       ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
+       if (ret < 0)
+               return ret;
+
+       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
+                                        der_pub_key);
+
+       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+       if (ret < 0)
+               goto error_free_tfm;
+
+       ret = -ENOMEM;
+       req = akcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req)
+               goto error_free_tfm;
+
+       ret = -ENOMEM;
+       outlen = crypto_akcipher_maxsize(tfm);
+       output = kmalloc(outlen, GFP_KERNEL);
+       if (!output)
+               goto error_free_req;
+
+       sg_init_one(&sig_sg, sig->s, sig->s_size);
+       sg_init_one(&digest_sg, output, outlen);
+       akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size,
+                                  outlen);
+       crypto_init_wait(&cwait);
+       akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+                                     CRYPTO_TFM_REQ_MAY_SLEEP,
+                                     crypto_req_done, &cwait);
+
+       /* Perform the verification calculation.  This doesn't actually do the
+        * verification, but rather calculates the hash expected by the
+        * signature and returns that to us.
+        */
+       ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
+       if (ret)
+               goto out_free_output;
+
+       /* Do the actual verification step. */
+       if (req->dst_len != sig->digest_size ||
+           memcmp(sig->digest, output, sig->digest_size) != 0)
+               ret = -EKEYREJECTED;
+
+out_free_output:
+       kfree(output);
+error_free_req:
+       akcipher_request_free(req);
+error_free_tfm:
+       crypto_free_akcipher(tfm);
+       pr_devel("<==%s() = %d\n", __func__, ret);
+       if (WARN_ON_ONCE(ret > 0))
+               ret = -EINVAL;
+       return ret;
+}
+
+/*
+ * Parse enough information out of TPM_KEY structure:
+ * TPM_STRUCT_VER -> 4 bytes
+ * TPM_KEY_USAGE -> 2 bytes
+ * TPM_KEY_FLAGS -> 4 bytes
+ * TPM_AUTH_DATA_USAGE -> 1 byte
+ * TPM_KEY_PARMS -> variable
+ * UINT32 PCRInfoSize -> 4 bytes
+ * BYTE* -> PCRInfoSize bytes
+ * TPM_STORE_PUBKEY
+ * UINT32 encDataSize;
+ * BYTE* -> encDataSize;
+ *
+ * TPM_KEY_PARMS:
+ * TPM_ALGORITHM_ID -> 4 bytes
+ * TPM_ENC_SCHEME -> 2 bytes
+ * TPM_SIG_SCHEME -> 2 bytes
+ * UINT32 parmSize -> 4 bytes
+ * BYTE* -> variable
+ */
+static int extract_key_parameters(struct tpm_key *tk)
+{
+       const void *cur = tk->blob;
+       uint32_t len = tk->blob_len;
+       const void *pub_key;
+       uint32_t sz;
+       uint32_t key_len;
+
+       if (len < 11)
+               return -EBADMSG;
+
+       /* Ensure this is a legacy key */
+       if (get_unaligned_be16(cur + 4) != 0x0015)
+               return -EBADMSG;
+
+       /* Skip to TPM_KEY_PARMS */
+       cur += 11;
+       len -= 11;
+
+       if (len < 12)
+               return -EBADMSG;
+
+       /* Make sure this is an RSA key */
+       if (get_unaligned_be32(cur) != 0x00000001)
+               return -EBADMSG;
+
+       /* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
+       if (get_unaligned_be16(cur + 4) != 0x0002)
+               return -EBADMSG;
+
+       /* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
+       if (get_unaligned_be16(cur + 6) != 0x0003)
+               return -EBADMSG;
+
+       sz = get_unaligned_be32(cur + 8);
+       if (len < sz + 12)
+               return -EBADMSG;
+
+       /* Move to TPM_RSA_KEY_PARMS */
+       len -= 12;
+       cur += 12;
+
+       /* Grab the RSA key length */
+       key_len = get_unaligned_be32(cur);
+
+       switch (key_len) {
+       case 512:
+       case 1024:
+       case 1536:
+       case 2048:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Move just past TPM_KEY_PARMS */
+       cur += sz;
+       len -= sz;
+
+       if (len < 4)
+               return -EBADMSG;
+
+       sz = get_unaligned_be32(cur);
+       if (len < 4 + sz)
+               return -EBADMSG;
+
+       /* Move to TPM_STORE_PUBKEY */
+       cur += 4 + sz;
+       len -= 4 + sz;
+
+       /* Grab the size of the public key, it should jive with the key size */
+       sz = get_unaligned_be32(cur);
+       if (sz > 256)
+               return -EINVAL;
+
+       pub_key = cur + 4;
+
+       tk->key_len = key_len;
+       tk->pub_key = pub_key;
+       tk->pub_key_len = sz;
+
+       return 0;
+}
+
+/* Given the blob, parse it and load it into the TPM */
+struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
+{
+       int r;
+       struct tpm_key *tk;
+
+       r = tpm_is_tpm2(NULL);
+       if (r < 0)
+               goto error;
+
+       /* We don't support TPM2 yet */
+       if (r > 0) {
+               r = -ENODEV;
+               goto error;
+       }
+
+       r = -ENOMEM;
+       tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
+       if (!tk)
+               goto error;
+
+       tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
+       if (!tk->blob)
+               goto error_memdup;
+
+       tk->blob_len = blob_len;
+
+       r = extract_key_parameters(tk);
+       if (r < 0)
+               goto error_extract;
+
+       return tk;
+
+error_extract:
+       kfree(tk->blob);
+       tk->blob_len = 0;
+error_memdup:
+       kfree(tk);
+error:
+       return ERR_PTR(r);
+}
+EXPORT_SYMBOL_GPL(tpm_key_create);
+
+/*
+ * TPM-based asymmetric key subtype
+ */
+struct asymmetric_key_subtype asym_tpm_subtype = {
+       .owner                  = THIS_MODULE,
+       .name                   = "asym_tpm",
+       .name_len               = sizeof("asym_tpm") - 1,
+       .describe               = asym_tpm_describe,
+       .destroy                = asym_tpm_destroy,
+       .query                  = tpm_key_query,
+       .eds_op                 = tpm_key_eds_op,
+       .verify_signature       = tpm_key_verify_signature,
+};
+EXPORT_SYMBOL_GPL(asym_tpm_subtype);
+
+MODULE_DESCRIPTION("TPM based asymmetric key subtype");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
index ca8e9ac34ce621613d29de02ba051eba593e7fc6..7be1ccf4fa9f2234c290e9bcffef773f176354aa 100644 (file)
@@ -16,3 +16,6 @@ extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
 extern int __asymmetric_key_hex_to_key_id(const char *id,
                                          struct asymmetric_key_id *match_id,
                                          size_t hexlen);
+
+extern int asymmetric_key_eds_op(struct kernel_pkey_params *params,
+                                const void *in, void *out);
index 26539e9a8bda41c37a664490e037f2365da7f15c..69a0788a7de5d08eddc6ad82451f2515ed94f6d4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/ctype.h>
 #include <keys/system_keyring.h>
+#include <keys/user-type.h>
 #include "asymmetric_keys.h"
 
 MODULE_LICENSE("GPL");
@@ -538,6 +539,45 @@ out:
        return ret;
 }
 
+int asymmetric_key_eds_op(struct kernel_pkey_params *params,
+                         const void *in, void *out)
+{
+       const struct asymmetric_key_subtype *subtype;
+       struct key *key = params->key;
+       int ret;
+
+       pr_devel("==>%s()\n", __func__);
+
+       if (key->type != &key_type_asymmetric)
+               return -EINVAL;
+       subtype = asymmetric_key_subtype(key);
+       if (!subtype ||
+           !key->payload.data[0])
+               return -EINVAL;
+       if (!subtype->eds_op)
+               return -ENOTSUPP;
+
+       ret = subtype->eds_op(params, in, out);
+
+       pr_devel("<==%s() = %d\n", __func__, ret);
+       return ret;
+}
+
+static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
+                                          const void *in, const void *in2)
+{
+       struct public_key_signature sig = {
+               .s_size         = params->in2_len,
+               .digest_size    = params->in_len,
+               .encoding       = params->encoding,
+               .hash_algo      = params->hash_algo,
+               .digest         = (void *)in,
+               .s              = (void *)in2,
+       };
+
+       return verify_signature(params->key, &sig);
+}
+
 struct key_type key_type_asymmetric = {
        .name                   = "asymmetric",
        .preparse               = asymmetric_key_preparse,
@@ -548,6 +588,9 @@ struct key_type key_type_asymmetric = {
        .destroy                = asymmetric_key_destroy,
        .describe               = asymmetric_key_describe,
        .lookup_restriction     = asymmetric_lookup_restriction,
+       .asym_query             = query_asymmetric_key,
+       .asym_eds_op            = asymmetric_key_eds_op,
+       .asym_verify_signature  = asymmetric_key_verify_signature,
 };
 EXPORT_SYMBOL_GPL(key_type_asymmetric);
 
index 0f134162cef4b5f89c016db315df1b52de18ef16..f0d56e1a8b7e2b4971004959261b0d5c18cf0a6b 100644 (file)
@@ -271,6 +271,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
        switch (ctx->last_oid) {
        case OID_rsaEncryption:
                ctx->sinfo->sig->pkey_algo = "rsa";
+               ctx->sinfo->sig->encoding = "pkcs1";
                break;
        default:
                printk("Unsupported pkey algo: %u\n", ctx->last_oid);
diff --git a/crypto/asymmetric_keys/pkcs8.asn1 b/crypto/asymmetric_keys/pkcs8.asn1
new file mode 100644 (file)
index 0000000..702c41a
--- /dev/null
@@ -0,0 +1,24 @@
+--
+-- This is the unencrypted variant
+--
+PrivateKeyInfo ::= SEQUENCE {
+       version                 Version,
+       privateKeyAlgorithm     PrivateKeyAlgorithmIdentifier,
+       privateKey              PrivateKey,
+       attributes              [0] IMPLICIT Attributes OPTIONAL
+}
+
+Version ::= INTEGER  ({ pkcs8_note_version })
+
+PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier ({ pkcs8_note_algo })
+
+PrivateKey ::= OCTET STRING ({ pkcs8_note_key })
+
+Attributes ::= SET OF Attribute
+
+Attribute ::= ANY
+
+AlgorithmIdentifier ::= SEQUENCE {
+       algorithm   OBJECT IDENTIFIER ({ pkcs8_note_OID }),
+       parameters  ANY OPTIONAL
+}
diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c
new file mode 100644 (file)
index 0000000..5f6a7ec
--- /dev/null
@@ -0,0 +1,184 @@
+/* PKCS#8 Private Key parser [RFC 5208].
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "PKCS8: "fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/oid_registry.h>
+#include <keys/asymmetric-subtype.h>
+#include <keys/asymmetric-parser.h>
+#include <crypto/public_key.h>
+#include "pkcs8.asn1.h"
+
+struct pkcs8_parse_context {
+       struct public_key *pub;
+       unsigned long   data;                   /* Start of data */
+       enum OID        last_oid;               /* Last OID encountered */
+       enum OID        algo_oid;               /* Algorithm OID */
+       u32             key_size;
+       const void      *key;
+};
+
+/*
+ * Note an OID when we find one for later processing when we know how to
+ * interpret it.
+ */
+int pkcs8_note_OID(void *context, size_t hdrlen,
+                  unsigned char tag,
+                  const void *value, size_t vlen)
+{
+       struct pkcs8_parse_context *ctx = context;
+
+       ctx->last_oid = look_up_OID(value, vlen);
+       if (ctx->last_oid == OID__NR) {
+               char buffer[50];
+
+               sprint_oid(value, vlen, buffer, sizeof(buffer));
+               pr_info("Unknown OID: [%lu] %s\n",
+                       (unsigned long)value - ctx->data, buffer);
+       }
+       return 0;
+}
+
+/*
+ * Note the version number of the ASN.1 blob.
+ */
+int pkcs8_note_version(void *context, size_t hdrlen,
+                      unsigned char tag,
+                      const void *value, size_t vlen)
+{
+       if (vlen != 1 || ((const u8 *)value)[0] != 0) {
+               pr_warn("Unsupported PKCS#8 version\n");
+               return -EBADMSG;
+       }
+       return 0;
+}
+
+/*
+ * Note the public algorithm.
+ */
+int pkcs8_note_algo(void *context, size_t hdrlen,
+                   unsigned char tag,
+                   const void *value, size_t vlen)
+{
+       struct pkcs8_parse_context *ctx = context;
+
+       if (ctx->last_oid != OID_rsaEncryption)
+               return -ENOPKG;
+
+       ctx->pub->pkey_algo = "rsa";
+       return 0;
+}
+
+/*
+ * Note the key data of the ASN.1 blob.
+ */
+int pkcs8_note_key(void *context, size_t hdrlen,
+                  unsigned char tag,
+                  const void *value, size_t vlen)
+{
+       struct pkcs8_parse_context *ctx = context;
+
+       ctx->key = value;
+       ctx->key_size = vlen;
+       return 0;
+}
+
+/*
+ * Parse a PKCS#8 private key blob.
+ */
+static struct public_key *pkcs8_parse(const void *data, size_t datalen)
+{
+       struct pkcs8_parse_context ctx;
+       struct public_key *pub;
+       long ret;
+
+       memset(&ctx, 0, sizeof(ctx));
+
+       ret = -ENOMEM;
+       ctx.pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
+       if (!ctx.pub)
+               goto error;
+
+       ctx.data = (unsigned long)data;
+
+       /* Attempt to decode the private key */
+       ret = asn1_ber_decoder(&pkcs8_decoder, &ctx, data, datalen);
+       if (ret < 0)
+               goto error_decode;
+
+       ret = -ENOMEM;
+       pub = ctx.pub;
+       pub->key = kmemdup(ctx.key, ctx.key_size, GFP_KERNEL);