From abe0ec5a81334d10ce96947922dc508b1fffdca2 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Fri, 4 Oct 2019 13:34:08 -0700 Subject: [PATCH] ANDROID: android-mainline quilt series for 5.4-ic1 This introduces a quilt series that can be used to create a rebase version of the android-mainline branch. The series applies to mainline commit 54ecb8f7028c5 ("Linux 5.4-rc1") The generated tree matches android-mainline commit c8e152bc7d05 ("ANDROID: staging: ion: Fix missing entry in kerneldoc header") Change-Id: I6fe8876981e342ae1f6a71afd6868d5c6e5de31e Signed-off-by: Todd Kjos --- ...r-handler-to-invalidate-vbmeta-parti.patch | 332 ++ ...d-dm-bow-to-cuttlefish-configuration.patch | 39 + ...NDROID-Add-initial-rockpi4_defconfig.patch | 564 ++ ...OID-Add-initial-x86_64-gki_defconfig.patch | 464 ++ ..._options2-to-view-private-mount-data.patch | 56 + ...ckpi4_defconfig-up-with-gki_defconfi.patch | 176 + ...Expose-gki_defconfig-to-build.config.patch | 42 + ...ANDROID-Fix-arm64-allmodconfig-build.patch | 37 + patches/ANDROID-Fixed-x86-regression.patch | 46 + ...ur-part-revert-of-asm-goto-usage-1-4.patch | 38 + ...ur-part-revert-of-asm-goto-usage-2-4.patch | 44 + ...ur-part-revert-of-asm-goto-usage-3-4.patch | 127 + ...ur-part-revert-of-asm-goto-usage-4-4.patch | 58 + ...NDROID-GKI-enable-CONFIG_SPI-for-x86.patch | 29 + ...DROID-GKI-enable-CONFIG_TIPC-for-x86.patch | 29 + ...ort-cma-symbols-for-cma-heap-as-a-mo.patch | 59 + ...D-Initial-abi_gki_aarch64-definition.patch | 60 + ...LVMLinux-allow-overriding-clang-targ.patch | 65 + ...h-device-failed-to-suspend-in-dpm_su.patch | 73 + ...-Move-from-clang-r328903-to-r346389b.patch | 43 + ...-Move-from-clang-r346389b-to-r349610.patch | 44 + ...-Move-from-clang-r349610-to-r353983c.patch | 59 + ...ve-CONFIG_USELIB-from-x86-gki-config.patch | 25 + ...Remove-unused-cuttlefish-build-infra.patch | 998 ++++ .../ANDROID-Removed-check-for-asm-goto.patch | 44 + ...-Removed-extraneous-configs-from-gki.patch | 98 + ...moved-extraneous-serial-8250-configs.patch | 47 + ...hardcoded-kernel-command-line-argume.patch | 29 + ...-unnecessary-modules-from-cuttlefish.patch | 36 + patches/ANDROID-Turn-xt_owner-module-on.patch | 48 + ...NDROID-add-extra-free-kbytes-tunable.patch | 181 + ...nfigs-so-that-GKI-boots-on-x86-cuttl.patch | 53 + ...sb-HCD-dummy-config-to-permit-usb-wr.patch | 41 + ...odconfig-Force-gki_defconfig-as-base.patch | 37 + ...OID-arm-enable-max-frequency-capping.patch | 33 + ...-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch | 55 + ...rm64-defconfig-Enable-EAS-by-default.patch | 47 + ...D-arm64-enable-max-frequency-capping.patch | 33 + ...-add-support-for-RT-prio-inheritance.patch | 573 ++ ...onfigs-switch-prebuilt-path-location.patch | 72 + ...-KOBJ_ONLINE-event-when-enabling-cpu.patch | 45 + ...Add-time_in_state-to-proc-uid-direct.patch | 143 + ...arch_topology-implement-max-frequenc.patch | 139 + ...times-add-proc-uid_concurrent_-activ.patch | 343 ++ ...times-don-t-copy-invalid-freqs-from-.patch | 155 + ...ID-cpufreq-times-optimize-proc-files.patch | 75 + ...times-record-fast-switch-frequency-t.patch | 115 + ...eq-times-track-per-uid-time-in-state.patch | 331 ++ ...cpufreq-track-per-task-time-in-state.patch | 476 ++ ...reate-build.configs-for-allmodconfig.patch | 57 + ...lefish-enable-CONFIG_INET_UDP_DIAG-y.patch | 45 + ...sh-enable-CONFIG_NETFILTER_XT_TARGET.patch | 59 + ...ttlefish-enable-CONFIG_NET_CLS_BPF-y.patch | 57 + ...fish-enable-CONFIG_NET_SCH_INGRESS-y.patch | 58 + ...lefish-enable-CONFIG_NET_SCH_NETEM-y.patch | 58 + ...ttlefish-enable-CONFIG_USB_RTL8152-y.patch | 58 + ...sh-gki-_defconfig-Enable-CONFIG_SDCA.patch | 67 + ...ROID-cuttlefish-overlayfs-regression.patch | 35 + ...sh_defconfig-Add-support-for-AC97-au.patch | 56 + ...sh_defconfig-Enable-CONFIG_ARM64_LSE.patch | 32 + ...sh_defconfig-Enable-CONFIG_CMDLINE_E.patch | 29 + ...fish_defconfig-Enable-CONFIG_CPUSETS.patch | 43 + ...sh_defconfig-Enable-CONFIG_CPU_FREQ_.patch | 42 + ...sh_defconfig-Enable-CONFIG_CRYPTO_AD.patch | 42 + ...sh_defconfig-Enable-CONFIG_DM_VERITY.patch | 42 + ...fish_defconfig-Enable-CONFIG_FUSE_FS.patch | 41 + ...sh_defconfig-Enable-CONFIG_INPUT_MOU.patch | 29 + ...ttlefish_defconfig-Enable-CONFIG_MMC.patch | 47 + ...sh_defconfig-Enable-CONFIG_NETFILTER.patch | 42 + ...sh_defconfig-Enable-CONFIG_OVERLAY_F.patch | 42 + ...ttlefish_defconfig-Enable-CONFIG_PSI.patch | 41 + ...sh_defconfig-Enable-CONFIG_RTC_HCTOS.patch | 45 + ...sh_defconfig-Enable-CONFIG_UID_SYS_S.patch | 42 + ...fig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch | 42 + ...able-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch | 42 + ...ig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch | 42 + ...sh_defconfig-Enable-EAS-related-defi.patch | 89 + ...sh_defconfig-Enable-SECURITY_PERF_EV.patch | 42 + ...lefish_defconfig-Enable-VIRTIO_INPUT.patch | 40 + ...uttlefish_defconfig-Enable-VIRT_WIFI.patch | 41 + ...efish_defconfig-Enable-vsock-options.patch | 43 + ..._defconfig-sync-with-android-mainl-1.patch | 119 + ..._defconfig-sync-with-android-mainl-2.patch | 29 + ...efconfig-build-config-for-cuttlefish.patch | 917 +++ .../ANDROID-dm-bow-Add-dm-bow-feature.patch | 1447 +++++ ...OID-dm-bow-Fix-32-bit-compile-errors.patch | 79 + ...Add-support-for-mapping-buffers-with.patch | 46 + ...Add-support-for-partial-cache-mainte.patch | 174 + ...Add-support-to-get-flags-associated-.patch | 80 + ...t-pass-cuttlefish-GKI-modularization.patch | 111 + .../ANDROID-fix-kernelci-build-break.patch | 42 + ...NDROID-fs-FS-tracepoints-to-track-IO.patch | 632 ++ ...ID-fs-Restore-vfs_path_lookup-export.patch | 52 + ...fs-epoll-use-freezable-blocking-call.patch | 54 + ...lefish-defconfigs-use-prebuilt-build.patch | 71 + ...efconfig-Add-GKI_HACKS_to_FIX-config.patch | 44 + ...onfig-Enable-CMA-SLAB_FREELIST-RANDO.patch | 40 + ...-gki_defconfig-Enable-HiSilicon-SoCs.patch | 45 + ...-gki_defconfig-Enable-SERIAL_DEV_BUS.patch | 42 + ...D-gki_defconfig-Minimally-enable-EFI.patch | 68 + ...onfig-Remove-cuttlefish-specific-con.patch | 97 + ...onfig-Remove-recommended-configs-not.patch | 153 + ...onfig-common-configs-for-device-DLKM.patch | 81 + ...i_defconfig-disable-BRIDGE_NETFILTER.patch | 26 + ...onfig-disable-CONFIG_LCD_CLASS_DEVIC.patch | 27 + ...i_defconfig-disable-IP_PNP-ECRYPT_FS.patch | 36 + ...onfig-enable-CMA-and-increase-CMA_AR.patch | 29 + ...onfig-enable-CONFIG_QCOM_-COMMAND_DB.patch | 70 + ...onfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch | 54 + ...OID-gki_defconfig-enable-CONFIG_TIPC.patch | 27 + ...ROID-gki_defconfig-enable-CONFIG_UIO.patch | 40 + ...ANDROID-gki_defconfig-enable-DMA_CMA.patch | 28 + ...onfig-enable-SLAB_FREELIST_RANDOM-SL.patch | 31 + ...ID-gki_defconfig-enable-more-configs.patch | 88 + ...onfig-initial-config-based-on-cuttle.patch | 467 ++ ..._defconfig-more-configs-for-partners.patch | 128 + ...onfig-more-generic-configs-for-DLKMs.patch | 69 + ...onfig-remove-more-recommended-config.patch | 50 + ...-gki_defconfig-set-CONFIG_NR_CPUS-32.patch | 46 + ...ki_defconfig-sync-with-savedefconfig.patch | 27 + ...fconfig-workaround-to-enable-configs.patch | 55 + ...NDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch | 56 + ...it-GKI-enable-hidden-configs-for-DRM.patch | 46 + ...t-GKI-enable-hidden-configs-for-GPIO.patch | 46 + ...KI-enable-hidden-configs-for-SND_SOC.patch | 45 + ...GKI-enable-hidden-configs-for-regmap.patch | 45 + ...OID-label-cuttlefish-modules-for-gki.patch | 53 + ...-field-to-store-names-for-private-an.patch | 648 +++ ...-Add-ignore-mmc-pm-notify-functional.patch | 54 + ...filesystem-private-data-to-mount-poi.patch | 172 + ...OID-mnt-Fix-null-pointer-dereference.patch | 65 + ...ble-wireless-core-features-with-GKI_.patch | 67 + ...-autoconf-routes-into-per-device-tab.patch | 270 + ...-make-PF_KEY-SHA256-use-RFC-complian.patch | 41 + ...r-xt_IDLETIMER-Add-new-netlink-msg-t.patch | 454 ++ ...r-xt_quota2-adding-the-original-quot.patch | 518 ++ ...rt-CONFIG_CMDLINE_EXTEND-config-opti.patch | 180 + ...keup_reason-add-an-API-to-log-wakeup.patch | 588 ++ .../ANDROID-proc-Add-proc-uid-directory.patch | 436 ++ ...-build.config-files-to-remove-duplic.patch | 116 + ...troduce-uclamp-latency-and-boost-wra.patch | 71 + ...event-unnecessary-active-balance-of-.patch | 63 + ...conditionally-honor-sync-flag-for-en.patch | 64 + ...date-max-cpu-capacity-in-case-of-max.patch | 222 + ...re-Add-a-latency-sensitive-flag-to-u.patch | 100 + ...ir-Also-do-misfit-in-overloaded-grou.patch | 37 + ...ir-Attempt-to-improve-throughput-for.patch | 55 + ...-fair-Bias-EAS-placement-for-latency.patch | 129 + ...ir-Don-t-balance-misfits-if-it-would.patch | 60 + ...ir-EAS-Add-uclamp-support-to-find_en.patch | 66 + ...ir-add-arch-scaling-function-for-max.patch | 83 + ...OID-sdcardfs-Add-sdcardfs-filesystem.patch | 5182 +++++++++++++++++ .../ANDROID-sdcardfs-Define-magic-value.patch | 36 + ...OID-sdcardfs-Enable-modular-sdcardfs.patch | 102 + ...fs-fix-fall-through-in-param-parsing.patch | 27 + ...-perf-Allow-further-restriction-of-p.patch | 120 + ...android-ion-Decouple-ION-page-poolin.patch | 184 + ...android-ion-Expose-ion_alloc-to-kern.patch | 151 + ...ion-Add-support-for-heap-specific-dm.patch | 335 ++ ...DROID-staging-ion-Build-fix-for-mips.patch | 27 + ...ion-Fix-uninitialized-variable-warni.patch | 51 + ...-ion-Remove-unnecessary-ion-heap-ops.patch | 180 + ...ion-add-support-for-consistent-heap-.patch | 180 + ...D-staging-ion-make-cma-heap-a-module.patch | 119 + ...ion-move-uapi-ion.h-to-uapi-linux-io.patch | 37 + ...ion-reserve-specific-heap-ids-for-kn.patch | 132 + ...D-sync-defconfigs-with-savedefconfig.patch | 104 + ...DROID-taskstats-track-fsync-syscalls.patch | 138 + ...ime-Adds-accounting-for-the-cputimes.patch | 318 + ...time-add-per-uid-IO-usage-accounting.patch | 650 +++ .../ANDROID-update-arm64-gki_defconfig.patch | 29 + patches/ANDROID-update-gki_defconfig-1.patch | 42 + patches/ANDROID-update-gki_defconfig-2.patch | 42 + ...adget-Fix-dependency-for-f_accessory.patch | 52 + ...et-configfs-Add-Uevent-to-notify-use.patch | 279 + ...et-configfs-Add-device-attribute-to-.patch | 154 + ...et-configfs-Add-function-devices-to-.patch | 110 + ...et-configfs-Add-state-attribute-to-a.patch | 124 + ...et-configfs-Add-usb_function-ptr-to-.patch | 39 + ...et-f_accessory-Add-Android-Accessory.patch | 1629 ++++++ ...et-f_audio_source-New-gadget-driver-.patch | 1153 ++++ ...b-gadget-f_midi-create-F_midi-device.patch | 110 + ...et-f_midi-set-fi-f-to-NULL-when-free.patch | 56 + ...permission2-for-filesystems-with-per.patch | 892 +++ ...setattr2-for-filesystems-with-per-mo.patch | 262 + ...d_canonical_path-for-stacked-filesys.patch | 113 + ...x86-Remove-a-useless-warning-message.patch | 39 + ...OID-x86-gki_defconfig-enable-DMA_CMA.patch | 27 + ...xfrm-remove-in_compat_syscall-checks.patch | 47 + .../Adding-GKI-Ramdisk-to-gki-config.patch | 32 + ...ing-SERIAL_OF_PLATFORM-module-to-gki.patch | 49 + patches/CONFIG_MMC-m.patch | 48 + patches/Enable-CONFIG_ION_SYSTEM_HEAP.patch | 41 + ...-irq-don-t-set-the-chip-for-all-irqs.patch | 29 + ...emove-uses-of-variable-length-arrays.patch | 110 + ...entify-the-end-of-the-kernel-area-to.patch | 79 + ...hed-membarrier-Fix-p-mm-membarrier_s.patch | 31 + ...h-rsc-modularize-RSC-controller-driv.patch | 61 + patches/series | 214 + ...e-ion-heaps-into-their-own-directory.patch | 139 + ...ng-ion-export-ion_free-for-ion_heaps.patch | 63 + ...on-fix-off-by-1-error-in-heap-search.patch | 42 + ...make-system-and-contig-heaps-modular.patch | 515 ++ ...ctor-ion-s-buffer-manipulators-into-.patch | 550 ++ ...ctor-ion-s-dmabuf-manipulators-into-.patch | 680 +++ ...ctor-ion-s-heap-API-into-linux-ion.h.patch | 1075 ++++ ...ctor-ion-s-heap-manipulators-into-a-.patch | 401 ++ ...split-system-and-system-contig-heaps.patch | 300 + ...i-match-the-existing-heap-type-enums.patch | 50 + 209 files changed, 36598 insertions(+) create mode 100644 patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch create mode 100644 patches/ANDROID-Add-dm-bow-to-cuttlefish-configuration.patch create mode 100644 patches/ANDROID-Add-initial-rockpi4_defconfig.patch create mode 100644 patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch create mode 100644 patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch create mode 100644 patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfi.patch create mode 100644 patches/ANDROID-Expose-gki_defconfig-to-build.config.patch create mode 100644 patches/ANDROID-Fix-arm64-allmodconfig-build.patch create mode 100644 patches/ANDROID-Fixed-x86-regression.patch create mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch create mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch create mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch create mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch create mode 100644 patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch create mode 100644 patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch create mode 100644 patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-mo.patch create mode 100644 patches/ANDROID-Initial-abi_gki_aarch64-definition.patch create mode 100644 patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-targ.patch create mode 100644 patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_su.patch create mode 100644 patches/ANDROID-Move-from-clang-r328903-to-r346389b.patch create mode 100644 patches/ANDROID-Move-from-clang-r346389b-to-r349610.patch create mode 100644 patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch create mode 100644 patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch create mode 100644 patches/ANDROID-Remove-unused-cuttlefish-build-infra.patch create mode 100644 patches/ANDROID-Removed-check-for-asm-goto.patch create mode 100644 patches/ANDROID-Removed-extraneous-configs-from-gki.patch create mode 100644 patches/ANDROID-Removed-extraneous-serial-8250-configs.patch create mode 100644 patches/ANDROID-Removed-hardcoded-kernel-command-line-argume.patch create mode 100644 patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch create mode 100644 patches/ANDROID-Turn-xt_owner-module-on.patch create mode 100644 patches/ANDROID-add-extra-free-kbytes-tunable.patch create mode 100644 patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttl.patch create mode 100644 patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-wr.patch create mode 100644 patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch create mode 100644 patches/ANDROID-arm-enable-max-frequency-capping.patch create mode 100644 patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch create mode 100644 patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch create mode 100644 patches/ANDROID-arm64-enable-max-frequency-capping.patch create mode 100644 patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch create mode 100644 patches/ANDROID-build-configs-switch-prebuilt-path-location.patch create mode 100644 patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpu.patch create mode 100644 patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-direct.patch create mode 100644 patches/ANDROID-cpufreq-arch_topology-implement-max-frequenc.patch create mode 100644 patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-activ.patch create mode 100644 patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-.patch create mode 100644 patches/ANDROID-cpufreq-times-optimize-proc-files.patch create mode 100644 patches/ANDROID-cpufreq-times-record-fast-switch-frequency-t.patch create mode 100644 patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch create mode 100644 patches/ANDROID-cpufreq-track-per-task-time-in-state.patch create mode 100644 patches/ANDROID-create-build.configs-for-allmodconfig.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_INET_UDP_DIAG-y.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_NETFILTER_XT_TARGET.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_NET_CLS_BPF-y.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_INGRESS-y.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_NETEM-y.patch create mode 100644 patches/ANDROID-cuttlefish-enable-CONFIG_USB_RTL8152-y.patch create mode 100644 patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCA.patch create mode 100644 patches/ANDROID-cuttlefish-overlayfs-regression.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Add-support-for-AC97-au.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_ARM64_LSE.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CMDLINE_E.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPUSETS.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPU_FREQ_.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CRYPTO_AD.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_DM_VERITY.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_FUSE_FS.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_INPUT_MOU.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_MMC.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_NETFILTER.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_OVERLAY_F.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_PSI.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_RTC_HCTOS.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_UID_SYS_S.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-EAS-related-defi.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-SECURITY_PERF_EV.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-VIRTIO_INPUT.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-VIRT_WIFI.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-Enable-vsock-options.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-1.patch create mode 100644 patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-2.patch create mode 100644 patches/ANDROID-defconfig-build-config-for-cuttlefish.patch create mode 100644 patches/ANDROID-dm-bow-Add-dm-bow-feature.patch create mode 100644 patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch create mode 100644 patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with.patch create mode 100644 patches/ANDROID-dma-buf-Add-support-for-partial-cache-mainte.patch create mode 100644 patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-.patch create mode 100644 patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch create mode 100644 patches/ANDROID-fix-kernelci-build-break.patch create mode 100644 patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch create mode 100644 patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch create mode 100644 patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch create mode 100644 patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build.patch create mode 100644 patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch create mode 100644 patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDO.patch create mode 100644 patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch create mode 100644 patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch create mode 100644 patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch create mode 100644 patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-con.patch create mode 100644 patches/ANDROID-gki_defconfig-Remove-recommended-configs-not.patch create mode 100644 patches/ANDROID-gki_defconfig-common-configs-for-device-DLKM.patch create mode 100644 patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch create mode 100644 patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVIC.patch create mode 100644 patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AR.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SL.patch create mode 100644 patches/ANDROID-gki_defconfig-enable-more-configs.patch create mode 100644 patches/ANDROID-gki_defconfig-initial-config-based-on-cuttle.patch create mode 100644 patches/ANDROID-gki_defconfig-more-configs-for-partners.patch create mode 100644 patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch create mode 100644 patches/ANDROID-gki_defconfig-remove-more-recommended-config.patch create mode 100644 patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch create mode 100644 patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch create mode 100644 patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch create mode 100644 patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch create mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch create mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch create mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch create mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch create mode 100644 patches/ANDROID-label-cuttlefish-modules-for-gki.patch create mode 100644 patches/ANDROID-mm-add-a-field-to-store-names-for-private-an.patch create mode 100644 patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functional.patch create mode 100644 patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-poi.patch create mode 100644 patches/ANDROID-mnt-Fix-null-pointer-dereference.patch create mode 100644 patches/ANDROID-net-enable-wireless-core-features-with-GKI_.patch create mode 100644 patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tab.patch create mode 100644 patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-complian.patch create mode 100644 patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-t.patch create mode 100644 patches/ANDROID-netfilter-xt_quota2-adding-the-original-quot.patch create mode 100644 patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-opti.patch create mode 100644 patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup.patch create mode 100644 patches/ANDROID-proc-Add-proc-uid-directory.patch create mode 100644 patches/ANDROID-refactor-build.config-files-to-remove-duplic.patch create mode 100644 patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wra.patch create mode 100644 patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-.patch create mode 100644 patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-en.patch create mode 100644 patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max.patch create mode 100644 patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-u.patch create mode 100644 patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-grou.patch create mode 100644 patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for.patch create mode 100644 patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch create mode 100644 patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would.patch create mode 100644 patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_en.patch create mode 100644 patches/ANDROID-sched-fair-add-arch-scaling-function-for-max.patch create mode 100644 patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch create mode 100644 patches/ANDROID-sdcardfs-Define-magic-value.patch create mode 100644 patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch create mode 100644 patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch create mode 100644 patches/ANDROID-security-perf-Allow-further-restriction-of-p.patch create mode 100644 patches/ANDROID-staging-android-ion-Decouple-ION-page-poolin.patch create mode 100644 patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kern.patch create mode 100644 patches/ANDROID-staging-ion-Add-support-for-heap-specific-dm.patch create mode 100644 patches/ANDROID-staging-ion-Build-fix-for-mips.patch create mode 100644 patches/ANDROID-staging-ion-Fix-uninitialized-variable-warni.patch create mode 100644 patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch create mode 100644 patches/ANDROID-staging-ion-add-support-for-consistent-heap-.patch create mode 100644 patches/ANDROID-staging-ion-make-cma-heap-a-module.patch create mode 100644 patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-io.patch create mode 100644 patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-kn.patch create mode 100644 patches/ANDROID-sync-defconfigs-with-savedefconfig.patch create mode 100644 patches/ANDROID-taskstats-track-fsync-syscalls.patch create mode 100644 patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes.patch create mode 100644 patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch create mode 100644 patches/ANDROID-update-arm64-gki_defconfig.patch create mode 100644 patches/ANDROID-update-gki_defconfig-1.patch create mode 100644 patches/ANDROID-update-gki_defconfig-2.patch create mode 100644 patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch create mode 100644 patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-use.patch create mode 100644 patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-.patch create mode 100644 patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-.patch create mode 100644 patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-a.patch create mode 100644 patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-.patch create mode 100644 patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory.patch create mode 100644 patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-.patch create mode 100644 patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch create mode 100644 patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free.patch create mode 100644 patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per.patch create mode 100644 patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mo.patch create mode 100644 patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesys.patch create mode 100644 patches/ANDROID-x86-Remove-a-useless-warning-message.patch create mode 100644 patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch create mode 100644 patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch create mode 100644 patches/Adding-GKI-Ramdisk-to-gki-config.patch create mode 100644 patches/Adding-SERIAL_OF_PLATFORM-module-to-gki.patch create mode 100644 patches/CONFIG_MMC-m.patch create mode 100644 patches/Enable-CONFIG_ION_SYSTEM_HEAP.patch create mode 100644 patches/Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch create mode 100644 patches/Revert-um-remove-uses-of-variable-length-arrays.patch create mode 100644 patches/Revert-x86-mm-Identify-the-end-of-the-kernel-area-to.patch create mode 100644 patches/UPSTREAM-fix-sched-membarrier-Fix-p-mm-membarrier_s.patch create mode 100644 patches/drivers-qcom-rpmh-rsc-modularize-RSC-controller-driv.patch create mode 100644 patches/series create mode 100644 patches/staging-ion-Move-ion-heaps-into-their-own-directory.patch create mode 100644 patches/staging-ion-export-ion_free-for-ion_heaps.patch create mode 100644 patches/staging-ion-fix-off-by-1-error-in-heap-search.patch create mode 100644 patches/staging-ion-make-system-and-contig-heaps-modular.patch create mode 100644 patches/staging-ion-refactor-ion-s-buffer-manipulators-into-.patch create mode 100644 patches/staging-ion-refactor-ion-s-dmabuf-manipulators-into-.patch create mode 100644 patches/staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch create mode 100644 patches/staging-ion-refactor-ion-s-heap-manipulators-into-a-.patch create mode 100644 patches/staging-ion-split-system-and-system-contig-heaps.patch create mode 100644 patches/staging-ion-uapi-match-the-existing-heap-type-enums.patch diff --git a/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch b/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch new file mode 100644 index 000000000000..bed0bc8fe254 --- /dev/null +++ b/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch @@ -0,0 +1,332 @@ +From d3c3722eb2abb01afead5f23f529cd3bca4ab710 Mon Sep 17 00:00:00 2001 +From: David Zeuthen +Date: Tue, 24 Jan 2017 13:17:01 -0500 +Subject: ANDROID: AVB error handler to invalidate vbmeta + partition. + +If androidboot.vbmeta.invalidate_on_error is 'yes' and +androidboot.vbmeta.device is set and points to a device with vbmeta +magic, this header will be overwritten upon an irrecoverable dm-verity +error. The side-effect of this is that the slot will fail to verify on +next reboot, effectively triggering the boot loader to fallback to +another slot. This work both if the vbmeta struct is at the start of a +partition or if there's an AVB footer at the end. + +This code is based on drivers/md/dm-verity-chromeos.c from ChromiumOS. + +Bug: 31622239 +Bug: 120445368 +Test: Manually tested (other arch). +Signed-off-by: David Zeuthen +[astrachan: re-diffed against a kernel without dm-android-verity] +Change-Id: I571b5a75461da38ad832a9bea33c298bef859e26 +Signed-off-by: Alistair Strachan +--- + drivers/md/Kconfig | 9 ++ + drivers/md/Makefile | 4 + + drivers/md/dm-verity-avb.c | 229 ++++++++++++++++++++++++++++++++++ + drivers/md/dm-verity-target.c | 6 +- + drivers/md/dm-verity.h | 2 + + 5 files changed, 249 insertions(+), 1 deletion(-) + create mode 100644 drivers/md/dm-verity-avb.c + +Index: common/drivers/md/Kconfig +=================================================================== +--- common.orig/drivers/md/Kconfig ++++ common/drivers/md/Kconfig +@@ -517,6 +517,17 @@ config DM_VERITY_VERIFY_ROOTHASH_SIG + + If unsure, say N. + ++config DM_VERITY_AVB ++ tristate "Support AVB specific verity error behavior" ++ depends on DM_VERITY ++ ---help--- ++ Enables Android Verified Boot platform-specific error ++ behavior. In particular, it will modify the vbmeta partition ++ specified on the kernel command-line when non-transient error ++ occurs (followed by a panic). ++ ++ If unsure, say N. ++ + config DM_VERITY_FEC + bool "Verity forward error correction support" + depends on DM_VERITY +Index: common/drivers/md/Makefile +=================================================================== +--- common.orig/drivers/md/Makefile ++++ common/drivers/md/Makefile +@@ -80,6 +80,10 @@ ifeq ($(CONFIG_DM_UEVENT),y) + dm-mod-objs += dm-uevent.o + endif + ++ifeq ($(CONFIG_DM_VERITY_AVB),y) ++dm-verity-objs += dm-verity-avb.o ++endif ++ + ifeq ($(CONFIG_DM_VERITY_FEC),y) + dm-verity-objs += dm-verity-fec.o + endif +Index: common/drivers/md/dm-verity-avb.c +=================================================================== +--- /dev/null ++++ common/drivers/md/dm-verity-avb.c +@@ -0,0 +1,229 @@ ++/* ++ * Copyright (C) 2017 Google. ++ * ++ * This file is released under the GPLv2. ++ * ++ * Based on drivers/md/dm-verity-chromeos.c ++ */ ++ ++#include ++#include ++#include ++ ++#define DM_MSG_PREFIX "verity-avb" ++ ++/* Set via module parameters. */ ++static char avb_vbmeta_device[64]; ++static char avb_invalidate_on_error[4]; ++ ++static void invalidate_vbmeta_endio(struct bio *bio) ++{ ++ if (bio->bi_status) ++ DMERR("invalidate_vbmeta_endio: error %d", bio->bi_status); ++ complete(bio->bi_private); ++} ++ ++static int invalidate_vbmeta_submit(struct bio *bio, ++ struct block_device *bdev, ++ int op, int access_last_sector, ++ struct page *page) ++{ ++ DECLARE_COMPLETION_ONSTACK(wait); ++ ++ bio->bi_private = &wait; ++ bio->bi_end_io = invalidate_vbmeta_endio; ++ bio_set_dev(bio, bdev); ++ bio_set_op_attrs(bio, op, REQ_SYNC); ++ ++ bio->bi_iter.bi_sector = 0; ++ if (access_last_sector) { ++ sector_t last_sector; ++ ++ last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1; ++ bio->bi_iter.bi_sector = last_sector; ++ } ++ if (!bio_add_page(bio, page, PAGE_SIZE, 0)) { ++ DMERR("invalidate_vbmeta_submit: bio_add_page error"); ++ return -EIO; ++ } ++ ++ submit_bio(bio); ++ /* Wait up to 2 seconds for completion or fail. */ ++ if (!wait_for_completion_timeout(&wait, msecs_to_jiffies(2000))) ++ return -EIO; ++ return 0; ++} ++ ++static int invalidate_vbmeta(dev_t vbmeta_devt) ++{ ++ int ret = 0; ++ struct block_device *bdev; ++ struct bio *bio; ++ struct page *page; ++ fmode_t dev_mode; ++ /* Ensure we do synchronous unblocked I/O. We may also need ++ * sync_bdev() on completion, but it really shouldn't. ++ */ ++ int access_last_sector = 0; ++ ++ DMINFO("invalidate_vbmeta: acting on device %d:%d", ++ MAJOR(vbmeta_devt), MINOR(vbmeta_devt)); ++ ++ /* First we open the device for reading. */ ++ dev_mode = FMODE_READ | FMODE_EXCL; ++ bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode, ++ invalidate_vbmeta); ++ if (IS_ERR(bdev)) { ++ DMERR("invalidate_kernel: could not open device for reading"); ++ dev_mode = 0; ++ ret = -ENOENT; ++ goto failed_to_read; ++ } ++ ++ bio = bio_alloc(GFP_NOIO, 1); ++ if (!bio) { ++ ret = -ENOMEM; ++ goto failed_bio_alloc; ++ } ++ ++ page = alloc_page(GFP_NOIO); ++ if (!page) { ++ ret = -ENOMEM; ++ goto failed_to_alloc_page; ++ } ++ ++ access_last_sector = 0; ++ ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_READ, ++ access_last_sector, page); ++ if (ret) { ++ DMERR("invalidate_vbmeta: error reading"); ++ goto failed_to_submit_read; ++ } ++ ++ /* We have a page. Let's make sure it looks right. */ ++ if (memcmp("AVB0", page_address(page), 4) == 0) { ++ /* Stamp it. */ ++ memcpy(page_address(page), "AVE0", 4); ++ DMINFO("invalidate_vbmeta: found vbmeta partition"); ++ } else { ++ /* Could be this is on a AVB footer, check. Also, since the ++ * AVB footer is in the last 64 bytes, adjust for the fact that ++ * we're dealing with 512-byte sectors. ++ */ ++ size_t offset = (1<bi_remaining. ++ */ ++ bio_reset(bio); ++ ++ ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_WRITE, ++ access_last_sector, page); ++ if (ret) { ++ DMERR("invalidate_vbmeta: error writing"); ++ goto failed_to_submit_write; ++ } ++ ++ DMERR("invalidate_vbmeta: completed."); ++ ret = 0; ++failed_to_submit_write: ++failed_to_write: ++invalid_header: ++ __free_page(page); ++failed_to_submit_read: ++ /* Technically, we'll leak a page with the pending bio, but ++ * we're about to reboot anyway. ++ */ ++failed_to_alloc_page: ++ bio_put(bio); ++failed_bio_alloc: ++ if (dev_mode) ++ blkdev_put(bdev, dev_mode); ++failed_to_read: ++ return ret; ++} ++ ++void dm_verity_avb_error_handler(void) ++{ ++ dev_t dev; ++ ++ DMINFO("AVB error handler called for %s", avb_vbmeta_device); ++ ++ if (strcmp(avb_invalidate_on_error, "yes") != 0) { ++ DMINFO("Not configured to invalidate"); ++ return; ++ } ++ ++ if (avb_vbmeta_device[0] == '\0') { ++ DMERR("avb_vbmeta_device parameter not set"); ++ goto fail_no_dev; ++ } ++ ++ dev = name_to_dev_t(avb_vbmeta_device); ++ if (!dev) { ++ DMERR("No matching partition for device: %s", ++ avb_vbmeta_device); ++ goto fail_no_dev; ++ } ++ ++ invalidate_vbmeta(dev); ++ ++fail_no_dev: ++ ; ++} ++ ++static int __init dm_verity_avb_init(void) ++{ ++ DMINFO("AVB error handler initialized with vbmeta device: %s", ++ avb_vbmeta_device); ++ return 0; ++} ++ ++static void __exit dm_verity_avb_exit(void) ++{ ++} ++ ++module_init(dm_verity_avb_init); ++module_exit(dm_verity_avb_exit); ++ ++MODULE_AUTHOR("David Zeuthen "); ++MODULE_DESCRIPTION("AVB-specific error handler for dm-verity"); ++MODULE_LICENSE("GPL"); ++ ++/* Declare parameter with no module prefix */ ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX "androidboot.vbmeta." ++module_param_string(device, avb_vbmeta_device, sizeof(avb_vbmeta_device), 0); ++module_param_string(invalidate_on_error, avb_invalidate_on_error, ++ sizeof(avb_invalidate_on_error), 0); +Index: common/drivers/md/dm-verity-target.c +=================================================================== +--- common.orig/drivers/md/dm-verity-target.c ++++ common/drivers/md/dm-verity-target.c +@@ -251,8 +251,12 @@ out: + if (v->mode == DM_VERITY_MODE_LOGGING) + return 0; + +- if (v->mode == DM_VERITY_MODE_RESTART) ++ if (v->mode == DM_VERITY_MODE_RESTART) { ++#ifdef CONFIG_DM_VERITY_AVB ++ dm_verity_avb_error_handler(); ++#endif + kernel_restart("dm-verity device corrupted"); ++ } + + return 1; + } +Index: common/drivers/md/dm-verity.h +=================================================================== +--- common.orig/drivers/md/dm-verity.h ++++ common/drivers/md/dm-verity.h +@@ -128,4 +128,6 @@ extern int verity_hash(struct dm_verity + extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, + sector_t block, u8 *digest, bool *is_zero); + ++extern void dm_verity_avb_error_handler(void); ++ + #endif /* DM_VERITY_H */ diff --git a/patches/ANDROID-Add-dm-bow-to-cuttlefish-configuration.patch b/patches/ANDROID-Add-dm-bow-to-cuttlefish-configuration.patch new file mode 100644 index 000000000000..e6b0f3eb5fa5 --- /dev/null +++ b/patches/ANDROID-Add-dm-bow-to-cuttlefish-configuration.patch @@ -0,0 +1,39 @@ +From a41cdee10376397a2139dbf4de41ec492cc1565e Mon Sep 17 00:00:00 2001 +From: Paul Lawrence +Date: Thu, 21 Mar 2019 13:23:03 -0700 +Subject: ANDROID: Add dm-bow to cuttlefish configuration + +Change-Id: I7f265cb8c6274da414d2477da9953546510ce26b +Signed-off-by: Paul Lawrence +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index b3116d935c841..76a68561f2fb1 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -218,6 +218,7 @@ CONFIG_DM_UEVENT=y + CONFIG_DM_VERITY=y + CONFIG_DM_VERITY_AVB=y + CONFIG_DM_VERITY_FEC=y ++CONFIG_DM_BOW=y + CONFIG_NETDEVICES=y + CONFIG_NETCONSOLE=y + CONFIG_NETCONSOLE_DYNAMIC=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index abd24a4f017d4..b2ad519f11c70 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -227,6 +227,7 @@ CONFIG_DM_UEVENT=y + CONFIG_DM_VERITY=y + CONFIG_DM_VERITY_AVB=y + CONFIG_DM_VERITY_FEC=y ++CONFIG_DM_BOW=y + CONFIG_NETDEVICES=y + CONFIG_NETCONSOLE=y + CONFIG_NETCONSOLE_DYNAMIC=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Add-initial-rockpi4_defconfig.patch b/patches/ANDROID-Add-initial-rockpi4_defconfig.patch new file mode 100644 index 000000000000..b00d1d70f66e --- /dev/null +++ b/patches/ANDROID-Add-initial-rockpi4_defconfig.patch @@ -0,0 +1,564 @@ +From 9a8189c272ac9fa2dd95aba34af9ce58fe541971 Mon Sep 17 00:00:00 2001 +From: Tristan Muntsinger +Date: Thu, 25 Jul 2019 13:48:04 -0700 +Subject: ANDROID: Add initial rockpi4_defconfig + +This is for the Rock Pi 4B board from Radxa with Rockchip's RK3399. + +Bug: 118442619 +Change-Id: If2ba4198ef268e5b249e909b1987d52f1c8d0def +Signed-off-by: Tristan Muntsinger +--- + arch/arm64/configs/rockpi4_defconfig | 540 +++++++++++++++++++++++++++ + 1 file changed, 540 insertions(+) + create mode 100644 arch/arm64/configs/rockpi4_defconfig + +diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig +new file mode 100644 +index 0000000000000..6d0cf70f37570 +--- /dev/null ++++ b/arch/arm64/configs/rockpi4_defconfig +@@ -0,0 +1,540 @@ ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_PSI=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_BLK_CGROUP=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_BPF=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++# CONFIG_RD_LZ4 is not set ++# CONFIG_SYSFS_SYSCALL is not set ++CONFIG_FHANDLE=y ++CONFIG_KALLSYMS_ALL=y ++CONFIG_BPF_SYSCALL=y ++# CONFIG_RSEQ is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_SLAB_FREELIST_RANDOM=y ++CONFIG_SLAB_FREELIST_HARDENED=y ++CONFIG_PROFILING=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SCHED_MC=y ++CONFIG_SECCOMP=y ++CONFIG_PARAVIRT=y ++CONFIG_COMPAT=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++CONFIG_RANDOMIZE_BASE=y ++CONFIG_CMDLINE="" ++# CONFIG_CMDLINE_FORCE is not set ++# CONFIG_EFI is not set ++CONFIG_PM_WAKELOCKS=y ++CONFIG_PM_WAKELOCKS_LIMIT=0 ++# CONFIG_PM_WAKELOCKS_GC is not set ++CONFIG_ENERGY_MODEL=y ++CONFIG_CPU_IDLE=y ++CONFIG_ARM_CPUIDLE=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_TIMES=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_ARM_SCPI_CPUFREQ=y ++CONFIG_ARM_SCMI_CPUFREQ=y ++CONFIG_ARM_SCMI_PROTOCOL=y ++# CONFIG_ARM_SCMI_POWER_DOMAIN is not set ++CONFIG_ARM_SCPI_PROTOCOL=y ++# CONFIG_ARM_SCPI_POWER_DOMAIN is not set ++CONFIG_VIRTUALIZATION=y ++CONFIG_KVM=y ++CONFIG_VHOST_VSOCK=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_AES_ARM64=y ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_BINFMT_MISC=y ++# CONFIG_SPARSEMEM_VMEMMAP is not set ++CONFIG_MEMORY_HOTPLUG=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_CMA=y ++CONFIG_CMA_AREAS=16 ++CONFIG_ZSMALLOC=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_XFRM_INTERFACE=y ++CONFIG_XFRM_STATISTICS=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_NET_IPGRE_DEMUX=y ++CONFIG_NET_IPVTI=y ++CONFIG_INET_ESP=y ++CONFIG_INET_UDP_DIAG=y ++CONFIG_INET_DIAG_DESTROY=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_ESP=y ++CONFIG_INET6_IPCOMP=y ++CONFIG_IPV6_MIP6=y ++CONFIG_IPV6_VTI=y ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_AMANDA=y ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_H323=y ++CONFIG_NF_CONNTRACK_IRC=y ++CONFIG_NF_CONNTRACK_NETBIOS_NS=y ++CONFIG_NF_CONNTRACK_PPTP=y ++CONFIG_NF_CONNTRACK_SANE=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NF_CT_NETLINK=y ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NETFILTER_XT_TARGET_NFLOG=y ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y ++CONFIG_NETFILTER_XT_TARGET_TPROXY=y ++CONFIG_NETFILTER_XT_TARGET_TRACE=y ++CONFIG_NETFILTER_XT_TARGET_SECMARK=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_MATCH_COMMENT=y ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y ++CONFIG_NETFILTER_XT_MATCH_LENGTH=y ++CONFIG_NETFILTER_XT_MATCH_LIMIT=y ++CONFIG_NETFILTER_XT_MATCH_MAC=y ++CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_OWNER=y ++CONFIG_NETFILTER_XT_MATCH_POLICY=y ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA2=y ++CONFIG_NETFILTER_XT_MATCH_SOCKET=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y ++CONFIG_NETFILTER_XT_MATCH_STRING=y ++CONFIG_NETFILTER_XT_MATCH_TIME=y ++CONFIG_NETFILTER_XT_MATCH_U32=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_NETMAP=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_SECURITY=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_L2TP=y ++CONFIG_BRIDGE=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_HTB=y ++CONFIG_NET_SCH_INGRESS=y ++CONFIG_NET_CLS_U32=y ++CONFIG_NET_CLS_BPF=y ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_U32=y ++CONFIG_NET_CLS_ACT=y ++CONFIG_VSOCKETS=y ++CONFIG_VIRTIO_VSOCKETS=y ++CONFIG_BT=y ++CONFIG_CFG80211=y ++# CONFIG_CFG80211_DEFAULT_PS is not set ++# CONFIG_CFG80211_CRDA_SUPPORT is not set ++CONFIG_MAC80211=y ++# CONFIG_MAC80211_RC_MINSTREL is not set ++CONFIG_RFKILL=y ++CONFIG_PCI=y ++CONFIG_PCI_HOST_GENERIC=y ++CONFIG_DEVTMPFS=y ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++CONFIG_DEBUG_DEVRES=y ++CONFIG_ZRAM=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_VIRTIO_BLK=y ++CONFIG_UID_SYS_STATS=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_UFSHCD=y ++CONFIG_SCSI_UFSHCD_PLATFORM=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_UEVENT=y ++CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_AVB=y ++CONFIG_DM_VERITY_FEC=y ++CONFIG_DM_BOW=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=y ++CONFIG_VIRTIO_NET=y ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++# CONFIG_NET_VENDOR_ALACRITECH is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_AQUANTIA is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++# CONFIG_NET_VENDOR_CADENCE is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++# CONFIG_NET_VENDOR_CORTINA is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_HP is not set ++# CONFIG_NET_VENDOR_HUAWEI is not set ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_MICROSEMI is not set ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETERION is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_NET_VENDOR_NI is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RDC is not set ++# CONFIG_NET_VENDOR_REALTEK is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SOLARFLARE is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_SOCIONEXT is not set ++CONFIG_STMMAC_ETH=y ++# CONFIG_DWMAC_GENERIC is not set ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_ROCKCHIP_PHY=y ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_MPPE=y ++CONFIG_PPTP=y ++CONFIG_PPPOL2TP=y ++CONFIG_USB_RTL8152=y ++CONFIG_USB_USBNET=y ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_VIRT_WIFI=y ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_UINPUT=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_EXAR is not set ++CONFIG_SERIAL_8250_NR_UARTS=48 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_MANY_PORTS=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_VIRTIO=y ++# CONFIG_HW_RANDOM_CAVIUM is not set ++# CONFIG_DEVPORT is not set ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_MUX_PINCTRL=y ++CONFIG_I2C_DEMUX_PINCTRL=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_I2C_DESIGNWARE_PLATFORM=y ++CONFIG_I2C_DESIGNWARE_SLAVE=y ++CONFIG_I2C_RK3X=y ++CONFIG_SPI=y ++CONFIG_SPI_ROCKCHIP=y ++CONFIG_SPMI=y ++CONFIG_DEBUG_PINCTRL=y ++CONFIG_PINCTRL_AMD=y ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_PINCTRL_RK805=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_GENERIC_PLATFORM=y ++CONFIG_POWER_AVS=y ++CONFIG_ROCKCHIP_IODOMAIN=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_POWER_RESET_GPIO_RESTART=y ++CONFIG_POWER_RESET_RESTART=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_POWER_RESET_SYSCON_POWEROFF=y ++CONFIG_SYSCON_REBOOT_MODE=y ++# CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_CPU_THERMAL=y ++CONFIG_DEVFREQ_THERMAL=y ++CONFIG_ROCKCHIP_THERMAL=y ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y ++# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set ++CONFIG_DW_WATCHDOG=y ++CONFIG_MFD_ACT8945A=y ++CONFIG_MFD_RK808=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_DEBUG=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_VIRTUAL_CONSUMER=y ++CONFIG_REGULATOR_USERSPACE_CONSUMER=y ++CONFIG_REGULATOR_GPIO=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_REGULATOR_RK808=y ++CONFIG_REGULATOR_VCTRL=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_VIDEO_V4L2_SUBDEV_API=y ++# CONFIG_VGA_ARB is not set ++CONFIG_DRM=y ++# CONFIG_DRM_FBDEV_EMULATION is not set ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_ROCKCHIP_DW_HDMI=y ++CONFIG_DRM_VIRTIO_GPU=y ++# CONFIG_LCD_CLASS_DEVICE is not set ++CONFIG_BACKLIGHT_CLASS_DEVICE=y ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_HRTIMER=y ++CONFIG_SND_DYNAMIC_MINORS=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_DRIVERS is not set ++CONFIG_SND_INTEL8X0=y ++CONFIG_SND_USB_AUDIO=y ++CONFIG_SND_SOC=y ++CONFIG_SND_SOC_TS3A227E=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_ELECOM=y ++CONFIG_HID_MAGICMOUSE=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MULTITOUCH=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_OTG=y ++CONFIG_USB_OTG_FSM=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++# CONFIG_USB_OHCI_HCD_PCI is not set ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_UEVENT=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_ACC=y ++CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_MMC=y ++# CONFIG_PWRSEQ_EMMC is not set ++# CONFIG_PWRSEQ_SIMPLE is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_OF_ARASAN=y ++CONFIG_MMC_SDHCI_OF_DWCMSHC=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_CQHCI=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_SYSTOHC is not set ++CONFIG_RTC_DRV_RK808=y ++CONFIG_RTC_DRV_PL030=y ++CONFIG_RTC_DRV_PL031=y ++CONFIG_DMADEVICES=y ++CONFIG_PL330_DMA=y ++CONFIG_VIRTIO_PCI=y ++# CONFIG_VIRTIO_PCI_LEGACY is not set ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_STAGING=y ++CONFIG_ASHMEM=y ++CONFIG_ANDROID_VSOC=y ++CONFIG_ION=y ++CONFIG_COMMON_CLK_RK808=y ++CONFIG_COMMON_CLK_SCPI=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_HWSPINLOCK=y ++# CONFIG_FSL_ERRATUM_A008585 is not set ++# CONFIG_HISILICON_ERRATUM_161010101 is not set ++CONFIG_MAILBOX=y ++CONFIG_ROCKCHIP_MBOX=y ++CONFIG_ROCKCHIP_IOMMU=y ++CONFIG_ARM_SMMU=y ++CONFIG_ROCKCHIP_PM_DOMAINS=y ++CONFIG_DEVFREQ_GOV_PERFORMANCE=y ++CONFIG_DEVFREQ_GOV_POWERSAVE=y ++CONFIG_DEVFREQ_GOV_USERSPACE=y ++CONFIG_DEVFREQ_GOV_PASSIVE=y ++CONFIG_ARM_RK3399_DMC_DEVFREQ=y ++CONFIG_PWM=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_EMMC=y ++CONFIG_PHY_ROCKCHIP_INNO_HDMI=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_USB=y ++CONFIG_ANDROID=y ++CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_INTERCONNECT=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_F2FS_FS=y ++CONFIG_F2FS_FS_SECURITY=y ++CONFIG_FS_ENCRYPTION=y ++# CONFIG_DNOTIFY is not set ++CONFIG_QUOTA=y ++CONFIG_QFMT_V2=y ++CONFIG_FUSE_FS=y ++CONFIG_OVERLAY_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y ++CONFIG_SECURITY=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_SECURITY_SELINUX=y ++CONFIG_CRYPTO_ADIANTUM=y ++CONFIG_CRYPTO_MD4=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DEV_ROCKCHIP=y ++CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC8=y ++CONFIG_XZ_DEC=y ++CONFIG_DMA_CMA=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_MUST_CHECK is not set ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_SOFTLOCKUP_DETECTOR=y ++# CONFIG_DETECT_HUNG_TASK is not set ++CONFIG_PANIC_TIMEOUT=5 ++CONFIG_SCHEDSTATS=y ++CONFIG_FUNCTION_TRACER=y ++# CONFIG_RUNTIME_TESTING_MENU is not set ++CONFIG_CORESIGHT=y ++CONFIG_CORESIGHT_STM=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch b/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch new file mode 100644 index 000000000000..dd0dd8b3968c --- /dev/null +++ b/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch @@ -0,0 +1,464 @@ +From 7d1009ce0de9f6f018be997f32989c3b51d5d57f Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Fri, 17 May 2019 16:52:29 -0700 +Subject: ANDROID: Add initial x86_64 gki_defconfig + +That is a copy from the aarch64 gki_defconfig. + +To be able to build in this configuration, + + + CONFIG_UNWINDER_FRAME_POINTER=y + +was necessary. + +Bug: 132113225 +Bug: 132629930 +Change-Id: I685ccea29efc7ba14f7b0a24f41983e37203f9a2 +Signed-off-by: Ram Muthiah +Signed-off-by: Matthias Maennich +--- + arch/x86/configs/gki_defconfig | 328 +++++++++++++++++++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 8 +- + build.config.cuttlefish.aarch64 | 3 +- + build.config.cuttlefish.x86_64 | 3 +- + build.config.gki.x86_64 | 17 + + 5 files changed, 352 insertions(+), 7 deletions(-) + create mode 100644 arch/x86/configs/gki_defconfig + create mode 100644 build.config.gki.x86_64 + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +new file mode 100644 +index 0000000000000..18ba312d0a602 +--- /dev/null ++++ b/arch/x86/configs/gki_defconfig +@@ -0,0 +1,328 @@ ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_PSI=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_BPF=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++# CONFIG_RD_LZ4 is not set ++# CONFIG_SYSFS_SYSCALL is not set ++# CONFIG_FHANDLE is not set ++CONFIG_KALLSYMS_ALL=y ++CONFIG_BPF_SYSCALL=y ++# CONFIG_RSEQ is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_PROFILING=y ++CONFIG_PM_WAKELOCKS=y ++CONFIG_PM_WAKELOCKS_LIMIT=0 ++# CONFIG_PM_WAKELOCKS_GC is not set ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_TIMES=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++# CONFIG_SPARSEMEM_VMEMMAP is not set ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_ZSMALLOC=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_XFRM_INTERFACE=y ++CONFIG_XFRM_STATISTICS=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_NET_IPGRE_DEMUX=y ++CONFIG_NET_IPVTI=y ++CONFIG_INET_ESP=y ++CONFIG_INET_UDP_DIAG=y ++CONFIG_INET_DIAG_DESTROY=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_ESP=y ++CONFIG_INET6_IPCOMP=y ++CONFIG_IPV6_MIP6=y ++CONFIG_IPV6_VTI=y ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_AMANDA=y ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_H323=y ++CONFIG_NF_CONNTRACK_IRC=y ++CONFIG_NF_CONNTRACK_NETBIOS_NS=y ++CONFIG_NF_CONNTRACK_PPTP=y ++CONFIG_NF_CONNTRACK_SANE=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NF_CT_NETLINK=y ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NETFILTER_XT_TARGET_NFLOG=y ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y ++CONFIG_NETFILTER_XT_TARGET_TPROXY=y ++CONFIG_NETFILTER_XT_TARGET_TRACE=y ++CONFIG_NETFILTER_XT_TARGET_SECMARK=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_MATCH_COMMENT=y ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y ++CONFIG_NETFILTER_XT_MATCH_LENGTH=y ++CONFIG_NETFILTER_XT_MATCH_LIMIT=y ++CONFIG_NETFILTER_XT_MATCH_MAC=y ++CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_OWNER=y ++CONFIG_NETFILTER_XT_MATCH_POLICY=y ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA2=y ++CONFIG_NETFILTER_XT_MATCH_SOCKET=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y ++CONFIG_NETFILTER_XT_MATCH_STRING=y ++CONFIG_NETFILTER_XT_MATCH_TIME=y ++CONFIG_NETFILTER_XT_MATCH_U32=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_NETMAP=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_SECURITY=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_L2TP=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_HTB=y ++CONFIG_NET_SCH_INGRESS=y ++CONFIG_NET_CLS_U32=y ++CONFIG_NET_CLS_BPF=y ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_U32=y ++CONFIG_NET_CLS_ACT=y ++CONFIG_VSOCKETS=y ++CONFIG_VIRTIO_VSOCKETS=y ++CONFIG_CFG80211=y ++# CONFIG_CFG80211_DEFAULT_PS is not set ++# CONFIG_CFG80211_CRDA_SUPPORT is not set ++CONFIG_MAC80211=y ++# CONFIG_MAC80211_RC_MINSTREL is not set ++CONFIG_RFKILL=y ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++CONFIG_DEBUG_DEVRES=y ++CONFIG_ZRAM=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_VIRTIO_BLK=y ++CONFIG_UID_SYS_STATS=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_VIRTIO=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_UEVENT=y ++CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_AVB=y ++CONFIG_DM_VERITY_FEC=y ++CONFIG_DM_BOW=y ++CONFIG_NETDEVICES=y ++CONFIG_TUN=y ++CONFIG_VIRTIO_NET=y ++# CONFIG_ETHERNET is not set ++CONFIG_PHYLIB=y ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_MPPE=y ++CONFIG_PPTP=y ++CONFIG_PPPOL2TP=y ++CONFIG_USB_RTL8152=y ++CONFIG_USB_USBNET=y ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_VIRT_WIFI=y ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_UINPUT=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=48 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_MANY_PORTS=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_VIRTIO=y ++# CONFIG_I2C_COMPAT is not set ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_GPIOLIB=y ++# CONFIG_HWMON is not set ++CONFIG_DEVFREQ_THERMAL=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_DRM=y ++# CONFIG_DRM_FBDEV_EMULATION is not set ++CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_BACKLIGHT_CLASS_DEVICE=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_HRTIMER=y ++CONFIG_SND_DYNAMIC_MINORS=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_DRIVERS is not set ++# CONFIG_SND_USB is not set ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_ELECOM=y ++CONFIG_HID_MAGICMOUSE=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MULTITOUCH=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_UEVENT=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_ACC=y ++CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_MMC=y ++# CONFIG_MMC_BLOCK is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_SYSTOHC is not set ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_STAGING=y ++CONFIG_ASHMEM=y ++CONFIG_ION=y ++CONFIG_MAILBOX=y ++CONFIG_PM_DEVFREQ=y ++CONFIG_ANDROID=y ++CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_F2FS_FS=y ++CONFIG_F2FS_FS_SECURITY=y ++# CONFIG_DNOTIFY is not set ++CONFIG_QUOTA=y ++CONFIG_QFMT_V2=y ++CONFIG_FUSE_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y ++CONFIG_SECURITY=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_SECURITY_SELINUX=y ++CONFIG_CRYPTO_ADIANTUM=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_CRC8=y ++CONFIG_XZ_DEC=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_MUST_CHECK is not set ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_SOFTLOCKUP_DETECTOR=y ++# CONFIG_DETECT_HUNG_TASK is not set ++CONFIG_PANIC_TIMEOUT=5 ++CONFIG_SCHEDSTATS=y ++# CONFIG_RUNTIME_TESTING_MENU is not set ++CONFIG_UNWINDER_FRAME_POINTER=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index d1f0fa08eacfb..06c931405999c 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -67,7 +67,6 @@ CONFIG_IA32_EMULATION=y + # CONFIG_FIRMWARE_MEMMAP is not set + CONFIG_OPROFILE=y + CONFIG_KPROBES=y +-CONFIG_JUMP_LABEL=y + CONFIG_REFCOUNT_FULL=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y +@@ -96,7 +95,6 @@ CONFIG_IP_PIMSM_V2=y + CONFIG_SYN_COOKIES=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +-# CONFIG_INET_XFRM_MODE_BEET is not set + CONFIG_INET_UDP_DIAG=y + CONFIG_INET_DIAG_DESTROY=y + CONFIG_TCP_CONG_ADVANCED=y +@@ -199,7 +197,8 @@ CONFIG_VIRTIO_VSOCKETS=y + CONFIG_CFG80211=y + CONFIG_MAC80211=y + CONFIG_RFKILL=y +-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y + CONFIG_DEVTMPFS=y + CONFIG_DEBUG_DEVRES=y + CONFIG_OF=y +@@ -459,10 +458,10 @@ CONFIG_DEBUG_INFO=y + # CONFIG_ENABLE_MUST_CHECK is not set + CONFIG_FRAME_WARN=1024 + # CONFIG_UNUSED_SYMBOLS is not set ++CONFIG_OPTIMIZE_INLINING=y + CONFIG_MAGIC_SYSRQ=y + CONFIG_DEBUG_STACK_USAGE=y + CONFIG_DEBUG_MEMORY_INIT=y +-CONFIG_DEBUG_STACKOVERFLOW=y + CONFIG_HARDLOCKUP_DETECTOR=y + CONFIG_PANIC_TIMEOUT=5 + CONFIG_SCHEDSTATS=y +@@ -470,5 +469,4 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=60 + CONFIG_ENABLE_DEFAULT_TRACERS=y + CONFIG_IO_DELAY_NONE=y + CONFIG_DEBUG_BOOT_PARAMS=y +-CONFIG_OPTIMIZE_INLINING=y + CONFIG_UNWINDER_FRAME_POINTER=y +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index ec53d6eac9ea3..bec1288d65e13 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -1,7 +1,8 @@ + ARCH=arm64 +-BRANCH=android-4.19 ++BRANCH=android-mainline + CLANG_TRIPLE=aarch64-linux-gnu- + CROSS_COMPILE=aarch64-linux-androidkernel- ++CC=clang + DEFCONFIG=cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index b49683d476d62..33063abed0edb 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -1,7 +1,8 @@ + ARCH=x86_64 +-BRANCH=android-4.19 ++BRANCH=android-mainline + CLANG_TRIPLE=x86_64-linux-gnu- + CROSS_COMPILE=x86_64-linux-androidkernel- ++CC=clang + DEFCONFIG=x86_64_cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common +diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 +new file mode 100644 +index 0000000000000..69d339dce4a0f +--- /dev/null ++++ b/build.config.gki.x86_64 +@@ -0,0 +1,17 @@ ++ARCH=x86_64 ++BRANCH=android-mainline ++CLANG_TRIPLE=x86_64-linux-gnu- ++CROSS_COMPILE=x86_64-linux-androidkernel- ++CC=clang ++DEFCONFIG=gki_defconfig ++EXTRA_CMDS='' ++KERNEL_DIR=common ++POST_DEFCONFIG_CMDS="check_defconfig" ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin ++FILES=" ++arch/x86/boot/bzImage ++vmlinux ++System.map ++" ++STOP_SHIP_TRACEPRINTK=1 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch b/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch new file mode 100644 index 000000000000..715ab723e988 --- /dev/null +++ b/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch @@ -0,0 +1,56 @@ +From 21019d4dee6cac07eebc9a624bf967fe22e1d902 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Tue, 16 Jul 2019 18:09:39 -0700 +Subject: ANDROID: Add show_options2 to view private mount data + +Exposes private fs data via show_options2 + +Bug: 120446149 +Change-Id: I2d1c06fae274eeac03ac1924ef162f7bbb2f29d0 +Signed-off-by: Daniel Rosenberg +--- + fs/proc_namespace.c | 8 ++++++-- + include/linux/fs.h | 1 + + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c +index e16fb8f2049e7..8fde658fdb112 100644 +--- a/fs/proc_namespace.c ++++ b/fs/proc_namespace.c +@@ -121,7 +121,9 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt) + if (err) + goto out; + show_mnt_opts(m, mnt); +- if (sb->s_op->show_options) ++ if (sb->s_op->show_options2) ++ err = sb->s_op->show_options2(mnt, m, mnt_path.dentry); ++ else if (sb->s_op->show_options) + err = sb->s_op->show_options(m, mnt_path.dentry); + seq_puts(m, " 0 0\n"); + out: +@@ -183,7 +185,9 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) + err = show_sb_opts(m, sb); + if (err) + goto out; +- if (sb->s_op->show_options) ++ if (sb->s_op->show_options2) { ++ err = sb->s_op->show_options2(mnt, m, mnt->mnt_root); ++ } else if (sb->s_op->show_options) + err = sb->s_op->show_options(m, mnt->mnt_root); + seq_putc(m, '\n'); + out: +diff --git a/include/linux/fs.h b/include/linux/fs.h +index e9c1d5637c171..045bd6ff12ae1 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1940,6 +1940,7 @@ struct super_operations { + void (*umount_begin) (struct super_block *); + + int (*show_options)(struct seq_file *, struct dentry *); ++ int (*show_options2)(struct vfsmount *,struct seq_file *, struct dentry *); + int (*show_devname)(struct seq_file *, struct dentry *); + int (*show_path)(struct seq_file *, struct dentry *); + int (*show_stats)(struct seq_file *, struct dentry *); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfi.patch b/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfi.patch new file mode 100644 index 000000000000..405d361f327d --- /dev/null +++ b/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfi.patch @@ -0,0 +1,176 @@ +From 8417edc3abbfaccc38e1bd89fd7f66232d73d541 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Wed, 4 Sep 2019 12:25:57 -0700 +Subject: ANDROID: Catch rockpi4_defconfig up with + gki_defconfig + +Change-Id: I640112a903d0b4944a087a4408241b901f37f6b8 +Signed-off-by: Alistair Delva +--- + arch/arm64/configs/rockpi4_defconfig | 31 +++++++++++++++------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig +index 6d0cf70f37570..2f97c1a8a60a6 100644 +--- a/arch/arm64/configs/rockpi4_defconfig ++++ b/arch/arm64/configs/rockpi4_defconfig +@@ -1,3 +1,4 @@ ++CONFIG_LOCALVERSION="-mainline" + CONFIG_AUDIT=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y +@@ -24,7 +25,6 @@ CONFIG_BLK_DEV_INITRD=y + # CONFIG_RD_LZO is not set + # CONFIG_RD_LZ4 is not set + # CONFIG_SYSFS_SYSCALL is not set +-CONFIG_FHANDLE=y + CONFIG_KALLSYMS_ALL=y + CONFIG_BPF_SYSCALL=y + # CONFIG_RSEQ is not set +@@ -35,8 +35,10 @@ CONFIG_EMBEDDED=y + CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y ++CONFIG_ARCH_QCOM=y + CONFIG_ARCH_ROCKCHIP=y + CONFIG_SCHED_MC=y ++CONFIG_NR_CPUS=32 + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y + CONFIG_COMPAT=y +@@ -45,9 +47,7 @@ CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y + CONFIG_RANDOMIZE_BASE=y +-CONFIG_CMDLINE="" +-# CONFIG_CMDLINE_FORCE is not set +-# CONFIG_EFI is not set ++# CONFIG_DMI is not set + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +@@ -65,6 +65,7 @@ CONFIG_ARM_SCMI_PROTOCOL=y + # CONFIG_ARM_SCMI_POWER_DOMAIN is not set + CONFIG_ARM_SCPI_PROTOCOL=y + # CONFIG_ARM_SCPI_POWER_DOMAIN is not set ++# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set + CONFIG_VIRTUALIZATION=y + CONFIG_KVM=y + CONFIG_VHOST_VSOCK=y +@@ -93,7 +94,6 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IP_PNP=y + CONFIG_NET_IPGRE_DEMUX=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +@@ -108,6 +108,7 @@ CONFIG_IPV6_MIP6=y + CONFIG_IPV6_VTI=y + CONFIG_IPV6_MULTIPLE_TABLES=y + CONFIG_NETFILTER=y ++# CONFIG_BRIDGE_NETFILTER is not set + CONFIG_NF_CONNTRACK=y + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +@@ -176,6 +177,7 @@ CONFIG_IP6_NF_FILTER=y + CONFIG_IP6_NF_TARGET_REJECT=y + CONFIG_IP6_NF_MANGLE=y + CONFIG_IP6_NF_RAW=y ++CONFIG_TIPC=y + CONFIG_L2TP=y + CONFIG_BRIDGE=y + CONFIG_NET_SCHED=y +@@ -376,7 +378,6 @@ CONFIG_WATCHDOG_PRETIMEOUT_GOV=y + CONFIG_DW_WATCHDOG=y + CONFIG_MFD_ACT8945A=y + CONFIG_MFD_RK808=y +-CONFIG_REGULATOR=y + CONFIG_REGULATOR_DEBUG=y + CONFIG_REGULATOR_FIXED_VOLTAGE=y + CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +@@ -388,7 +389,6 @@ CONFIG_REGULATOR_VCTRL=y + CONFIG_MEDIA_SUPPORT=y + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_MEDIA_CONTROLLER=y +-CONFIG_VIDEO_V4L2_SUBDEV_API=y + # CONFIG_VGA_ARB is not set + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set +@@ -397,7 +397,6 @@ CONFIG_ROCKCHIP_DW_HDMI=y + CONFIG_DRM_VIRTIO_GPU=y + # CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y +-# CONFIG_BACKLIGHT_GENERIC is not set + CONFIG_SOUND=y + CONFIG_SND=y + CONFIG_SND_HRTIMER=y +@@ -427,6 +426,7 @@ CONFIG_USB_OHCI_HCD=y + # CONFIG_USB_OHCI_HCD_PCI is not set + CONFIG_USB_OHCI_HCD_PLATFORM=y + CONFIG_USB_GADGET=y ++CONFIG_USB_DUMMY_HCD=m + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y +@@ -442,10 +442,10 @@ CONFIG_MMC_SDHCI_OF_ARASAN=y + CONFIG_MMC_SDHCI_OF_DWCMSHC=y + CONFIG_MMC_DW=y + CONFIG_MMC_DW_ROCKCHIP=y +-CONFIG_MMC_CQHCI=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y ++CONFIG_EDAC=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set + CONFIG_RTC_DRV_RK808=y +@@ -462,16 +462,17 @@ CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y ++CONFIG_ION_SYSTEM_HEAP=y ++CONFIG_ION_SYSTEM_CONTIG_HEAP=y + CONFIG_COMMON_CLK_RK808=y + CONFIG_COMMON_CLK_SCPI=y +-# CONFIG_COMMON_CLK_XGENE is not set + CONFIG_HWSPINLOCK=y +-# CONFIG_FSL_ERRATUM_A008585 is not set +-# CONFIG_HISILICON_ERRATUM_161010101 is not set + CONFIG_MAILBOX=y + CONFIG_ROCKCHIP_MBOX=y + CONFIG_ROCKCHIP_IOMMU=y + CONFIG_ARM_SMMU=y ++CONFIG_QCOM_COMMAND_DB=y ++CONFIG_QCOM_RPMH=y + CONFIG_ROCKCHIP_PM_DOMAINS=y + CONFIG_DEVFREQ_GOV_PERFORMANCE=y + CONFIG_DEVFREQ_GOV_POWERSAVE=y +@@ -480,10 +481,12 @@ CONFIG_DEVFREQ_GOV_PASSIVE=y + CONFIG_ARM_RK3399_DMC_DEVFREQ=y + CONFIG_PWM=y + CONFIG_PWM_ROCKCHIP=y ++CONFIG_QCOM_PDC=y + CONFIG_PHY_ROCKCHIP_EMMC=y + CONFIG_PHY_ROCKCHIP_INNO_HDMI=y + CONFIG_PHY_ROCKCHIP_INNO_USB2=y + CONFIG_PHY_ROCKCHIP_USB=y ++CONFIG_RAS=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y + CONFIG_ROCKCHIP_EFUSE=y +@@ -500,9 +503,9 @@ CONFIG_FUSE_FS=y + CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +-CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y +-CONFIG_ECRYPT_FS=y ++# CONFIG_EFIVAR_FS is not set ++CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch b/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch new file mode 100644 index 000000000000..78fea44efe93 --- /dev/null +++ b/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch @@ -0,0 +1,42 @@ +From b2cb642b34dc982ed62783a109d7b73097942f6f Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Wed, 8 May 2019 23:07:39 +0100 +Subject: ANDROID: Expose gki_defconfig to build.config + +With this in place, the gki_defconfig can be build with build.sh +machinery. + +Bug: 132113225 +Change-Id: I4c623a866cd41aa4587e4fab1c4e5254f6680542 +Signed-off-by: Matthias Maennich +--- + build.config.gki.aarch64 | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + create mode 100644 build.config.gki.aarch64 + +diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 +new file mode 100644 +index 0000000000000..dec295284ffa0 +--- /dev/null ++++ b/build.config.gki.aarch64 +@@ -0,0 +1,17 @@ ++ARCH=arm64 ++BRANCH=android-mainline ++CLANG_TRIPLE=aarch64-linux-gnu- ++CROSS_COMPILE=aarch64-linux-androidkernel- ++CC=clang ++DEFCONFIG=gki_defconfig ++EXTRA_CMDS='' ++KERNEL_DIR=common ++POST_DEFCONFIG_CMDS="check_defconfig" ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin ++FILES=" ++arch/arm64/boot/Image.gz ++vmlinux ++System.map ++" ++STOP_SHIP_TRACEPRINTK=1 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Fix-arm64-allmodconfig-build.patch b/patches/ANDROID-Fix-arm64-allmodconfig-build.patch new file mode 100644 index 000000000000..3aa7075e1836 --- /dev/null +++ b/patches/ANDROID-Fix-arm64-allmodconfig-build.patch @@ -0,0 +1,37 @@ +From 099f0261d93727c97aa0dea2ed22bedf991fe574 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Tue, 24 Sep 2019 17:28:02 +0100 +Subject: ANDROID: Fix arm64 allmodconfig build + +Allmodconfig on arm64 enables CPU_BIG_ENDIAN=y, which causes issues with +ld.lld which doesn't support linking aarch64be-linux-gnu targets (see +https://reviews.llvm.org/D58655#1410281). However, it is very unlikely +that real android devices run with arm64 BE hardware in practice. So, +until we can find a better fix, let's simply force CPU_BIG_ENDIAN=n for +allmodconfig builds. + +Bug: 141733632 +Bug: 140224784 +Signed-off-by: Quentin Perret +Change-Id: Ic4693ae1f462144c8219b397463ca341f6fe08a1 +--- + build.config.allmodconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/build.config.allmodconfig b/build.config.allmodconfig +index 6e0404b8de47..deaa8f3d5a69 100644 +--- a/build.config.allmodconfig ++++ b/build.config.allmodconfig +@@ -6,7 +6,8 @@ POST_DEFCONFIG_CMDS="update_config" + function update_config() { + ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \ + -d TEST_KMOD \ +- -d XFS_FS ++ -d XFS_FS \ ++ -d CPU_BIG_ENDIAN + (cd ${OUT_DIR} && \ + make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Fixed-x86-regression.patch b/patches/ANDROID-Fixed-x86-regression.patch new file mode 100644 index 000000000000..07d9c2abe027 --- /dev/null +++ b/patches/ANDROID-Fixed-x86-regression.patch @@ -0,0 +1,46 @@ +From 819b4d829053dd13e02aebc14f14b92078907655 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 12 Jun 2019 14:25:25 -0700 +Subject: ANDROID: Fixed x86 regression + +Added SMP and CMDLINE to defconfig + +Test: Boot x86 gki +Change-Id: I6930d60dceb5b180825337d5371d375259984a33 +Signed-off-by: Ram Muthiah +--- + arch/x86/configs/gki_defconfig | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 864595c719e76..94690e9d016a2 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -33,13 +33,14 @@ CONFIG_EMBEDDED=y + CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y ++CONFIG_SMP=y ++CONFIG_CMDLINE_BOOL=y ++CONFIG_CMDLINE="console=ttyS0 reboot=p" + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +-CONFIG_CPU_FREQ=y + CONFIG_CPU_FREQ_TIMES=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=y +-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y + CONFIG_IA32_EMULATION=y + CONFIG_KPROBES=y + CONFIG_MODULES=y +@@ -288,7 +289,6 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ION=y +-CONFIG_MAILBOX=y + CONFIG_PM_DEVFREQ=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch new file mode 100644 index 000000000000..f6be530f0b03 --- /dev/null +++ b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch @@ -0,0 +1,38 @@ +From 1f523078f2c7bac8531c68f5b72e42157c202fce Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 21 May 2019 18:15:10 -0700 +Subject: + +Revert "x86/uaccess: Dont leak the AC flag into __put_user() argument evaluation" +This reverts commit 6ae865615fc43d014da2fd1f1bba7e81ee622d1b. + +Bug: 120440614 +Bug: 132629930 +Change-Id: I38f78e20d255ab4b33546d2e9d98f64d7e590e1d +Signed-off-by: Ram Muthiah +--- + arch/x86/include/asm/uaccess.h | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index 35c225ede0e4f..29920ffb5df10 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -429,11 +429,10 @@ do { \ + ({ \ + __label__ __pu_label; \ + int __pu_err = -EFAULT; \ +- __typeof__(*(ptr)) __pu_val = (x); \ +- __typeof__(ptr) __pu_ptr = (ptr); \ +- __typeof__(size) __pu_size = (size); \ ++ __typeof__(*(ptr)) __pu_val; \ ++ __pu_val = x; \ + __uaccess_begin(); \ +- __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ ++ __put_user_size(__pu_val, (ptr), (size), __pu_label); \ + __pu_err = 0; \ + __pu_label: \ + __uaccess_end(); \ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch new file mode 100644 index 000000000000..7c1db35969b2 --- /dev/null +++ b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch @@ -0,0 +1,44 @@ +From 6cbeaede2e4fdb044c67d99722a66b73b11b6701 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 21 May 2019 18:15:21 -0700 +Subject: + +Revert "x86/uaccess: Don't leak the AC flag into __put_user() value evaluation" +This reverts commit 2a418cf3f5f1caf911af288e978d61c9844b0695. + +Bug: 120440614 +Bug: 132629930 +Change-Id: Ib177230b39d1247060f425205d63d65065ed936a +Signed-off-by: Ram Muthiah +--- + arch/x86/include/asm/uaccess.h | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index 29920ffb5df10..c647784dd0c40 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -282,7 +282,7 @@ do { \ + __put_user_goto(x, ptr, "l", "k", "ir", label); \ + break; \ + case 8: \ +- __put_user_goto_u64(x, ptr, label); \ ++ __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ + break; \ + default: \ + __put_user_bad(); \ +@@ -429,10 +429,8 @@ do { \ + ({ \ + __label__ __pu_label; \ + int __pu_err = -EFAULT; \ +- __typeof__(*(ptr)) __pu_val; \ +- __pu_val = x; \ + __uaccess_begin(); \ +- __put_user_size(__pu_val, (ptr), (size), __pu_label); \ ++ __put_user_size((x), (ptr), (size), __pu_label); \ + __pu_err = 0; \ + __pu_label: \ + __uaccess_end(); \ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch new file mode 100644 index 000000000000..2b26bb896bac --- /dev/null +++ b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch @@ -0,0 +1,127 @@ +From c4a6bc72fb2b9bd99de674d603b82ad74f5cbdb3 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 21 May 2019 18:20:17 -0700 +Subject: + +Revert "Use __put_user_goto in __put_user_size() and unsafe_put_user()" +This reverts commit a959dc88f9c8900296ccf13e2f3e1cbc555a8917. + +Bug: 120440614 +Bug: 132629930 +Change-Id: I07410ed2bc7552f16ec119fbc2001bb43ffef6f4 +Signed-off-by: Ram Muthiah +--- + arch/x86/include/asm/uaccess.h | 57 ++++++++++++++++++++-------------- + 1 file changed, 33 insertions(+), 24 deletions(-) + +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index c647784dd0c40..01e410fa97d99 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -184,14 +184,19 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) + + + #ifdef CONFIG_X86_32 +-#define __put_user_goto_u64(x, addr, label) \ +- asm_volatile_goto("\n" \ +- "1: movl %%eax,0(%1)\n" \ +- "2: movl %%edx,4(%1)\n" \ +- _ASM_EXTABLE_UA(1b, %l2) \ +- _ASM_EXTABLE_UA(2b, %l2) \ +- : : "A" (x), "r" (addr) \ +- : : label) ++#define __put_user_asm_u64(x, addr, err, errret) \ ++ asm volatile("\n" \ ++ "1: movl %%eax,0(%2)\n" \ ++ "2: movl %%edx,4(%2)\n" \ ++ "3:" \ ++ ".section .fixup,\"ax\"\n" \ ++ "4: movl %3,%0\n" \ ++ " jmp 3b\n" \ ++ ".previous\n" \ ++ _ASM_EXTABLE_UA(1b, 4b) \ ++ _ASM_EXTABLE_UA(2b, 4b) \ ++ : "=r" (err) \ ++ : "A" (x), "r" (addr), "i" (errret), "0" (err)) + + #define __put_user_asm_ex_u64(x, addr) \ + asm volatile("\n" \ +@@ -206,8 +211,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) + asm volatile("call __put_user_8" : "=a" (__ret_pu) \ + : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") + #else +-#define __put_user_goto_u64(x, ptr, label) \ +- __put_user_goto(x, ptr, "q", "", "er", label) ++#define __put_user_asm_u64(x, ptr, retval, errret) \ ++ __put_user_asm(x, ptr, retval, "q", "", "er", errret) + #define __put_user_asm_ex_u64(x, addr) \ + __put_user_asm_ex(x, addr, "q", "", "er") + #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) +@@ -268,21 +273,23 @@ extern void __put_user_8(void); + __builtin_expect(__ret_pu, 0); \ + }) + +-#define __put_user_size(x, ptr, size, label) \ ++#define __put_user_size(x, ptr, size, retval, errret) \ + do { \ ++ retval = 0; \ + __chk_user_ptr(ptr); \ + switch (size) { \ + case 1: \ +- __put_user_goto(x, ptr, "b", "b", "iq", label); \ ++ __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ + break; \ + case 2: \ +- __put_user_goto(x, ptr, "w", "w", "ir", label); \ ++ __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ + break; \ + case 4: \ +- __put_user_goto(x, ptr, "l", "k", "ir", label); \ ++ __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ + break; \ + case 8: \ +- __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ ++ __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \ ++ errret); \ + break; \ + default: \ + __put_user_bad(); \ +@@ -427,12 +434,9 @@ do { \ + + #define __put_user_nocheck(x, ptr, size) \ + ({ \ +- __label__ __pu_label; \ +- int __pu_err = -EFAULT; \ ++ int __pu_err; \ + __uaccess_begin(); \ +- __put_user_size((x), (ptr), (size), __pu_label); \ +- __pu_err = 0; \ +-__pu_label: \ ++ __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ + __uaccess_end(); \ + __builtin_expect(__pu_err, 0); \ + }) +@@ -716,11 +720,16 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt + #define user_access_begin(a,b) user_access_begin(a,b) + #define user_access_end() __uaccess_end() + +-#define user_access_save() smap_save() +-#define user_access_restore(x) smap_restore(x) ++#define user_access_save() smap_save() ++#define user_access_restore(x) smap_restore(x) + +-#define unsafe_put_user(x, ptr, label) \ +- __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) ++#define unsafe_put_user(x, ptr, err_label) \ ++do { \ ++ int __pu_err; \ ++ __typeof__(*(ptr)) __pu_val = (x); \ ++ __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \ ++ if (unlikely(__pu_err)) goto err_label; \ ++} while (0) + + #define unsafe_get_user(x, ptr, err_label) \ + do { \ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch new file mode 100644 index 000000000000..1a778df0965e --- /dev/null +++ b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch @@ -0,0 +1,58 @@ +From 43da3e283a034446549fa6e8847a5dcbd3614422 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 21 May 2019 18:21:54 -0700 +Subject: + +Revert "x86 uaccess: Introduce __put_user_goto" +This reverts commit 4a789213c9a54c8b618924d3421e56e98df8a447. + +Bug: 120440614 +Bug: 132629930 +Change-Id: If5e90d475d74d9aa3505972f43bc4ee48bed038f +Signed-off-by: Ram Muthiah +--- + arch/x86/include/asm/uaccess.h | 28 +++++++++++----------------- + 1 file changed, 11 insertions(+), 17 deletions(-) + +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index 01e410fa97d99..b498ffae35cac 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -463,23 +463,17 @@ struct __large_struct { unsigned long buf[100]; }; + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +-#define __put_user_goto(x, addr, itype, rtype, ltype, label) \ +- asm_volatile_goto("\n" \ +- "1: mov"itype" %"rtype"0,%1\n" \ +- _ASM_EXTABLE_UA(1b, %l2) \ +- : : ltype(x), "m" (__m(addr)) \ +- : : label) +- +-#define __put_user_failed(x, addr, itype, rtype, ltype, errret) \ +- ({ __label__ __puflab; \ +- int __pufret = errret; \ +- __put_user_goto(x,addr,itype,rtype,ltype,__puflab); \ +- __pufret = 0; \ +- __puflab: __pufret; }) +- +-#define __put_user_asm(x, addr, retval, itype, rtype, ltype, errret) do { \ +- retval = __put_user_failed(x, addr, itype, rtype, ltype, errret); \ +-} while (0) ++#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ ++ asm volatile("\n" \ ++ "1: mov"itype" %"rtype"1,%2\n" \ ++ "2:\n" \ ++ ".section .fixup,\"ax\"\n" \ ++ "3: mov %3,%0\n" \ ++ " jmp 2b\n" \ ++ ".previous\n" \ ++ _ASM_EXTABLE_UA(1b, 3b) \ ++ : "=r"(err) \ ++ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) + + #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ + asm volatile("1: mov"itype" %"rtype"0,%1\n" \ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch b/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch new file mode 100644 index 000000000000..cba52f487d7e --- /dev/null +++ b/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch @@ -0,0 +1,29 @@ +From ec89293b2fdbe45c5af7a6e9d9456adb0f0ecf6b Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Tue, 3 Sep 2019 09:42:35 -0700 +Subject: ANDROID: GKI: enable CONFIG_SPI for x86 + +Adds compile coverage for SPI in the TH builds, runtime no so much. + +Signed-off-by: Mark Salyzyn +Bug: 140290328 +Change-Id: I2d7777ab0e671248084880e5c1770b6ec6d7a650 +--- + arch/x86/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index e86cd1009a67c..9b76d55e8c413 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -240,6 +240,7 @@ CONFIG_HW_RANDOM=y + CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y + CONFIG_GPIOLIB=y + # CONFIG_HWMON is not set + CONFIG_DEVFREQ_THERMAL=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch b/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch new file mode 100644 index 000000000000..2151d4f88ddc --- /dev/null +++ b/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch @@ -0,0 +1,29 @@ +From f88ffe6c2675a7ed714dc614478ab527669bfe4e Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Tue, 3 Sep 2019 13:17:23 -0700 +Subject: ANDROID: GKI: enable CONFIG_TIPC for x86 + +Adds compile coverage for TIPC in the TH builds, runtime not so much. + +Signed-off-by: Mark Salyzyn +Bug: 140406060 +Change-Id: I7731157396372683c906f1f4eb2fdbdb7015f446 +--- + arch/x86/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 9b76d55e8c413..6b0ff4ca236ab 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -145,6 +145,7 @@ CONFIG_IP6_NF_FILTER=y + CONFIG_IP6_NF_TARGET_REJECT=y + CONFIG_IP6_NF_MANGLE=y + CONFIG_IP6_NF_RAW=y ++CONFIG_TIPC=y + CONFIG_L2TP=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-mo.patch b/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-mo.patch new file mode 100644 index 000000000000..0b058ad007d4 --- /dev/null +++ b/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-mo.patch @@ -0,0 +1,59 @@ +From 716306e82c3cdc7ef3347f3b84db5980c873bb22 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Fri, 13 Sep 2019 14:50:38 -0700 +Subject: ANDROID: GKI: export cma symbols for cma heap as + a module + +Bug: 140294230 +Test: builds + +Change-Id: I04c12174934c24a704d5c1e5be3e7e948c777a78 +Signed-off-by: Sandeep Patil +--- + mm/cma.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/mm/cma.c b/mm/cma.c +index 7fe0b8356775..db4642e58058 100644 +--- a/mm/cma.c ++++ b/mm/cma.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -54,6 +55,7 @@ const char *cma_get_name(const struct cma *cma) + { + return cma->name ? cma->name : "(undefined)"; + } ++EXPORT_SYMBOL_GPL(cma_get_name); + + static unsigned long cma_bitmap_aligned_mask(const struct cma *cma, + unsigned int align_order) +@@ -500,6 +502,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, + pr_debug("%s(): returned %p\n", __func__, page); + return page; + } ++EXPORT_SYMBOL_GPL(cma_alloc); + + /** + * cma_release() - release allocated pages +@@ -533,6 +536,7 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count) + + return true; + } ++EXPORT_SYMBOL_GPL(cma_release); + + int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) + { +@@ -547,3 +551,4 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) + + return 0; + } ++EXPORT_SYMBOL_GPL(cma_for_each_area); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch b/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch new file mode 100644 index 000000000000..d99e5ea2201d --- /dev/null +++ b/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch @@ -0,0 +1,60 @@ +From 553049f81c5ad43603aa9b9a813d9c965ce6f2d7 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Tue, 28 May 2019 12:38:16 +0100 +Subject: ANDROID: Initial abi_gki_aarch64 definition + +abi_gki_aarch64.out contains the ABI definition corresponding to the +current sources and the configuration referred to in +build.config.gki.aarch64. + +As part of the build.sh tooling it will be copied over into the +distribution for further inspection / analysis. See +https://android-review.googlesource.com/970737 for details on that +process. + +This is the initial version of this definition to allow implementation +of workflows around it. It is not considered stable at this point. It is +expected that it will break with significant changes from either +upstream or with changes implemented specific for this tree. Automated +validation is supposed to catch differences between this definition and +the actual binary before they are introduced into the tree. At a later +stage this validation should be part of build.sh itself. + +Bug: 133501930 +Change-Id: I815940ee13037ad450547e0ab0786e37f0b83d9b +Signed-off-by: Matthias Maennich +--- + abi_gki_aarch64.out | 319440 ++++++++++++++++++++++++++++++++++++ + build.config.gki.aarch64 | 1 + + 2 files changed, 319441 insertions(+) + create mode 100644 abi_gki_aarch64.out + +Index: common/build.config.gki.aarch64 +=================================================================== +--- common.orig/build.config.gki.aarch64 ++++ common/build.config.gki.aarch64 +@@ -1,19 +1,5 @@ +-ARCH=arm64 +-BRANCH=android-mainline +-CLANG_TRIPLE=aarch64-linux-gnu- +-CROSS_COMPILE=aarch64-linux-androidkernel- +-CC=clang +-DEFCONFIG=gki_defconfig +-EXTRA_CMDS='' +-KERNEL_DIR=common +-POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 +-LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin +-FILES=" +-arch/arm64/boot/Image.gz +-vmlinux +-System.map +-" +-STOP_SHIP_TRACEPRINTK=1 +-BUILD_INITRAMFS=1 ++. ${ROOT_DIR}/common/build.config.common ++. ${ROOT_DIR}/common/build.config.aarch64 ++. ${ROOT_DIR}/common/build.config.gki ++ ++ABI_DEFINITION=abi_gki_aarch64.xml diff --git a/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-targ.patch b/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-targ.patch new file mode 100644 index 000000000000..2560fb206bf6 --- /dev/null +++ b/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-targ.patch @@ -0,0 +1,65 @@ +From 134911c36422e676c97964a4eddc66d6fbd00da9 Mon Sep 17 00:00:00 2001 +From: Greg Hackmann +Date: Tue, 25 Oct 2016 13:59:59 -0700 +Subject: ANDROID: Kbuild, LLVMLinux: allow overriding clang + target triple + +Android has an unusual setup where the kernel needs to target +[arch]-linux-gnu to avoid Android userspace-specific flags and +optimizations, but AOSP doesn't ship a matching binutils. + +Add a new variable CLANG_TRIPLE which can override the "-target" triple +used to compile the kernel, while using a different CROSS_COMPILE to +pick the binutils/gcc installation. For Android you'd do something +like: + + export CLANG_TRIPLE=aarch64-linux-gnu- + export CROSS_COMPILE=aarch64-linux-android- + +If you don't need something like this, leave CLANG_TRIPLE unset and it +will default to CROSS_COMPILE. + +Change-Id: I85d63599c6ab8ed458071cdf9197d85b1f7f150b +Signed-off-by: Greg Hackmann +[astrachan: Added a script to check for incorrectly falling back to the + default when CLANG_TRIPLE is unset] +Bug: 118439987 +Bug: 120440614 +Test: make CLANG_TRIPLE=x86_64-linux-gnu CC=clang +Signed-off-by: Alistair Strachan +--- + Makefile | 6 +++++- + scripts/clang-android.sh | 4 ++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + create mode 100755 scripts/clang-android.sh + +diff --git a/Makefile b/Makefile +index 6886f22902c9c..4f2d1676df567 100644 +--- a/Makefile ++++ b/Makefile +@@ -521,7 +521,11 @@ endif + + ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) + ifneq ($(CROSS_COMPILE),) +-CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) ++CLANG_TRIPLE ?= $(CROSS_COMPILE) ++CLANG_FLAGS += --target=$(notdir $(CLANG_TRIPLE:%-=%)) ++ifeq ($(shell $(srctree)/scripts/clang-android.sh $(CC) $(CLANG_FLAGS)), y) ++$(error "Clang with Android --target detected. Did you specify CLANG_TRIPLE?") ++endif + GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) + CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) + GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) +diff --git a/scripts/clang-android.sh b/scripts/clang-android.sh +new file mode 100755 +index 0000000000000..9186c4f48576e +--- /dev/null ++++ b/scripts/clang-android.sh +@@ -0,0 +1,4 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0 ++ ++$* -dM -E - &1 | grep -q __ANDROID__ && echo "y" +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_su.patch b/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_su.patch new file mode 100644 index 000000000000..3bb55f3fd69b --- /dev/null +++ b/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_su.patch @@ -0,0 +1,73 @@ +From 49c56f99b67531f610b33217b8e3840db1ea57e9 Mon Sep 17 00:00:00 2001 +From: zhuguangqing +Date: Fri, 23 Aug 2019 09:04:06 +0800 +Subject: ANDROID: Log which device failed to suspend in + dpm_suspend_start() + +Problem background: In the process of suspend, maybe some device suspend +callback failed in dpm_suspend_start()/dpm_prepare()/dpm_suspend(). +Because it's after suspend_console(), so printf() is disabled now. +Currently we can see "Some devices failed to suspend, or early wake +event detected" by log_suspend_abort_reason() in bugreport. There are +many devices but we don't know which exactly device failed. So we +want to do a little change to record which device failed. + +Note: I checked upstream LTS kernel, then I found the +patch can not be sent upstream, because it uses function +log_suspend_abort_reason() in wakeup_reason.c, the initial +patch(https://patchwork.kernel.org/patch/3827331/) for adding +/kernel/power/wakeup_reason.c is not accepted by upstream which +was merged in AOSP common kernels. So maybe the patch could +only be sent to AOSP common kernels. + +Test: manual - Use modified version for daily use two days, from +bugreport we can see which device failed. +Bug: 120445600 +Change-Id: I326c87ca1263496db79d08ec615f12fc22452d7a +Signed-off-by: zhuguangqing +--- + drivers/base/power/main.c | 1 + + kernel/power/suspend.c | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c +index 11d2eae19b07b..1f48fd8823197 100644 +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -2007,6 +2007,7 @@ int dpm_prepare(pm_message_t state) + } + pr_info("Device %s not prepared for power transition: code %d\n", + dev_name(dev), error); ++ dpm_save_failed_dev(dev_name(dev)); + put_device(dev); + break; + } +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index 058c2be53d070..c528eb4ed84b8 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -500,7 +500,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) + */ + int suspend_devices_and_enter(suspend_state_t state) + { +- int error; ++ int error, last_dev; + bool wakeup = false; + + if (!sleep_state_supported(state)) +@@ -519,8 +519,11 @@ int suspend_devices_and_enter(suspend_state_t state) + suspend_test_start(); + error = dpm_suspend_start(PMSG_SUSPEND); + if (error) { ++ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; ++ last_dev %= REC_FAILED_NUM; + pr_err("Some devices failed to suspend, or early wake event detected\n"); +- log_suspend_abort_reason("Some devices failed to suspend, or early wake event detected"); ++ log_suspend_abort_reason("%s device failed to suspend, or early wake event detected", ++ suspend_stats.failed_devs[last_dev]); + goto Recover_platform; + } + suspend_test_finish("suspend devices"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Move-from-clang-r328903-to-r346389b.patch b/patches/ANDROID-Move-from-clang-r328903-to-r346389b.patch new file mode 100644 index 000000000000..424d6ef385b4 --- /dev/null +++ b/patches/ANDROID-Move-from-clang-r328903-to-r346389b.patch @@ -0,0 +1,43 @@ +From e73ed590cc04dd0c831b463e5e2b98bf1841dbcd Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 7 Dec 2018 11:34:16 -0800 +Subject: ANDROID: Move from clang r328903 to r346389b. + +Bug: 120439617 +Bug: 120503084 +Change-Id: I21bb183cac03753d1ba719a69305e2199c3f3227 +Signed-off-by: Alistair Strachan +--- + build.config.cuttlefish.aarch64 | 2 +- + build.config.cuttlefish.x86_64 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index bfb1f560b2986..5fb372dce6a22 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -6,7 +6,7 @@ DEFCONFIG=cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index 69813b30c8ea4..a81cb544f51a4 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Move-from-clang-r346389b-to-r349610.patch b/patches/ANDROID-Move-from-clang-r346389b-to-r349610.patch new file mode 100644 index 000000000000..5810bc00df17 --- /dev/null +++ b/patches/ANDROID-Move-from-clang-r346389b-to-r349610.patch @@ -0,0 +1,44 @@ +From 6ed72e9046b89a2821ad76f7250bcbee66316d09 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 12 Feb 2019 13:23:11 -0800 +Subject: ANDROID: Move from clang r346389b to r349610. + +Bug: 123635022 +Test: make ARCH=arm64 cuttlefish_defconfig && make ARCH=arm64 +Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 +Change-Id: Icc02ea92c13435fa5a6ecd33d8878629762fd2f7 +Signed-off-by: Alistair Strachan +--- + build.config.cuttlefish.aarch64 | 2 +- + build.config.cuttlefish.x86_64 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index 5fb372dce6a22..fe921b46a9a8d 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -6,7 +6,7 @@ DEFCONFIG=cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index a81cb544f51a4..31e4057673f41 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch b/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch new file mode 100644 index 000000000000..26baa2a49cf0 --- /dev/null +++ b/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch @@ -0,0 +1,59 @@ +From 04117ea579e13122c3c44954aa2b1233d65efa96 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 14 May 2019 16:07:58 -0700 +Subject: ANDROID: Move from clang r349610 to r353983c. + +Bug: 120439617 +Bug: 132097678 +Test: make ARCH=arm64 cuttlefish_defconfig && make ARCH=arm64 +Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 +Change-Id: If5542a39e36fb4de6dd4b4135a22e188f752dd84 +Signed-off-by: Alistair Strachan +--- + build.config.cuttlefish.aarch64 | 2 +- + build.config.cuttlefish.x86_64 | 2 +- + build.config.gki.aarch64 | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index fe921b46a9a8d..ec53d6eac9ea3 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -6,7 +6,7 @@ DEFCONFIG=cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index 31e4057673f41..b49683d476d62 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 +index dec295284ffa0..ecc2985e92cb5 100644 +--- a/build.config.gki.aarch64 ++++ b/build.config.gki.aarch64 +@@ -7,7 +7,7 @@ DEFCONFIG=gki_defconfig + EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch b/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch new file mode 100644 index 000000000000..2b7ece18107d --- /dev/null +++ b/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch @@ -0,0 +1,25 @@ +From a02c37bcdef853ce26e57f4697159820e655b7dc Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Fri, 20 Sep 2019 15:28:37 -0700 +Subject: ANDROID: Remove CONFIG_USELIB from x86 gki config + +Bug: 138199351 +Change-Id: Ib517ad710337a38602bf7f30ecf616d6d02ca8af +Signed-off-by: Ram Muthiah +--- + arch/x86/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index bcd12981dff4..642729662b04 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -1,4 +1,5 @@ + CONFIG_LOCALVERSION="-mainline" ++# CONFIG_USELIB is not set + CONFIG_AUDIT=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Remove-unused-cuttlefish-build-infra.patch b/patches/ANDROID-Remove-unused-cuttlefish-build-infra.patch new file mode 100644 index 000000000000..ec10d30a988c --- /dev/null +++ b/patches/ANDROID-Remove-unused-cuttlefish-build-infra.patch @@ -0,0 +1,998 @@ +From 431e4d6c828bfe2ae7349f5f0221998a332119d7 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Mon, 12 Aug 2019 12:54:11 -0700 +Subject: ANDROID: Remove unused cuttlefish build infra + +Cuttlefish will use gki_defconfig on this branch. + +Change-Id: I20d37d538ca8f4de80282c4a3a98dbcfb7c33170 +Signed-off-by: Alistair Delva +--- + arch/arm64/configs/cuttlefish_defconfig | 443 ----------------- + arch/x86/configs/x86_64_cuttlefish_defconfig | 472 ------------------- + build.config.cuttlefish.aarch64 | 18 - + build.config.cuttlefish.x86_64 | 18 - + 4 files changed, 951 deletions(-) + delete mode 100644 arch/arm64/configs/cuttlefish_defconfig + delete mode 100644 arch/x86/configs/x86_64_cuttlefish_defconfig + delete mode 100644 build.config.cuttlefish.aarch64 + delete mode 100644 build.config.cuttlefish.x86_64 + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +deleted file mode 100644 +index b84aad53e6d69..0000000000000 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ /dev/null +@@ -1,443 +0,0 @@ +-CONFIG_AUDIT=y +-CONFIG_NO_HZ=y +-CONFIG_HIGH_RES_TIMERS=y +-CONFIG_PREEMPT=y +-CONFIG_TASKSTATS=y +-CONFIG_TASK_DELAY_ACCT=y +-CONFIG_TASK_XACCT=y +-CONFIG_TASK_IO_ACCOUNTING=y +-CONFIG_PSI=y +-CONFIG_IKCONFIG=y +-CONFIG_IKCONFIG_PROC=y +-CONFIG_MEMCG=y +-CONFIG_MEMCG_SWAP=y +-CONFIG_RT_GROUP_SCHED=y +-CONFIG_CGROUP_FREEZER=y +-CONFIG_CPUSETS=y +-CONFIG_CGROUP_CPUACCT=y +-CONFIG_CGROUP_BPF=y +-CONFIG_SCHED_AUTOGROUP=y +-CONFIG_BLK_DEV_INITRD=y +-# CONFIG_RD_BZIP2 is not set +-# CONFIG_RD_LZMA is not set +-# CONFIG_RD_XZ is not set +-# CONFIG_RD_LZO is not set +-# CONFIG_RD_LZ4 is not set +-CONFIG_SGETMASK_SYSCALL=y +-# CONFIG_SYSFS_SYSCALL is not set +-# CONFIG_FHANDLE is not set +-CONFIG_KALLSYMS_ALL=y +-CONFIG_BPF_SYSCALL=y +-# CONFIG_RSEQ is not set +-CONFIG_EMBEDDED=y +-# CONFIG_VM_EVENT_COUNTERS is not set +-# CONFIG_COMPAT_BRK is not set +-# CONFIG_SLAB_MERGE_DEFAULT is not set +-CONFIG_PROFILING=y +-CONFIG_SCHED_MC=y +-CONFIG_HZ_100=y +-CONFIG_SECCOMP=y +-CONFIG_PARAVIRT=y +-CONFIG_ARM64_SW_TTBR0_PAN=y +-CONFIG_COMPAT=y +-CONFIG_ARMV8_DEPRECATED=y +-CONFIG_SWP_EMULATION=y +-CONFIG_CP15_BARRIER_EMULATION=y +-CONFIG_SETEND_EMULATION=y +-CONFIG_RANDOMIZE_BASE=y +-# CONFIG_EFI is not set +-CONFIG_PM_WAKELOCKS=y +-CONFIG_PM_WAKELOCKS_LIMIT=0 +-# CONFIG_PM_WAKELOCKS_GC is not set +-CONFIG_PM_DEBUG=y +-CONFIG_ENERGY_MODEL=y +-CONFIG_CPU_IDLE=y +-CONFIG_ARM_CPUIDLE=y +-CONFIG_CPU_FREQ=y +-CONFIG_CPU_FREQ_TIMES=y +-CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +-CONFIG_CPU_FREQ_GOV_POWERSAVE=y +-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +-CONFIG_CPUFREQ_DT=y +-CONFIG_ARM_SCPI_CPUFREQ=y +-CONFIG_ARM_SCMI_CPUFREQ=y +-CONFIG_ARM_SCMI_PROTOCOL=y +-# CONFIG_ARM_SCMI_POWER_DOMAIN is not set +-CONFIG_ARM_SCPI_PROTOCOL=y +-# CONFIG_ARM_SCPI_POWER_DOMAIN is not set +-CONFIG_KPROBES=y +-CONFIG_MODULES=y +-CONFIG_MODULE_UNLOAD=y +-CONFIG_MODVERSIONS=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_SPARSEMEM_VMEMMAP is not set +-CONFIG_KSM=y +-CONFIG_TRANSPARENT_HUGEPAGE=y +-CONFIG_ZSMALLOC=y +-CONFIG_NET=y +-CONFIG_PACKET=y +-CONFIG_UNIX=y +-CONFIG_XFRM_USER=y +-CONFIG_XFRM_INTERFACE=y +-CONFIG_XFRM_STATISTICS=y +-CONFIG_NET_KEY=y +-CONFIG_INET=y +-CONFIG_IP_MULTICAST=y +-CONFIG_IP_ADVANCED_ROUTER=y +-CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_NET_IPGRE_DEMUX=y +-CONFIG_NET_IPVTI=y +-CONFIG_INET_ESP=y +-CONFIG_INET_UDP_DIAG=y +-CONFIG_INET_DIAG_DESTROY=y +-CONFIG_TCP_CONG_ADVANCED=y +-# CONFIG_TCP_CONG_BIC is not set +-# CONFIG_TCP_CONG_WESTWOOD is not set +-# CONFIG_TCP_CONG_HTCP is not set +-CONFIG_IPV6_ROUTER_PREF=y +-CONFIG_IPV6_ROUTE_INFO=y +-CONFIG_IPV6_OPTIMISTIC_DAD=y +-CONFIG_INET6_ESP=y +-CONFIG_INET6_IPCOMP=y +-CONFIG_IPV6_MIP6=y +-CONFIG_IPV6_VTI=y +-CONFIG_IPV6_MULTIPLE_TABLES=y +-CONFIG_NETFILTER=y +-CONFIG_NF_CONNTRACK=y +-CONFIG_NF_CONNTRACK_SECMARK=y +-CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CONNTRACK_AMANDA=y +-CONFIG_NF_CONNTRACK_FTP=y +-CONFIG_NF_CONNTRACK_H323=y +-CONFIG_NF_CONNTRACK_IRC=y +-CONFIG_NF_CONNTRACK_NETBIOS_NS=y +-CONFIG_NF_CONNTRACK_PPTP=y +-CONFIG_NF_CONNTRACK_SANE=y +-CONFIG_NF_CONNTRACK_TFTP=y +-CONFIG_NF_CT_NETLINK=y +-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +-CONFIG_NETFILTER_XT_TARGET_CT=y +-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +-CONFIG_NETFILTER_XT_TARGET_MARK=y +-CONFIG_NETFILTER_XT_TARGET_NFLOG=y +-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +-CONFIG_NETFILTER_XT_TARGET_TPROXY=y +-CONFIG_NETFILTER_XT_TARGET_TRACE=y +-CONFIG_NETFILTER_XT_TARGET_SECMARK=y +-CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +-CONFIG_NETFILTER_XT_MATCH_BPF=y +-CONFIG_NETFILTER_XT_MATCH_COMMENT=y +-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +-CONFIG_NETFILTER_XT_MATCH_HELPER=y +-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +-CONFIG_NETFILTER_XT_MATCH_LENGTH=y +-CONFIG_NETFILTER_XT_MATCH_LIMIT=y +-CONFIG_NETFILTER_XT_MATCH_MAC=y +-CONFIG_NETFILTER_XT_MATCH_MARK=y +-CONFIG_NETFILTER_XT_MATCH_OWNER=y +-CONFIG_NETFILTER_XT_MATCH_POLICY=y +-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +-CONFIG_NETFILTER_XT_MATCH_QUOTA=y +-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +-CONFIG_NETFILTER_XT_MATCH_SOCKET=y +-CONFIG_NETFILTER_XT_MATCH_STATE=y +-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +-CONFIG_NETFILTER_XT_MATCH_STRING=y +-CONFIG_NETFILTER_XT_MATCH_TIME=y +-CONFIG_NETFILTER_XT_MATCH_U32=y +-CONFIG_IP_NF_IPTABLES=y +-CONFIG_IP_NF_MATCH_ECN=y +-CONFIG_IP_NF_MATCH_TTL=y +-CONFIG_IP_NF_FILTER=y +-CONFIG_IP_NF_TARGET_REJECT=y +-CONFIG_IP_NF_NAT=y +-CONFIG_IP_NF_TARGET_MASQUERADE=y +-CONFIG_IP_NF_TARGET_NETMAP=y +-CONFIG_IP_NF_TARGET_REDIRECT=y +-CONFIG_IP_NF_MANGLE=y +-CONFIG_IP_NF_RAW=y +-CONFIG_IP_NF_SECURITY=y +-CONFIG_IP_NF_ARPTABLES=y +-CONFIG_IP_NF_ARPFILTER=y +-CONFIG_IP_NF_ARP_MANGLE=y +-CONFIG_IP6_NF_IPTABLES=y +-CONFIG_IP6_NF_MATCH_RPFILTER=y +-CONFIG_IP6_NF_FILTER=y +-CONFIG_IP6_NF_TARGET_REJECT=y +-CONFIG_IP6_NF_MANGLE=y +-CONFIG_IP6_NF_RAW=y +-CONFIG_L2TP=y +-CONFIG_NET_SCHED=y +-CONFIG_NET_SCH_HTB=y +-CONFIG_NET_SCH_NETEM=y +-CONFIG_NET_SCH_INGRESS=y +-CONFIG_NET_CLS_U32=y +-CONFIG_NET_CLS_BPF=y +-CONFIG_NET_EMATCH=y +-CONFIG_NET_EMATCH_U32=y +-CONFIG_NET_CLS_ACT=y +-CONFIG_VSOCKETS=y +-CONFIG_VIRTIO_VSOCKETS=y +-CONFIG_CFG80211=y +-# CONFIG_CFG80211_DEFAULT_PS is not set +-# CONFIG_CFG80211_CRDA_SUPPORT is not set +-CONFIG_MAC80211=y +-# CONFIG_MAC80211_RC_MINSTREL is not set +-CONFIG_RFKILL=y +-CONFIG_PCI=y +-CONFIG_PCI_HOST_GENERIC=y +-CONFIG_DEVTMPFS=y +-# CONFIG_ALLOW_DEV_COREDUMP is not set +-CONFIG_DEBUG_DEVRES=y +-CONFIG_OF_UNITTEST=y +-CONFIG_ZRAM=y +-CONFIG_BLK_DEV_LOOP=y +-CONFIG_BLK_DEV_RAM=y +-CONFIG_BLK_DEV_RAM_SIZE=8192 +-CONFIG_VIRTIO_BLK=y +-CONFIG_UID_SYS_STATS=y +-CONFIG_SCSI=y +-# CONFIG_SCSI_PROC_FS is not set +-CONFIG_BLK_DEV_SD=y +-CONFIG_MD=y +-CONFIG_BLK_DEV_DM=y +-CONFIG_DM_CRYPT=y +-CONFIG_DM_UEVENT=y +-CONFIG_DM_VERITY=y +-CONFIG_DM_VERITY_AVB=y +-CONFIG_DM_VERITY_FEC=y +-CONFIG_DM_BOW=y +-CONFIG_NETDEVICES=y +-CONFIG_NETCONSOLE=y +-CONFIG_NETCONSOLE_DYNAMIC=y +-CONFIG_TUN=y +-CONFIG_VIRTIO_NET=y +-# CONFIG_ETHERNET is not set +-CONFIG_PHYLIB=y +-CONFIG_PPP=y +-CONFIG_PPP_BSDCOMP=y +-CONFIG_PPP_DEFLATE=y +-CONFIG_PPP_MPPE=y +-CONFIG_PPTP=y +-CONFIG_PPPOL2TP=y +-CONFIG_USB_RTL8152=y +-CONFIG_USB_USBNET=y +-# CONFIG_USB_NET_AX8817X is not set +-# CONFIG_USB_NET_AX88179_178A is not set +-# CONFIG_USB_NET_CDCETHER is not set +-# CONFIG_USB_NET_CDC_NCM is not set +-# CONFIG_USB_NET_NET1080 is not set +-# CONFIG_USB_NET_CDC_SUBSET is not set +-# CONFIG_USB_NET_ZAURUS is not set +-# CONFIG_WLAN_VENDOR_ADMTEK is not set +-# CONFIG_WLAN_VENDOR_ATH is not set +-# CONFIG_WLAN_VENDOR_ATMEL is not set +-# CONFIG_WLAN_VENDOR_BROADCOM is not set +-# CONFIG_WLAN_VENDOR_CISCO is not set +-# CONFIG_WLAN_VENDOR_INTEL is not set +-# CONFIG_WLAN_VENDOR_INTERSIL is not set +-# CONFIG_WLAN_VENDOR_MARVELL is not set +-# CONFIG_WLAN_VENDOR_MEDIATEK is not set +-# CONFIG_WLAN_VENDOR_RALINK is not set +-# CONFIG_WLAN_VENDOR_REALTEK is not set +-# CONFIG_WLAN_VENDOR_RSI is not set +-# CONFIG_WLAN_VENDOR_ST is not set +-# CONFIG_WLAN_VENDOR_TI is not set +-# CONFIG_WLAN_VENDOR_ZYDAS is not set +-# CONFIG_WLAN_VENDOR_QUANTENNA is not set +-CONFIG_VIRT_WIFI=y +-CONFIG_INPUT_EVDEV=y +-# CONFIG_INPUT_KEYBOARD is not set +-# CONFIG_INPUT_MOUSE is not set +-CONFIG_INPUT_JOYSTICK=y +-CONFIG_JOYSTICK_XPAD=y +-CONFIG_JOYSTICK_XPAD_FF=y +-CONFIG_JOYSTICK_XPAD_LEDS=y +-CONFIG_INPUT_TABLET=y +-CONFIG_TABLET_USB_ACECAD=y +-CONFIG_TABLET_USB_AIPTEK=y +-CONFIG_TABLET_USB_GTCO=y +-CONFIG_TABLET_USB_HANWANG=y +-CONFIG_TABLET_USB_KBTAB=y +-CONFIG_INPUT_MISC=y +-CONFIG_INPUT_UINPUT=y +-# CONFIG_VT is not set +-# CONFIG_LEGACY_PTYS is not set +-# CONFIG_DEVMEM is not set +-CONFIG_SERIAL_8250=y +-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +-CONFIG_SERIAL_8250_CONSOLE=y +-# CONFIG_SERIAL_8250_EXAR is not set +-CONFIG_SERIAL_8250_NR_UARTS=48 +-CONFIG_SERIAL_8250_EXTENDED=y +-CONFIG_SERIAL_8250_MANY_PORTS=y +-CONFIG_SERIAL_8250_SHARE_IRQ=y +-CONFIG_SERIAL_OF_PLATFORM=y +-CONFIG_SERIAL_AMBA_PL011=y +-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +-CONFIG_VIRTIO_CONSOLE=y +-CONFIG_HW_RANDOM=y +-CONFIG_HW_RANDOM_VIRTIO=y +-# CONFIG_HW_RANDOM_CAVIUM is not set +-# CONFIG_DEVPORT is not set +-# CONFIG_I2C_COMPAT is not set +-# CONFIG_I2C_HELPER_AUTO is not set +-# CONFIG_HWMON is not set +-CONFIG_THERMAL=y +-CONFIG_CPU_THERMAL=y +-CONFIG_MEDIA_SUPPORT=y +-# CONFIG_VGA_ARB is not set +-CONFIG_DRM=y +-# CONFIG_DRM_FBDEV_EMULATION is not set +-CONFIG_DRM_VIRTIO_GPU=y +-CONFIG_SOUND=y +-CONFIG_SND=y +-CONFIG_SND_HRTIMER=y +-# CONFIG_SND_SUPPORT_OLD_API is not set +-# CONFIG_SND_VERBOSE_PROCFS is not set +-# CONFIG_SND_DRIVERS is not set +-CONFIG_SND_INTEL8X0=y +-# CONFIG_SND_USB is not set +-CONFIG_HIDRAW=y +-CONFIG_UHID=y +-CONFIG_HID_A4TECH=y +-CONFIG_HID_ACRUX=y +-CONFIG_HID_ACRUX_FF=y +-CONFIG_HID_APPLE=y +-CONFIG_HID_BELKIN=y +-CONFIG_HID_CHERRY=y +-CONFIG_HID_CHICONY=y +-CONFIG_HID_PRODIKEYS=y +-CONFIG_HID_CYPRESS=y +-CONFIG_HID_DRAGONRISE=y +-CONFIG_DRAGONRISE_FF=y +-CONFIG_HID_EMS_FF=y +-CONFIG_HID_ELECOM=y +-CONFIG_HID_EZKEY=y +-CONFIG_HID_HOLTEK=y +-CONFIG_HID_KEYTOUCH=y +-CONFIG_HID_KYE=y +-CONFIG_HID_UCLOGIC=y +-CONFIG_HID_WALTOP=y +-CONFIG_HID_GYRATION=y +-CONFIG_HID_TWINHAN=y +-CONFIG_HID_KENSINGTON=y +-CONFIG_HID_LCPOWER=y +-CONFIG_HID_LOGITECH=y +-CONFIG_HID_LOGITECH_DJ=y +-CONFIG_LOGITECH_FF=y +-CONFIG_LOGIRUMBLEPAD2_FF=y +-CONFIG_LOGIG940_FF=y +-CONFIG_HID_MAGICMOUSE=y +-CONFIG_HID_MICROSOFT=y +-CONFIG_HID_MONTEREY=y +-CONFIG_HID_MULTITOUCH=y +-CONFIG_HID_NTRIG=y +-CONFIG_HID_ORTEK=y +-CONFIG_HID_PANTHERLORD=y +-CONFIG_PANTHERLORD_FF=y +-CONFIG_HID_PETALYNX=y +-CONFIG_HID_PICOLCD=y +-CONFIG_HID_PRIMAX=y +-CONFIG_HID_ROCCAT=y +-CONFIG_HID_SAITEK=y +-CONFIG_HID_SAMSUNG=y +-CONFIG_HID_SONY=y +-CONFIG_HID_SPEEDLINK=y +-CONFIG_HID_SUNPLUS=y +-CONFIG_HID_GREENASIA=y +-CONFIG_GREENASIA_FF=y +-CONFIG_HID_SMARTJOYPLUS=y +-CONFIG_SMARTJOYPLUS_FF=y +-CONFIG_HID_TIVO=y +-CONFIG_HID_TOPSEED=y +-CONFIG_HID_THRUSTMASTER=y +-CONFIG_HID_WACOM=y +-CONFIG_HID_WIIMOTE=y +-CONFIG_HID_ZEROPLUS=y +-CONFIG_HID_ZYDACRON=y +-CONFIG_USB_HIDDEV=y +-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +-CONFIG_USB_EHCI_HCD=y +-CONFIG_USB_GADGET=y +-CONFIG_USB_CONFIGFS=y +-CONFIG_USB_CONFIGFS_UEVENT=y +-CONFIG_USB_CONFIGFS_F_FS=y +-CONFIG_USB_CONFIGFS_F_ACC=y +-CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y +-CONFIG_USB_CONFIGFS_F_MIDI=y +-CONFIG_MMC=y +-# CONFIG_PWRSEQ_EMMC is not set +-# CONFIG_PWRSEQ_SIMPLE is not set +-# CONFIG_MMC_BLOCK is not set +-CONFIG_RTC_CLASS=y +-# CONFIG_RTC_SYSTOHC is not set +-CONFIG_RTC_DRV_PL030=y +-CONFIG_RTC_DRV_PL031=y +-CONFIG_VIRTIO_PCI=y +-# CONFIG_VIRTIO_PCI_LEGACY is not set +-CONFIG_VIRTIO_INPUT=y +-CONFIG_VIRTIO_MMIO=y +-CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +-CONFIG_STAGING=y +-CONFIG_ASHMEM=y +-CONFIG_ANDROID_VSOC=y +-CONFIG_ION=y +-CONFIG_ION_SYSTEM_HEAP=y +-CONFIG_COMMON_CLK_SCPI=y +-# CONFIG_COMMON_CLK_XGENE is not set +-CONFIG_MAILBOX=y +-# CONFIG_IOMMU_SUPPORT is not set +-CONFIG_ANDROID=y +-CONFIG_ANDROID_BINDER_IPC=y +-CONFIG_EXT4_FS=y +-CONFIG_EXT4_FS_SECURITY=y +-CONFIG_F2FS_FS=y +-CONFIG_F2FS_FS_SECURITY=y +-CONFIG_FS_ENCRYPTION=y +-# CONFIG_DNOTIFY is not set +-CONFIG_QUOTA=y +-CONFIG_QFMT_V2=y +-CONFIG_FUSE_FS=y +-CONFIG_OVERLAY_FS=y +-CONFIG_MSDOS_FS=y +-CONFIG_VFAT_FS=y +-CONFIG_TMPFS=y +-CONFIG_TMPFS_POSIX_ACL=y +-CONFIG_SDCARD_FS=y +-CONFIG_PSTORE=y +-CONFIG_PSTORE_CONSOLE=y +-CONFIG_PSTORE_RAM=y +-CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +-CONFIG_SECURITY=y +-CONFIG_SECURITY_NETWORK=y +-CONFIG_LSM_MMAP_MIN_ADDR=65536 +-CONFIG_HARDENED_USERCOPY=y +-CONFIG_SECURITY_SELINUX=y +-CONFIG_CRYPTO_ADIANTUM=y +-CONFIG_CRYPTO_SHA512=y +-CONFIG_CRYPTO_LZ4=y +-CONFIG_CRYPTO_ZSTD=y +-CONFIG_CRYPTO_ANSI_CPRNG=y +-CONFIG_CRYPTO_DEV_VIRTIO=y +-CONFIG_XZ_DEC=y +-CONFIG_PRINTK_TIME=y +-CONFIG_DEBUG_INFO=y +-# CONFIG_ENABLE_MUST_CHECK is not set +-CONFIG_FRAME_WARN=1024 +-# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +-CONFIG_MAGIC_SYSRQ=y +-CONFIG_DEBUG_STACK_USAGE=y +-CONFIG_DEBUG_MEMORY_INIT=y +-CONFIG_SOFTLOCKUP_DETECTOR=y +-# CONFIG_DETECT_HUNG_TASK is not set +-CONFIG_PANIC_TIMEOUT=5 +-CONFIG_SCHEDSTATS=y +-CONFIG_RCU_CPU_STALL_TIMEOUT=60 +-CONFIG_ENABLE_DEFAULT_TRACERS=y +-# CONFIG_RUNTIME_TESTING_MENU is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +deleted file mode 100644 +index cad481541d690..0000000000000 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ /dev/null +@@ -1,472 +0,0 @@ +-CONFIG_POSIX_MQUEUE=y +-# CONFIG_USELIB is not set +-CONFIG_AUDIT=y +-CONFIG_NO_HZ=y +-CONFIG_HIGH_RES_TIMERS=y +-CONFIG_PREEMPT=y +-CONFIG_BSD_PROCESS_ACCT=y +-CONFIG_TASKSTATS=y +-CONFIG_TASK_DELAY_ACCT=y +-CONFIG_TASK_XACCT=y +-CONFIG_TASK_IO_ACCOUNTING=y +-CONFIG_PSI=y +-CONFIG_IKCONFIG=y +-CONFIG_IKCONFIG_PROC=y +-CONFIG_CGROUPS=y +-CONFIG_MEMCG=y +-CONFIG_MEMCG_SWAP=y +-CONFIG_CGROUP_SCHED=y +-CONFIG_RT_GROUP_SCHED=y +-CONFIG_CGROUP_FREEZER=y +-CONFIG_CPUSETS=y +-# CONFIG_PROC_PID_CPUSET is not set +-CONFIG_CGROUP_CPUACCT=y +-CONFIG_CGROUP_BPF=y +-CONFIG_NAMESPACES=y +-CONFIG_BLK_DEV_INITRD=y +-# CONFIG_RD_LZ4 is not set +-# CONFIG_FHANDLE is not set +-# CONFIG_PCSPKR_PLATFORM is not set +-CONFIG_KALLSYMS_ALL=y +-CONFIG_BPF_SYSCALL=y +-CONFIG_EMBEDDED=y +-# CONFIG_COMPAT_BRK is not set +-CONFIG_PROFILING=y +-CONFIG_SMP=y +-CONFIG_HYPERVISOR_GUEST=y +-CONFIG_PARAVIRT=y +-CONFIG_PARAVIRT_SPINLOCKS=y +-CONFIG_MCORE2=y +-CONFIG_PROCESSOR_SELECT=y +-# CONFIG_CPU_SUP_CENTAUR is not set +-CONFIG_NR_CPUS=8 +-# CONFIG_MICROCODE is not set +-CONFIG_X86_MSR=y +-CONFIG_X86_CPUID=y +-# CONFIG_MTRR is not set +-CONFIG_HZ_100=y +-CONFIG_KEXEC=y +-CONFIG_CRASH_DUMP=y +-CONFIG_PHYSICAL_START=0x200000 +-CONFIG_PHYSICAL_ALIGN=0x1000000 +-CONFIG_CMDLINE_BOOL=y +-CONFIG_CMDLINE="console=ttyS0 reboot=p" +-CONFIG_PM_WAKELOCKS=y +-CONFIG_PM_WAKELOCKS_LIMIT=0 +-# CONFIG_PM_WAKELOCKS_GC is not set +-CONFIG_PM_DEBUG=y +-CONFIG_ACPI_PROCFS_POWER=y +-# CONFIG_ACPI_FAN is not set +-# CONFIG_ACPI_THERMAL is not set +-# CONFIG_X86_PM_TIMER is not set +-CONFIG_CPU_FREQ_TIMES=y +-CONFIG_CPU_FREQ_GOV_ONDEMAND=y +-CONFIG_X86_ACPI_CPUFREQ=y +-CONFIG_PCI_MSI=y +-CONFIG_IA32_EMULATION=y +-# CONFIG_FIRMWARE_MEMMAP is not set +-CONFIG_OPROFILE=y +-CONFIG_KPROBES=y +-CONFIG_REFCOUNT_FULL=y +-CONFIG_MODULES=y +-CONFIG_MODULE_UNLOAD=y +-CONFIG_MODVERSIONS=y +-CONFIG_PARTITION_ADVANCED=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-CONFIG_BINFMT_MISC=y +-CONFIG_KSM=y +-CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +-CONFIG_TRANSPARENT_HUGEPAGE=y +-CONFIG_ZSMALLOC=y +-CONFIG_NET=y +-CONFIG_PACKET=y +-CONFIG_UNIX=y +-CONFIG_XFRM_USER=y +-CONFIG_NET_KEY=y +-CONFIG_INET=y +-CONFIG_IP_MULTICAST=y +-CONFIG_IP_ADVANCED_ROUTER=y +-CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IP_ROUTE_MULTIPATH=y +-CONFIG_IP_ROUTE_VERBOSE=y +-CONFIG_IP_MROUTE=y +-CONFIG_IP_PIMSM_V1=y +-CONFIG_IP_PIMSM_V2=y +-CONFIG_SYN_COOKIES=y +-CONFIG_NET_IPVTI=y +-CONFIG_INET_ESP=y +-CONFIG_INET_UDP_DIAG=y +-CONFIG_INET_DIAG_DESTROY=y +-CONFIG_TCP_CONG_ADVANCED=y +-# CONFIG_TCP_CONG_BIC is not set +-# CONFIG_TCP_CONG_WESTWOOD is not set +-# CONFIG_TCP_CONG_HTCP is not set +-CONFIG_TCP_MD5SIG=y +-CONFIG_IPV6_ROUTER_PREF=y +-CONFIG_IPV6_ROUTE_INFO=y +-CONFIG_IPV6_OPTIMISTIC_DAD=y +-CONFIG_INET6_AH=y +-CONFIG_INET6_ESP=y +-CONFIG_INET6_IPCOMP=y +-CONFIG_IPV6_MIP6=y +-CONFIG_IPV6_VTI=y +-CONFIG_IPV6_MULTIPLE_TABLES=y +-CONFIG_NETLABEL=y +-CONFIG_NETFILTER=y +-CONFIG_NF_CONNTRACK=y +-CONFIG_NF_CONNTRACK_SECMARK=y +-CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CONNTRACK_AMANDA=y +-CONFIG_NF_CONNTRACK_FTP=y +-CONFIG_NF_CONNTRACK_H323=y +-CONFIG_NF_CONNTRACK_IRC=y +-CONFIG_NF_CONNTRACK_NETBIOS_NS=y +-CONFIG_NF_CONNTRACK_PPTP=y +-CONFIG_NF_CONNTRACK_SANE=y +-CONFIG_NF_CONNTRACK_TFTP=y +-CONFIG_NF_CT_NETLINK=y +-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +-CONFIG_NETFILTER_XT_TARGET_CT=y +-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +-CONFIG_NETFILTER_XT_TARGET_MARK=y +-CONFIG_NETFILTER_XT_TARGET_NFLOG=y +-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +-CONFIG_NETFILTER_XT_TARGET_TPROXY=y +-CONFIG_NETFILTER_XT_TARGET_TRACE=y +-CONFIG_NETFILTER_XT_TARGET_SECMARK=y +-CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +-CONFIG_NETFILTER_XT_MATCH_BPF=y +-CONFIG_NETFILTER_XT_MATCH_COMMENT=y +-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +-CONFIG_NETFILTER_XT_MATCH_HELPER=y +-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +-CONFIG_NETFILTER_XT_MATCH_LENGTH=y +-CONFIG_NETFILTER_XT_MATCH_LIMIT=y +-CONFIG_NETFILTER_XT_MATCH_MAC=y +-CONFIG_NETFILTER_XT_MATCH_MARK=y +-CONFIG_NETFILTER_XT_MATCH_OWNER=y +-CONFIG_NETFILTER_XT_MATCH_POLICY=y +-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +-CONFIG_NETFILTER_XT_MATCH_QUOTA=y +-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +-CONFIG_NETFILTER_XT_MATCH_SOCKET=y +-CONFIG_NETFILTER_XT_MATCH_STATE=y +-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +-CONFIG_NETFILTER_XT_MATCH_STRING=y +-CONFIG_NETFILTER_XT_MATCH_TIME=y +-CONFIG_NETFILTER_XT_MATCH_U32=y +-CONFIG_IP_NF_IPTABLES=y +-CONFIG_IP_NF_MATCH_AH=y +-CONFIG_IP_NF_MATCH_ECN=y +-CONFIG_IP_NF_MATCH_TTL=y +-CONFIG_IP_NF_FILTER=y +-CONFIG_IP_NF_TARGET_REJECT=y +-CONFIG_IP_NF_NAT=y +-CONFIG_IP_NF_TARGET_MASQUERADE=y +-CONFIG_IP_NF_TARGET_NETMAP=y +-CONFIG_IP_NF_TARGET_REDIRECT=y +-CONFIG_IP_NF_MANGLE=y +-CONFIG_IP_NF_RAW=y +-CONFIG_IP_NF_SECURITY=y +-CONFIG_IP_NF_ARPTABLES=y +-CONFIG_IP_NF_ARPFILTER=y +-CONFIG_IP_NF_ARP_MANGLE=y +-CONFIG_IP6_NF_IPTABLES=y +-CONFIG_IP6_NF_MATCH_IPV6HEADER=y +-CONFIG_IP6_NF_MATCH_RPFILTER=y +-CONFIG_IP6_NF_FILTER=y +-CONFIG_IP6_NF_TARGET_REJECT=y +-CONFIG_IP6_NF_MANGLE=y +-CONFIG_IP6_NF_RAW=y +-CONFIG_NET_SCHED=y +-CONFIG_NET_SCH_HTB=y +-CONFIG_NET_SCH_NETEM=y +-CONFIG_NET_SCH_INGRESS=y +-CONFIG_NET_CLS_U32=y +-CONFIG_NET_CLS_BPF=y +-CONFIG_NET_EMATCH=y +-CONFIG_NET_EMATCH_U32=y +-CONFIG_NET_CLS_ACT=y +-CONFIG_VSOCKETS=y +-CONFIG_VIRTIO_VSOCKETS=y +-CONFIG_CFG80211=y +-CONFIG_MAC80211=y +-CONFIG_RFKILL=y +-CONFIG_PCI=y +-CONFIG_PCI_MSI=y +-CONFIG_DEVTMPFS=y +-CONFIG_DEBUG_DEVRES=y +-CONFIG_OF=y +-CONFIG_OF_UNITTEST=y +-# CONFIG_PNP_DEBUG_MESSAGES is not set +-CONFIG_ZRAM=y +-CONFIG_BLK_DEV_LOOP=y +-CONFIG_BLK_DEV_RAM=y +-CONFIG_BLK_DEV_RAM_SIZE=8192 +-CONFIG_VIRTIO_BLK=y +-CONFIG_UID_SYS_STATS=y +-CONFIG_SCSI=y +-CONFIG_BLK_DEV_SD=y +-CONFIG_BLK_DEV_SR=y +-CONFIG_BLK_DEV_SR_VENDOR=y +-CONFIG_CHR_DEV_SG=y +-CONFIG_SCSI_CONSTANTS=y +-CONFIG_SCSI_SPI_ATTRS=y +-CONFIG_MD=y +-CONFIG_BLK_DEV_DM=y +-CONFIG_DM_CRYPT=y +-CONFIG_DM_MIRROR=y +-CONFIG_DM_ZERO=y +-CONFIG_DM_UEVENT=y +-CONFIG_DM_VERITY=y +-CONFIG_DM_VERITY_AVB=y +-CONFIG_DM_VERITY_FEC=y +-CONFIG_DM_BOW=y +-CONFIG_NETDEVICES=y +-CONFIG_NETCONSOLE=y +-CONFIG_NETCONSOLE_DYNAMIC=y +-CONFIG_TUN=y +-CONFIG_VIRTIO_NET=y +-# CONFIG_ETHERNET is not set +-CONFIG_PPP=y +-CONFIG_PPP_BSDCOMP=y +-CONFIG_PPP_DEFLATE=y +-CONFIG_PPP_MPPE=y +-CONFIG_USB_RTL8152=y +-CONFIG_USB_USBNET=y +-# CONFIG_USB_NET_AX8817X is not set +-# CONFIG_USB_NET_AX88179_178A is not set +-# CONFIG_USB_NET_CDCETHER is not set +-# CONFIG_USB_NET_CDC_NCM is not set +-# CONFIG_USB_NET_NET1080 is not set +-# CONFIG_USB_NET_CDC_SUBSET is not set +-# CONFIG_USB_NET_ZAURUS is not set +-# CONFIG_WLAN_VENDOR_ADMTEK is not set +-# CONFIG_WLAN_VENDOR_ATH is not set +-# CONFIG_WLAN_VENDOR_ATMEL is not set +-# CONFIG_WLAN_VENDOR_BROADCOM is not set +-# CONFIG_WLAN_VENDOR_CISCO is not set +-# CONFIG_WLAN_VENDOR_INTEL is not set +-# CONFIG_WLAN_VENDOR_INTERSIL is not set +-# CONFIG_WLAN_VENDOR_MARVELL is not set +-# CONFIG_WLAN_VENDOR_MEDIATEK is not set +-# CONFIG_WLAN_VENDOR_RALINK is not set +-# CONFIG_WLAN_VENDOR_REALTEK is not set +-# CONFIG_WLAN_VENDOR_RSI is not set +-# CONFIG_WLAN_VENDOR_ST is not set +-# CONFIG_WLAN_VENDOR_TI is not set +-# CONFIG_WLAN_VENDOR_ZYDAS is not set +-# CONFIG_WLAN_VENDOR_QUANTENNA is not set +-CONFIG_MAC80211_HWSIM=y +-CONFIG_VIRT_WIFI=y +-CONFIG_INPUT_MOUSEDEV=y +-CONFIG_INPUT_EVDEV=y +-# CONFIG_INPUT_KEYBOARD is not set +-# CONFIG_INPUT_MOUSE is not set +-CONFIG_INPUT_JOYSTICK=y +-CONFIG_JOYSTICK_XPAD=y +-CONFIG_JOYSTICK_XPAD_FF=y +-CONFIG_JOYSTICK_XPAD_LEDS=y +-CONFIG_INPUT_TABLET=y +-CONFIG_TABLET_USB_ACECAD=y +-CONFIG_TABLET_USB_AIPTEK=y +-CONFIG_TABLET_USB_GTCO=y +-CONFIG_TABLET_USB_HANWANG=y +-CONFIG_TABLET_USB_KBTAB=y +-CONFIG_INPUT_MISC=y +-CONFIG_INPUT_UINPUT=y +-# CONFIG_SERIO_I8042 is not set +-# CONFIG_VT is not set +-# CONFIG_LEGACY_PTYS is not set +-# CONFIG_DEVMEM is not set +-CONFIG_SERIAL_8250=y +-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +-CONFIG_SERIAL_8250_CONSOLE=y +-# CONFIG_SERIAL_8250_EXAR is not set +-CONFIG_SERIAL_8250_NR_UARTS=48 +-CONFIG_SERIAL_8250_EXTENDED=y +-CONFIG_SERIAL_8250_MANY_PORTS=y +-CONFIG_SERIAL_8250_SHARE_IRQ=y +-CONFIG_VIRTIO_CONSOLE=y +-CONFIG_HW_RANDOM=y +-# CONFIG_HW_RANDOM_INTEL is not set +-# CONFIG_HW_RANDOM_AMD is not set +-# CONFIG_HW_RANDOM_VIA is not set +-CONFIG_HW_RANDOM_VIRTIO=y +-CONFIG_HPET=y +-# CONFIG_HPET_MMAP_DEFAULT is not set +-# CONFIG_DEVPORT is not set +-# CONFIG_ACPI_I2C_OPREGION is not set +-# CONFIG_I2C_COMPAT is not set +-# CONFIG_I2C_HELPER_AUTO is not set +-CONFIG_PTP_1588_CLOCK=y +-# CONFIG_HWMON is not set +-# CONFIG_X86_PKG_TEMP_THERMAL is not set +-CONFIG_WATCHDOG=y +-CONFIG_SOFT_WATCHDOG=y +-CONFIG_MEDIA_SUPPORT=y +-# CONFIG_VGA_ARB is not set +-CONFIG_DRM=y +-# CONFIG_DRM_FBDEV_EMULATION is not set +-CONFIG_DRM_VIRTIO_GPU=y +-CONFIG_SOUND=y +-CONFIG_SND=y +-CONFIG_SND_HRTIMER=y +-# CONFIG_SND_SUPPORT_OLD_API is not set +-# CONFIG_SND_VERBOSE_PROCFS is not set +-# CONFIG_SND_DRIVERS is not set +-CONFIG_SND_INTEL8X0=y +-# CONFIG_SND_USB is not set +-CONFIG_HIDRAW=y +-CONFIG_UHID=y +-CONFIG_HID_A4TECH=y +-CONFIG_HID_ACRUX=y +-CONFIG_HID_ACRUX_FF=y +-CONFIG_HID_APPLE=y +-CONFIG_HID_BELKIN=y +-CONFIG_HID_CHERRY=y +-CONFIG_HID_CHICONY=y +-CONFIG_HID_PRODIKEYS=y +-CONFIG_HID_CYPRESS=y +-CONFIG_HID_DRAGONRISE=y +-CONFIG_DRAGONRISE_FF=y +-CONFIG_HID_EMS_FF=y +-CONFIG_HID_ELECOM=y +-CONFIG_HID_EZKEY=y +-CONFIG_HID_HOLTEK=y +-CONFIG_HID_KEYTOUCH=y +-CONFIG_HID_KYE=y +-CONFIG_HID_UCLOGIC=y +-CONFIG_HID_WALTOP=y +-CONFIG_HID_GYRATION=y +-CONFIG_HID_TWINHAN=y +-CONFIG_HID_KENSINGTON=y +-CONFIG_HID_LCPOWER=y +-CONFIG_HID_LOGITECH=y +-CONFIG_HID_LOGITECH_DJ=y +-CONFIG_LOGITECH_FF=y +-CONFIG_LOGIRUMBLEPAD2_FF=y +-CONFIG_LOGIG940_FF=y +-CONFIG_HID_MAGICMOUSE=y +-CONFIG_HID_MICROSOFT=y +-CONFIG_HID_MONTEREY=y +-CONFIG_HID_MULTITOUCH=y +-CONFIG_HID_NTRIG=y +-CONFIG_HID_ORTEK=y +-CONFIG_HID_PANTHERLORD=y +-CONFIG_PANTHERLORD_FF=y +-CONFIG_HID_PETALYNX=y +-CONFIG_HID_PICOLCD=y +-CONFIG_HID_PRIMAX=y +-CONFIG_HID_ROCCAT=y +-CONFIG_HID_SAITEK=y +-CONFIG_HID_SAMSUNG=y +-CONFIG_HID_SONY=y +-CONFIG_HID_SPEEDLINK=y +-CONFIG_HID_SUNPLUS=y +-CONFIG_HID_GREENASIA=y +-CONFIG_GREENASIA_FF=y +-CONFIG_HID_SMARTJOYPLUS=y +-CONFIG_SMARTJOYPLUS_FF=y +-CONFIG_HID_TIVO=y +-CONFIG_HID_TOPSEED=y +-CONFIG_HID_THRUSTMASTER=y +-CONFIG_HID_WACOM=y +-CONFIG_HID_WIIMOTE=y +-CONFIG_HID_ZEROPLUS=y +-CONFIG_HID_ZYDACRON=y +-CONFIG_USB_HIDDEV=y +-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +-CONFIG_USB_EHCI_HCD=y +-CONFIG_USB_GADGET=y +-CONFIG_USB_DUMMY_HCD=y +-CONFIG_USB_CONFIGFS=y +-CONFIG_USB_CONFIGFS_UEVENT=y +-CONFIG_USB_CONFIGFS_F_FS=y +-CONFIG_USB_CONFIGFS_F_ACC=y +-CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y +-CONFIG_USB_CONFIGFS_F_MIDI=y +-CONFIG_MMC=y +-# CONFIG_PWRSEQ_EMMC is not set +-# CONFIG_PWRSEQ_SIMPLE is not set +-# CONFIG_MMC_BLOCK is not set +-CONFIG_RTC_CLASS=y +-CONFIG_SW_SYNC=y +-CONFIG_VIRTIO_PCI=y +-CONFIG_VIRTIO_INPUT=y +-CONFIG_VIRTIO_MMIO=y +-CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +-CONFIG_STAGING=y +-CONFIG_ASHMEM=y +-CONFIG_ANDROID_VSOC=y +-CONFIG_ION=y +-CONFIG_ION_SYSTEM_HEAP=y +-# CONFIG_X86_PLATFORM_DEVICES is not set +-# CONFIG_IOMMU_SUPPORT is not set +-CONFIG_ANDROID=y +-CONFIG_ANDROID_BINDER_IPC=y +-CONFIG_EXT4_FS=y +-CONFIG_EXT4_FS_POSIX_ACL=y +-CONFIG_EXT4_FS_SECURITY=y +-CONFIG_EXT4_ENCRYPTION=y +-CONFIG_F2FS_FS=y +-CONFIG_F2FS_FS_SECURITY=y +-CONFIG_F2FS_FS_ENCRYPTION=y +-CONFIG_QUOTA=y +-CONFIG_QUOTA_NETLINK_INTERFACE=y +-# CONFIG_PRINT_QUOTA_WARNING is not set +-CONFIG_QFMT_V2=y +-CONFIG_AUTOFS4_FS=y +-CONFIG_FUSE_FS=y +-CONFIG_OVERLAY_FS=y +-CONFIG_MSDOS_FS=y +-CONFIG_VFAT_FS=y +-CONFIG_PROC_KCORE=y +-CONFIG_TMPFS=y +-CONFIG_TMPFS_POSIX_ACL=y +-CONFIG_HUGETLBFS=y +-CONFIG_SDCARD_FS=y +-CONFIG_PSTORE=y +-CONFIG_PSTORE_CONSOLE=y +-CONFIG_PSTORE_RAM=y +-CONFIG_NLS_DEFAULT="utf8" +-CONFIG_NLS_CODEPAGE_437=y +-CONFIG_NLS_ASCII=y +-CONFIG_NLS_ISO8859_1=y +-CONFIG_NLS_UTF8=y +-CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +-CONFIG_SECURITY=y +-CONFIG_SECURITY_NETWORK=y +-CONFIG_SECURITY_PATH=y +-CONFIG_HARDENED_USERCOPY=y +-CONFIG_SECURITY_SELINUX=y +-CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +-# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +-CONFIG_CRYPTO_ADIANTUM=y +-CONFIG_CRYPTO_SHA512=y +-CONFIG_CRYPTO_AES_NI_INTEL=y +-CONFIG_CRYPTO_LZ4=y +-CONFIG_CRYPTO_ZSTD=y +-CONFIG_CRYPTO_DEV_VIRTIO=y +-CONFIG_PRINTK_TIME=y +-CONFIG_DEBUG_INFO=y +-# CONFIG_ENABLE_MUST_CHECK is not set +-CONFIG_FRAME_WARN=1024 +-# CONFIG_UNUSED_SYMBOLS is not set +-CONFIG_OPTIMIZE_INLINING=y +-CONFIG_MAGIC_SYSRQ=y +-CONFIG_DEBUG_STACK_USAGE=y +-CONFIG_DEBUG_MEMORY_INIT=y +-CONFIG_HARDLOCKUP_DETECTOR=y +-CONFIG_PANIC_TIMEOUT=5 +-CONFIG_SCHEDSTATS=y +-CONFIG_RCU_CPU_STALL_TIMEOUT=60 +-CONFIG_ENABLE_DEFAULT_TRACERS=y +-CONFIG_IO_DELAY_NONE=y +-CONFIG_DEBUG_BOOT_PARAMS=y +-CONFIG_UNWINDER_FRAME_POINTER=y +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +deleted file mode 100644 +index b9115335e3fc1..0000000000000 +--- a/build.config.cuttlefish.aarch64 ++++ /dev/null +@@ -1,18 +0,0 @@ +-ARCH=arm64 +-BRANCH=android-mainline +-CLANG_TRIPLE=aarch64-linux-gnu- +-CROSS_COMPILE=aarch64-linux-androidkernel- +-CC=clang +-DEFCONFIG=cuttlefish_defconfig +-EXTRA_CMDS='' +-KERNEL_DIR=common +-POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 +-LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin +-FILES=" +-arch/arm64/boot/Image.gz +-vmlinux +-System.map +-" +-STOP_SHIP_TRACEPRINTK=1 +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +deleted file mode 100644 +index bdcbecea3ce11..0000000000000 +--- a/build.config.cuttlefish.x86_64 ++++ /dev/null +@@ -1,18 +0,0 @@ +-ARCH=x86_64 +-BRANCH=android-mainline +-CLANG_TRIPLE=x86_64-linux-gnu- +-CROSS_COMPILE=x86_64-linux-androidkernel- +-CC=clang +-DEFCONFIG=x86_64_cuttlefish_defconfig +-EXTRA_CMDS='' +-KERNEL_DIR=common +-POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 +-LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin +-FILES=" +-arch/x86/boot/bzImage +-vmlinux +-System.map +-" +-STOP_SHIP_TRACEPRINTK=1 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Removed-check-for-asm-goto.patch b/patches/ANDROID-Removed-check-for-asm-goto.patch new file mode 100644 index 000000000000..0d7c11f8a5e3 --- /dev/null +++ b/patches/ANDROID-Removed-check-for-asm-goto.patch @@ -0,0 +1,44 @@ +From 28dd583e21a3d424a245e5927c5d79eb6f6aa3ac Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Wed, 24 Oct 2018 13:58:11 -0700 +Subject: ANDROID: Removed check for asm-goto + +Cherry pick was manually applied due to conflicts with +upstream commits: e9666d10a56 and 829fe4aa9ac +-------- +Revert "x86: Force asm-goto" + +This reverts commit e501ce957a786ecd076ea0cfb10b114e6e4d0f40. + +This change broke building the x86_64 kernel with clang. The kernel +still builds and works fine without asm-goto support. Revert this +change to unblock testing clang kernels on cuttlefish. + +Bug: 118142806 +Bug: 120440614 +Bug: 132629930 +Change-Id: Ib32498acc0596264f8cd15de0b603579dd643dd7 +Signed-off-by: Alistair Strachan +Signed-off-by: Ram Muthiah +--- + arch/x86/Makefile | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/x86/Makefile b/arch/x86/Makefile +index 94df0868804bc..408bb5532d1ba 100644 +--- a/arch/x86/Makefile ++++ b/arch/x86/Makefile +@@ -298,10 +298,6 @@ vdso_install: + + archprepare: checkbin + checkbin: +-ifndef CONFIG_CC_HAS_ASM_GOTO +- @echo Compiler lacks asm-goto support. +- @exit 1 +-endif + ifdef CONFIG_RETPOLINE + ifeq ($(RETPOLINE_CFLAGS),) + @echo "You are building kernel with non-retpoline compiler." >&2 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Removed-extraneous-configs-from-gki.patch b/patches/ANDROID-Removed-extraneous-configs-from-gki.patch new file mode 100644 index 000000000000..4e93849b73a8 --- /dev/null +++ b/patches/ANDROID-Removed-extraneous-configs-from-gki.patch @@ -0,0 +1,98 @@ +From c7a44084de83b1737175e87662b02a0038de71a8 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 12 Jun 2019 18:05:43 -0700 +Subject: ANDROID: Removed extraneous configs from gki + +Removed SCSI_VIRTIO and VIRTIO_BALLOON + +Test: Boot x86 cuttlefish and gki +Signed-off-by: Ram Muthiah +Change-Id: I342ee9a9a2c715565ce5304f37d40575c234efd6 +--- + abi_gki_aarch64.xml | 252456 ++++++++-------- + arch/arm64/configs/cuttlefish_defconfig | 2 - + arch/arm64/configs/gki_defconfig | 2 - + arch/x86/configs/gki_defconfig | 2 - + arch/x86/configs/x86_64_cuttlefish_defconfig | 2 - + 5 files changed, 127295 insertions(+), 125169 deletions(-) + +Index: common/arch/arm64/configs/cuttlefish_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/cuttlefish_defconfig ++++ common/arch/arm64/configs/cuttlefish_defconfig +@@ -204,7 +204,6 @@ CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + # CONFIG_SCSI_PROC_FS is not set + CONFIG_BLK_DEV_SD=y +-CONFIG_SCSI_VIRTIO=y + CONFIG_MD=y + CONFIG_BLK_DEV_DM=y + CONFIG_DM_CRYPT=y +@@ -382,7 +381,6 @@ CONFIG_RTC_DRV_PL030=y + CONFIG_RTC_DRV_PL031=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set +-CONFIG_VIRTIO_BALLOON=y + CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -196,7 +196,6 @@ CONFIG_SCSI=y + CONFIG_BLK_DEV_SD=y + CONFIG_SCSI_UFSHCD=y + CONFIG_SCSI_UFSHCD_PLATFORM=y +-CONFIG_SCSI_VIRTIO=y + CONFIG_MD=y + CONFIG_BLK_DEV_DM=y + CONFIG_DM_CRYPT=y +@@ -327,7 +326,6 @@ CONFIG_RTC_DRV_PL030=y + CONFIG_RTC_DRV_PL031=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set +-CONFIG_VIRTIO_BALLOON=y + CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +Index: common/arch/x86/configs/gki_defconfig +=================================================================== +--- common.orig/arch/x86/configs/gki_defconfig ++++ common/arch/x86/configs/gki_defconfig +@@ -174,7 +174,6 @@ CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + # CONFIG_SCSI_PROC_FS is not set + CONFIG_BLK_DEV_SD=y +-CONFIG_SCSI_VIRTIO=y + CONFIG_MD=y + CONFIG_BLK_DEV_DM=y + CONFIG_DM_CRYPT=y +@@ -282,7 +281,6 @@ CONFIG_LEDS_TRIGGERS=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set + CONFIG_VIRTIO_PCI=y +-CONFIG_VIRTIO_BALLOON=y + CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +Index: common/arch/x86/configs/x86_64_cuttlefish_defconfig +=================================================================== +--- common.orig/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ common/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -217,7 +217,6 @@ CONFIG_BLK_DEV_SR_VENDOR=y + CONFIG_CHR_DEV_SG=y + CONFIG_SCSI_CONSTANTS=y + CONFIG_SCSI_SPI_ATTRS=y +-CONFIG_SCSI_VIRTIO=y + CONFIG_MD=y + CONFIG_BLK_DEV_DM=y + CONFIG_DM_CRYPT=y +@@ -399,7 +398,6 @@ CONFIG_MMC=y + CONFIG_RTC_CLASS=y + CONFIG_SW_SYNC=y + CONFIG_VIRTIO_PCI=y +-CONFIG_VIRTIO_BALLOON=y + CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y diff --git a/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch b/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch new file mode 100644 index 000000000000..8210b3933552 --- /dev/null +++ b/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch @@ -0,0 +1,47 @@ +From caf3327044b78551610869db4eb5f3a50fb037bc Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Sun, 15 Sep 2019 23:24:48 -0700 +Subject: ANDROID: Removed extraneous serial 8250 configs + +Signed-off-by: Ram Muthiah +Test: Local Boot of cuttlefish with this kernel +Bug: 132629930 +Change-Id: I12afb2b95105bfdbaa81cc51367664fa36a4f60c +--- + arch/arm64/configs/gki_defconfig | 4 ---- + arch/x86/configs/gki_defconfig | 4 ---- + 2 files changed, 8 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index d650f7d141e7f..ea9960028cfd3 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -264,10 +264,6 @@ CONFIG_SERIAL_8250=y + # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set + CONFIG_SERIAL_8250_CONSOLE=y + # CONFIG_SERIAL_8250_EXAR is not set +-CONFIG_SERIAL_8250_NR_UARTS=48 +-CONFIG_SERIAL_8250_EXTENDED=y +-CONFIG_SERIAL_8250_MANY_PORTS=y +-CONFIG_SERIAL_8250_SHARE_IRQ=y + CONFIG_SERIAL_OF_PLATFORM=m + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 511a763add373..a5953d43d480e 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -237,10 +237,6 @@ CONFIG_INPUT_UINPUT=y + CONFIG_SERIAL_8250=y + # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set + CONFIG_SERIAL_8250_CONSOLE=y +-CONFIG_SERIAL_8250_NR_UARTS=48 +-CONFIG_SERIAL_8250_EXTENDED=y +-CONFIG_SERIAL_8250_MANY_PORTS=y +-CONFIG_SERIAL_8250_SHARE_IRQ=y + CONFIG_SERIAL_OF_PLATFORM=m + CONFIG_HW_RANDOM=y + CONFIG_HW_RANDOM_VIRTIO=m +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Removed-hardcoded-kernel-command-line-argume.patch b/patches/ANDROID-Removed-hardcoded-kernel-command-line-argume.patch new file mode 100644 index 000000000000..34be42bda40f --- /dev/null +++ b/patches/ANDROID-Removed-hardcoded-kernel-command-line-argume.patch @@ -0,0 +1,29 @@ +From 0cff3964418be2e6ae15a66c815fae8fe5d1d2b5 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Sun, 4 Aug 2019 13:37:09 -0700 +Subject: ANDROID: Removed hardcoded kernel command line + arguments + +Test: Booted mainline on cuttlefish locally +Signed-off-by: Ram Muthiah +Change-Id: I5a32dcc1bc4faaff08b032f4ff8350adf2bbb5c1 +--- + arch/x86/configs/gki_defconfig | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 4016f8be75c52..731cec5e1bc30 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -35,8 +35,6 @@ CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_SMP=y +-CONFIG_CMDLINE_BOOL=y +-CONFIG_CMDLINE="console=ttyS0 reboot=p" + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch b/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch new file mode 100644 index 000000000000..47320bf7e216 --- /dev/null +++ b/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch @@ -0,0 +1,36 @@ +From 1d9332540b0ea68ffa85fa577a58c9f1de7fd468 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Fri, 9 Aug 2019 12:48:12 -0700 +Subject: ANDROID: Removed unnecessary modules from cuttlefish. + +Modules do not succesfuly load on cuttlefish and are not needed for gki. + +Bug: 132629930 +Test: Treehugger + Launch local KO Ramdisk +Signed-of-by: Ram Muthiah +Change-Id: I07b6c140e4c474d66132a4fb5630d18933b69e81 +--- + arch/x86/configs/gki_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 731cec5e1bc30..2d5f55d7b9669 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -242,11 +242,13 @@ CONFIG_HW_RANDOM_VIRTIO=y + CONFIG_GPIOLIB=y + # CONFIG_HWMON is not set + CONFIG_DEVFREQ_THERMAL=y ++# CONFIG_X86_PKG_TEMP_THERMAL is not set + CONFIG_MEDIA_SUPPORT=y + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=y ++# CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y + CONFIG_SND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-Turn-xt_owner-module-on.patch b/patches/ANDROID-Turn-xt_owner-module-on.patch new file mode 100644 index 000000000000..ed0273c87c65 --- /dev/null +++ b/patches/ANDROID-Turn-xt_owner-module-on.patch @@ -0,0 +1,48 @@ +From ef0ddecd14b7a66b6b36d7354b2f8f1fb5ab8ca1 Mon Sep 17 00:00:00 2001 +From: Chenbo Feng +Date: Fri, 8 Feb 2019 15:53:02 -0800 +Subject: ANDROID: Turn xt_owner module on + +Once xt_qtaguid module is deprecated, the netd strictController which +uses owner match to filter egress traffic will not work because +xt_qtaguid masquerades as (and implements/extends) the "owner" module on +android devices. It can be resolved by turning upstream xt_owner module +back on since strictController only targets egress traffic and the +upstream xt_owner module works fine in this case. + +Signed-off-by: Chenbo Feng +Bug: 79938294 +Test: manual cherry-pick and compile +Change-Id: Ia099db025f17f6042384c9f0caf7b941a40b8b84 +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index d74af2e0e4b1f..87a90ea32c2de 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -143,6 +143,7 @@ CONFIG_NETFILTER_XT_MATCH_LENGTH=y + CONFIG_NETFILTER_XT_MATCH_LIMIT=y + CONFIG_NETFILTER_XT_MATCH_MAC=y + CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_OWNER=y + CONFIG_NETFILTER_XT_MATCH_POLICY=y + CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y + CONFIG_NETFILTER_XT_MATCH_QUOTA=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 35c800c4bb40e..e889c64f64f80 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -147,6 +147,7 @@ CONFIG_NETFILTER_XT_MATCH_LENGTH=y + CONFIG_NETFILTER_XT_MATCH_LIMIT=y + CONFIG_NETFILTER_XT_MATCH_MAC=y + CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_OWNER=y + CONFIG_NETFILTER_XT_MATCH_POLICY=y + CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y + CONFIG_NETFILTER_XT_MATCH_QUOTA=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-add-extra-free-kbytes-tunable.patch b/patches/ANDROID-add-extra-free-kbytes-tunable.patch new file mode 100644 index 000000000000..6bfbd3288388 --- /dev/null +++ b/patches/ANDROID-add-extra-free-kbytes-tunable.patch @@ -0,0 +1,181 @@ +From e0e3dae468e3ddf181cd22c2a8cbe44f449a909e Mon Sep 17 00:00:00 2001 +From: Rik van Riel +Date: Thu, 1 Sep 2011 15:26:50 -0400 +Subject: ANDROID: add extra free kbytes tunable + +Add a userspace visible knob to tell the VM to keep an extra amount +of memory free, by increasing the gap between each zone's min and +low watermarks. + +This is useful for realtime applications that call system +calls and have a bound on the number of allocations that happen +in any short time period. In this application, extra_free_kbytes +would be left at an amount equal to or larger than than the +maximum number of allocations that happen in any burst. + +It may also be useful to reduce the memory use of virtual +machines (temporarily?), in a way that does not cause memory +fragmentation like ballooning does. + +[ccross] +Revived for use on old kernels where no other solution exists. +The tunable will be removed on kernels that do better at avoiding +direct reclaim. + +[surenb] +Will be reverted as soon as Android framework is reworked to +use upstream-supported watermark_scale_factor instead of +extra_free_kbytes. + +Bug: 86445363 +Bug: 109664768 +Bug: 120445732 +Change-Id: I765a42be8e964bfd3e2886d1ca85a29d60c3bb3e +Signed-off-by: Rik van Riel +Signed-off-by: Colin Cross +Signed-off-by: Suren Baghdasaryan +--- + Documentation/admin-guide/sysctl/vm.rst | 16 ++++++++++++++++ + kernel/sysctl.c | 9 +++++++++ + mm/page_alloc.c | 25 +++++++++++++++++++++---- + 3 files changed, 46 insertions(+), 4 deletions(-) + +diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst +index 64aeee1009cab..9e84700082275 100644 +--- a/Documentation/admin-guide/sysctl/vm.rst ++++ b/Documentation/admin-guide/sysctl/vm.rst +@@ -37,6 +37,7 @@ Currently, these files are in /proc/sys/vm: + - dirty_writeback_centisecs + - drop_caches + - extfrag_threshold ++- extra_free_kbytes + - hugetlb_shm_group + - laptop_mode + - legacy_va_layout +@@ -287,6 +288,21 @@ only use the low memory and they can fill it up with dirty data without + any throttling. + + ++extra_free_kbytes ++ ++This parameter tells the VM to keep extra free memory between the threshold ++where background reclaim (kswapd) kicks in, and the threshold where direct ++reclaim (by allocating processes) kicks in. ++ ++This is useful for workloads that require low latency memory allocations ++and have a bounded burstiness in memory allocations, for example a ++realtime application that receives and transmits network traffic ++(causing in-kernel memory allocations) with a maximum total message burst ++size of 200MB may need 200MB of extra free memory to avoid direct reclaim ++related latencies. ++ ++============================================================== ++ + hugetlb_shm_group + ================= + +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 078950d9605ba..94cf7c5c1a3f9 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -111,6 +111,7 @@ extern char core_pattern[]; + extern unsigned int core_pipe_limit; + #endif + extern int pid_max; ++extern int extra_free_kbytes; + extern int pid_max_min, pid_max_max; + extern int percpu_pagelist_fraction; + extern int latencytop_enabled; +@@ -1523,6 +1524,14 @@ static struct ctl_table vm_table[] = { + .extra1 = SYSCTL_ONE, + .extra2 = &one_thousand, + }, ++ { ++ .procname = "extra_free_kbytes", ++ .data = &extra_free_kbytes, ++ .maxlen = sizeof(extra_free_kbytes), ++ .mode = 0644, ++ .proc_handler = min_free_kbytes_sysctl_handler, ++ .extra1 = SYSCTL_ZERO, ++ }, + { + .procname = "percpu_pagelist_fraction", + .data = &percpu_pagelist_fraction, +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 9c9194959271c..ff37c80783da3 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -313,6 +313,11 @@ compound_page_dtor * const compound_page_dtors[] = { + #endif + }; + ++/* ++ * Try to keep at least this much lowmem free. Do not allow normal ++ * allocations below this point, only high priority ones. Automatically ++ * tuned according to the amount of memory in the system. ++ */ + int min_free_kbytes = 1024; + int user_min_free_kbytes = -1; + #ifdef CONFIG_DISCONTIGMEM +@@ -331,6 +336,13 @@ int watermark_boost_factor __read_mostly = 15000; + #endif + int watermark_scale_factor = 10; + ++/* ++ * Extra memory for the system to try freeing. Used to temporarily ++ * free memory, to make space for new workloads. Anyone can allocate ++ * down to the min watermarks controlled by min_free_kbytes above. ++ */ ++int extra_free_kbytes = 0; ++ + static unsigned long nr_kernel_pages __initdata; + static unsigned long nr_all_pages __initdata; + static unsigned long dma_reserve __initdata; +@@ -7692,6 +7704,7 @@ static void setup_per_zone_lowmem_reserve(void) + static void __setup_per_zone_wmarks(void) + { + unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); ++ unsigned long pages_low = extra_free_kbytes >> (PAGE_SHIFT - 10); + unsigned long lowmem_pages = 0; + struct zone *zone; + unsigned long flags; +@@ -7703,11 +7716,13 @@ static void __setup_per_zone_wmarks(void) + } + + for_each_zone(zone) { +- u64 tmp; ++ u64 tmp, low; + + spin_lock_irqsave(&zone->lock, flags); + tmp = (u64)pages_min * zone_managed_pages(zone); + do_div(tmp, lowmem_pages); ++ low = (u64)pages_low * zone_managed_pages(zone); ++ do_div(low, vm_total_pages); + if (is_highmem(zone)) { + /* + * __GFP_HIGH and PF_MEMALLOC allocations usually don't +@@ -7740,8 +7755,10 @@ static void __setup_per_zone_wmarks(void) + mult_frac(zone_managed_pages(zone), + watermark_scale_factor, 10000)); + +- zone->_watermark[WMARK_LOW] = min_wmark_pages(zone) + tmp; +- zone->_watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2; ++ zone->_watermark[WMARK_LOW] = min_wmark_pages(zone) + ++ low + tmp; ++ zone->_watermark[WMARK_HIGH] = min_wmark_pages(zone) + ++ low + tmp * 2; + zone->watermark_boost = 0; + + spin_unlock_irqrestore(&zone->lock, flags); +@@ -7825,7 +7842,7 @@ core_initcall(init_per_zone_wmark_min) + /* + * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so + * that we can call two helper functions whenever min_free_kbytes +- * changes. ++ * or extra_free_kbytes changes. + */ + int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *length, loff_t *ppos) +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttl.patch b/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttl.patch new file mode 100644 index 000000000000..1a775580337d --- /dev/null +++ b/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttl.patch @@ -0,0 +1,53 @@ +From 3b628b0636d640bbe7cf646192d325cbd33404ca Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 22 May 2019 20:11:24 -0700 +Subject: ANDROID: added configs so that GKI boots on x86 + cuttlefish + +Bug: 132629930 +Test: built and ran gki on cuttlefish locally +Change-Id: I2cbfef4fd97888edaa5b6413a2459160c7117bd5 +Signed-off-by: Ram Muthiah +--- + arch/x86/configs/gki_defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 18ba312d0a602..cdaba53b7bb04 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -38,6 +38,7 @@ CONFIG_CPU_FREQ=y + CONFIG_CPU_FREQ_TIMES=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=y + CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_IA32_EMULATION=y + CONFIG_KPROBES=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y +@@ -156,6 +157,7 @@ CONFIG_CFG80211=y + CONFIG_MAC80211=y + # CONFIG_MAC80211_RC_MINSTREL is not set + CONFIG_RFKILL=y ++CONFIG_PCI=y + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y + CONFIG_ZRAM=y +@@ -274,6 +276,7 @@ CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set ++CONFIG_VIRTIO_PCI=y + CONFIG_VIRTIO_BALLOON=y + CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y +@@ -289,6 +292,7 @@ CONFIG_EXT4_FS=y + CONFIG_EXT4_FS_SECURITY=y + CONFIG_F2FS_FS=y + CONFIG_F2FS_FS_SECURITY=y ++CONFIG_FS_ENCRYPTION=y + # CONFIG_DNOTIFY is not set + CONFIG_QUOTA=y + CONFIG_QFMT_V2=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-wr.patch b/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-wr.patch new file mode 100644 index 000000000000..5619b7ffa068 --- /dev/null +++ b/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-wr.patch @@ -0,0 +1,41 @@ +From ea4b5d09e53c6007ed1959f53c2968f785b07521 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 3 Jul 2019 14:31:23 -0700 +Subject: ANDROID: adding usb HCD dummy config to permit usb + write ops on init + +Bug: 136021903 +Change-Id: I45ae272fd7243e290f0701a7f29722788ce0cd5a +Signed-off-by: Ram Muthiah +--- + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index ec05661160667..7c66f40c97398 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -314,6 +314,7 @@ CONFIG_HID_MULTITOUCH=y + CONFIG_USB_HIDDEV=y + CONFIG_USB=y + CONFIG_USB_GADGET=y ++CONFIG_USB_DUMMY_HCD=y + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index c0993920b94dd..65c67797fb74d 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -267,6 +267,7 @@ CONFIG_HID_MULTITOUCH=y + CONFIG_USB_HIDDEV=y + CONFIG_USB=y + CONFIG_USB_GADGET=y ++CONFIG_USB_DUMMY_HCD=y + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch b/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch new file mode 100644 index 000000000000..d29ca3046a46 --- /dev/null +++ b/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch @@ -0,0 +1,37 @@ +From bdac6faf2dfdd42e3a101416dba539550d96ad05 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Mon, 30 Sep 2019 16:23:52 +0100 +Subject: ANDROID: allmodconfig: Force gki_defconfig as + base + +Allmodconfig enables as many options as it can to maximize the number of +modules it can build. While this is generally a good idea, this can also +lead to very convoluted configurations (such as CPU_BIG_ENDIAN=y on +arm64) which we don't necessarily want to support even if they break. On +the other hand, gki_defconfig already contains the set of core options +we definitely want to support, so it makes sense to use that as a base. + +Point KCONFIG_ALLMODCONFIG to the relevant gki_defconfig file in order +to ensure a minimally sensible config that allconfig is not allowed to +modify. + +Bug: 140224784 +Signed-off-by: Quentin Perret +Change-Id: Ib4cf3c9565f040a577ce3cec008293520be1af84 +--- + build.config.allmodconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/build.config.allmodconfig b/build.config.allmodconfig +index 43b1a70d5800..6e0404b8de47 100644 +--- a/build.config.allmodconfig ++++ b/build.config.allmodconfig +@@ -1,4 +1,5 @@ + DEFCONFIG=allmodconfig ++KCONFIG_ALLCONFIG=${ROOT_DIR}/common/arch/${ARCH%_*}/configs/gki_defconfig + + # XFS_FS is currently broken on this branch with clang-9 + POST_DEFCONFIG_CMDS="update_config" +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-arm-enable-max-frequency-capping.patch b/patches/ANDROID-arm-enable-max-frequency-capping.patch new file mode 100644 index 000000000000..9600371e56ba --- /dev/null +++ b/patches/ANDROID-arm-enable-max-frequency-capping.patch @@ -0,0 +1,33 @@ +From 150b7ce48a29566d996bda293e8857ef45298bdc Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann +Date: Thu, 10 May 2018 16:58:04 +0100 +Subject: ANDROID: arm: enable max frequency capping + +Defines arch_scale_max_freq_capacity() to use the topology driver +scale function. + +Signed-off-by: Ionela Voinescu +Signed-off-by: Dietmar Eggemann +Signed-off-by: Quentin Perret +Change-Id: I79f444399ea3b2948364fde80ccee52a9ece5b9a +--- + arch/arm/include/asm/topology.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h +index 8a0fae94d45e..a2edacb56459 100644 +--- a/arch/arm/include/asm/topology.h ++++ b/arch/arm/include/asm/topology.h +@@ -10,6 +10,9 @@ + /* Replace task scheduler's default frequency-invariant accounting */ + #define arch_scale_freq_capacity topology_get_freq_scale + ++/* Replace task scheduler's default max-frequency-invariant accounting */ ++#define arch_scale_max_freq_capacity topology_get_max_freq_scale ++ + /* Replace task scheduler's default cpu-invariant accounting */ + #define arch_scale_cpu_capacity topology_get_cpu_scale + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch b/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch new file mode 100644 index 000000000000..57bf148e885f --- /dev/null +++ b/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch @@ -0,0 +1,55 @@ +From fe16d6c073c3b27fd0d00caf8f9251b2335c3316 Mon Sep 17 00:00:00 2001 +From: Colin Cross +Date: Wed, 2 Apr 2014 18:02:15 -0700 +Subject: ANDROID: arm64: copy CONFIG_CMDLINE_EXTEND from ARM + +Copy the config choice for CONFIG_CMDLINE_EXTEND from +arch/arm/Kconfig, including CONFIG_CMDLINE_FROM_BOOTLOADER +as the default. These will be used by drivers/of/fdt.c. + +Bug: 120440972 +Change-Id: I8416038498ddf8fc1e99ab06109825eb1492aa7f +Signed-off-by: Colin Cross +--- + arch/arm64/Kconfig | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 3adcec05b1f67..b1dd948f96659 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -1538,6 +1538,23 @@ config CMDLINE + entering them here. As a minimum, you should specify the the + root device (e.g. root=/dev/nfs). + ++choice ++ prompt "Kernel command line type" if CMDLINE != "" ++ default CMDLINE_FROM_BOOTLOADER ++ ++config CMDLINE_FROM_BOOTLOADER ++ bool "Use bootloader kernel arguments if available" ++ help ++ Uses the command-line options passed by the boot loader. If ++ the boot loader doesn't provide any, the default kernel command ++ string provided in CMDLINE will be used. ++ ++config CMDLINE_EXTEND ++ bool "Extend bootloader kernel arguments" ++ help ++ The command-line arguments provided by the boot loader will be ++ appended to the default kernel command string. ++ + config CMDLINE_FORCE + bool "Always use the default kernel command string" + help +@@ -1545,6 +1562,7 @@ config CMDLINE_FORCE + loader passes other arguments to the kernel. + This is useful if you cannot or don't want to change the + command-line options your boot loader passes to the kernel. ++endchoice + + config EFI_STUB + bool +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch b/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch new file mode 100644 index 000000000000..bc7db899b107 --- /dev/null +++ b/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch @@ -0,0 +1,47 @@ +From 588085feb44fa553aec7eb98545a570e189eabad Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Wed, 3 Jul 2019 10:48:14 +0100 +Subject: ANDROID: arm64: defconfig: Enable EAS by default + +Use schedutil as default cpufreq governor so EAS can start. Also, enable +util-clamp to enable frequency selection biasing. + +Change-Id: Iec9098f27c0353dabc23bd98efbca6479de41796 +Signed-off-by: Quentin Perret +--- + arch/arm64/configs/defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 8e05c39eab08..2c029af5d7e0 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -13,10 +13,12 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y ++CONFIG_UCLAMP_TASK=y + CONFIG_NUMA_BALANCING=y + CONFIG_MEMCG=y + CONFIG_MEMCG_SWAP=y + CONFIG_BLK_CGROUP=y ++CONFIG_UCLAMP_TASK_GROUP=y + CONFIG_CGROUP_PIDS=y + CONFIG_CGROUP_HUGETLB=y + CONFIG_CPUSETS=y +@@ -71,10 +73,12 @@ CONFIG_COMPAT=y + CONFIG_RANDOMIZE_BASE=y + CONFIG_HIBERNATION=y + CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_ENERGY_MODEL=y + CONFIG_ARM_CPUIDLE=y + CONFIG_ARM_PSCI_CPUIDLE=y + CONFIG_CPU_FREQ=y + CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=m + CONFIG_CPU_FREQ_GOV_USERSPACE=y + CONFIG_CPU_FREQ_GOV_ONDEMAND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-arm64-enable-max-frequency-capping.patch b/patches/ANDROID-arm64-enable-max-frequency-capping.patch new file mode 100644 index 000000000000..02db9f29b6a9 --- /dev/null +++ b/patches/ANDROID-arm64-enable-max-frequency-capping.patch @@ -0,0 +1,33 @@ +From a273512dafbf6322b134716873d50d1af803972f Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann +Date: Thu, 10 May 2018 16:54:16 +0100 +Subject: ANDROID: arm64: enable max frequency capping + +Defines arch_scale_max_freq_capacity() to use the topology driver +scale function. + +Change-Id: If7565747ec862e42ac55196240522ef8d22ca67d +Signed-off-by: Ionela Voinescu +Signed-off-by: Dietmar Eggemann +Signed-off-by: Quentin Perret +--- + arch/arm64/include/asm/topology.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h +index a4d945db95a2..70697177d6ec 100644 +--- a/arch/arm64/include/asm/topology.h ++++ b/arch/arm64/include/asm/topology.h +@@ -19,6 +19,9 @@ int pcibus_to_node(struct pci_bus *bus); + /* Replace task scheduler's default frequency-invariant accounting */ + #define arch_scale_freq_capacity topology_get_freq_scale + ++/* Replace task scheduler's default max-frequency-invariant accounting */ ++#define arch_scale_max_freq_capacity topology_get_max_freq_scale ++ + /* Replace task scheduler's default cpu-invariant accounting */ + #define arch_scale_cpu_capacity topology_get_cpu_scale + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch b/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch new file mode 100644 index 000000000000..edeb0606656a --- /dev/null +++ b/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch @@ -0,0 +1,573 @@ +From f26f402c7656946b47df499d381fc51bc5a966a1 Mon Sep 17 00:00:00 2001 +From: Martijn Coenen +Date: Tue, 6 Jun 2017 17:04:42 -0700 +Subject: ANDROID: binder: add support for RT prio inheritance. + +Adds support for SCHED_BATCH/SCHED_FIFO/SCHED_RR +priority inheritance. + +Bug: 34461621 +Bug: 37293077 +Bug: 120446518 +Change-Id: I71f356e476be2933713a0ecfa2cc31aa141e2dc6 +Signed-off-by: Martijn Coenen +[AmitP: Include for struct sched_param] +Signed-off-by: Amit Pundir +[astrachan: Folded the following changes into this patch: + 69308b3b07dd ("ANDROID: binder: add min sched_policy to node.") + 7a6edeb62d86 ("ANDROID: binder: improve priority inheritance.") + 22b061b17679 ("ANDROID: binder: don't check prio permissions on restore.") + 67cf97141d81 ("ANDROID: binder: Add tracing for binder priority inheritance.") + fb92c34f7ba3 ("ANDROID: binder: add RT inheritance flag to node.") + c847b48f8cda ("ANDROID: binder: init desired_prio.sched_policy before use it")] +Signed-off-by: Alistair Strachan +--- + drivers/android/binder.c | 243 ++++++++++++++++++++++++---- + drivers/android/binder_trace.h | 24 +++ + include/uapi/linux/android/binder.h | 50 +++++- + 3 files changed, 284 insertions(+), 33 deletions(-) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index dc1c83eafc225..f3cf51af833bf 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -66,6 +66,7 @@ + #include + + #include ++#include + + #include + +@@ -316,10 +317,13 @@ struct binder_error { + * and by @lock) + * @has_async_transaction: async transaction to node in progress + * (protected by @lock) ++ * @sched_policy: minimum scheduling policy for node ++ * (invariant after initialized) + * @accept_fds: file descriptor operations supported for node + * (invariant after initialized) + * @min_priority: minimum scheduling priority + * (invariant after initialized) ++ * @inherit_rt: inherit RT scheduling policy from caller + * @txn_security_ctx: require sender's security context + * (invariant after initialized) + * @async_todo: list of async work items +@@ -357,6 +361,8 @@ struct binder_node { + /* + * invariant after initialization + */ ++ u8 sched_policy:2; ++ u8 inherit_rt:1; + u8 accept_fds:1; + u8 txn_security_ctx:1; + u8 min_priority; +@@ -430,6 +436,22 @@ enum binder_deferred_state { + BINDER_DEFERRED_RELEASE = 0x02, + }; + ++/** ++ * struct binder_priority - scheduler policy and priority ++ * @sched_policy scheduler policy ++ * @prio [100..139] for SCHED_NORMAL, [0..99] for FIFO/RT ++ * ++ * The binder driver supports inheriting the following scheduler policies: ++ * SCHED_NORMAL ++ * SCHED_BATCH ++ * SCHED_FIFO ++ * SCHED_RR ++ */ ++struct binder_priority { ++ unsigned int sched_policy; ++ int prio; ++}; ++ + /** + * struct binder_proc - binder process bookkeeping + * @proc_node: element for binder_procs list +@@ -503,7 +525,7 @@ struct binder_proc { + int requested_threads; + int requested_threads_started; + int tmp_ref; +- long default_priority; ++ struct binder_priority default_priority; + struct dentry *debugfs_entry; + struct binder_alloc alloc; + struct binder_context *context; +@@ -553,6 +575,7 @@ enum { + * @is_dead: thread is dead and awaiting free + * when outstanding transactions are cleaned up + * (protected by @proc->inner_lock) ++ * @task: struct task_struct for this thread + * + * Bookkeeping structure for binder threads. + */ +@@ -572,6 +595,7 @@ struct binder_thread { + struct binder_stats stats; + atomic_t tmp_ref; + bool is_dead; ++ struct task_struct *task; + }; + + /** +@@ -605,8 +629,9 @@ struct binder_transaction { + struct binder_buffer *buffer; + unsigned int code; + unsigned int flags; +- long priority; +- long saved_priority; ++ struct binder_priority priority; ++ struct binder_priority saved_priority; ++ bool set_priority_called; + kuid_t sender_euid; + struct list_head fd_fixups; + binder_uintptr_t security_ctx; +@@ -1065,22 +1090,145 @@ static void binder_wakeup_proc_ilocked(struct binder_proc *proc) + binder_wakeup_thread_ilocked(proc, thread, /* sync = */false); + } + +-static void binder_set_nice(long nice) ++static bool is_rt_policy(int policy) ++{ ++ return policy == SCHED_FIFO || policy == SCHED_RR; ++} ++ ++static bool is_fair_policy(int policy) ++{ ++ return policy == SCHED_NORMAL || policy == SCHED_BATCH; ++} ++ ++static bool binder_supported_policy(int policy) ++{ ++ return is_fair_policy(policy) || is_rt_policy(policy); ++} ++ ++static int to_userspace_prio(int policy, int kernel_priority) ++{ ++ if (is_fair_policy(policy)) ++ return PRIO_TO_NICE(kernel_priority); ++ else ++ return MAX_USER_RT_PRIO - 1 - kernel_priority; ++} ++ ++static int to_kernel_prio(int policy, int user_priority) + { +- long min_nice; ++ if (is_fair_policy(policy)) ++ return NICE_TO_PRIO(user_priority); ++ else ++ return MAX_USER_RT_PRIO - 1 - user_priority; ++} + +- if (can_nice(current, nice)) { +- set_user_nice(current, nice); ++static void binder_do_set_priority(struct task_struct *task, ++ struct binder_priority desired, ++ bool verify) ++{ ++ int priority; /* user-space prio value */ ++ bool has_cap_nice; ++ unsigned int policy = desired.sched_policy; ++ ++ if (task->policy == policy && task->normal_prio == desired.prio) + return; ++ ++ has_cap_nice = has_capability_noaudit(task, CAP_SYS_NICE); ++ ++ priority = to_userspace_prio(policy, desired.prio); ++ ++ if (verify && is_rt_policy(policy) && !has_cap_nice) { ++ long max_rtprio = task_rlimit(task, RLIMIT_RTPRIO); ++ ++ if (max_rtprio == 0) { ++ policy = SCHED_NORMAL; ++ priority = MIN_NICE; ++ } else if (priority > max_rtprio) { ++ priority = max_rtprio; ++ } ++ } ++ ++ if (verify && is_fair_policy(policy) && !has_cap_nice) { ++ long min_nice = rlimit_to_nice(task_rlimit(task, RLIMIT_NICE)); ++ ++ if (min_nice > MAX_NICE) { ++ binder_user_error("%d RLIMIT_NICE not set\n", ++ task->pid); ++ return; ++ } else if (priority < min_nice) { ++ priority = min_nice; ++ } ++ } ++ ++ if (policy != desired.sched_policy || ++ to_kernel_prio(policy, priority) != desired.prio) ++ binder_debug(BINDER_DEBUG_PRIORITY_CAP, ++ "%d: priority %d not allowed, using %d instead\n", ++ task->pid, desired.prio, ++ to_kernel_prio(policy, priority)); ++ ++ trace_binder_set_priority(task->tgid, task->pid, task->normal_prio, ++ to_kernel_prio(policy, priority), ++ desired.prio); ++ ++ /* Set the actual priority */ ++ if (task->policy != policy || is_rt_policy(policy)) { ++ struct sched_param params; ++ ++ params.sched_priority = is_rt_policy(policy) ? priority : 0; ++ ++ sched_setscheduler_nocheck(task, ++ policy | SCHED_RESET_ON_FORK, ++ ¶ms); + } +- min_nice = rlimit_to_nice(rlimit(RLIMIT_NICE)); +- binder_debug(BINDER_DEBUG_PRIORITY_CAP, +- "%d: nice value %ld not allowed use %ld instead\n", +- current->pid, nice, min_nice); +- set_user_nice(current, min_nice); +- if (min_nice <= MAX_NICE) ++ if (is_fair_policy(policy)) ++ set_user_nice(task, priority); ++} ++ ++static void binder_set_priority(struct task_struct *task, ++ struct binder_priority desired) ++{ ++ binder_do_set_priority(task, desired, /* verify = */ true); ++} ++ ++static void binder_restore_priority(struct task_struct *task, ++ struct binder_priority desired) ++{ ++ binder_do_set_priority(task, desired, /* verify = */ false); ++} ++ ++static void binder_transaction_priority(struct task_struct *task, ++ struct binder_transaction *t, ++ struct binder_priority node_prio, ++ bool inherit_rt) ++{ ++ struct binder_priority desired_prio = t->priority; ++ ++ if (t->set_priority_called) + return; +- binder_user_error("%d RLIMIT_NICE not set\n", current->pid); ++ ++ t->set_priority_called = true; ++ t->saved_priority.sched_policy = task->policy; ++ t->saved_priority.prio = task->normal_prio; ++ ++ if (!inherit_rt && is_rt_policy(desired_prio.sched_policy)) { ++ desired_prio.prio = NICE_TO_PRIO(0); ++ desired_prio.sched_policy = SCHED_NORMAL; ++ } ++ ++ if (node_prio.prio < t->priority.prio || ++ (node_prio.prio == t->priority.prio && ++ node_prio.sched_policy == SCHED_FIFO)) { ++ /* ++ * In case the minimum priority on the node is ++ * higher (lower value), use that priority. If ++ * the priority is the same, but the node uses ++ * SCHED_FIFO, prefer SCHED_FIFO, since it can ++ * run unbounded, unlike SCHED_RR. ++ */ ++ desired_prio = node_prio; ++ } ++ ++ binder_set_priority(task, desired_prio); + } + + static struct binder_node *binder_get_node_ilocked(struct binder_proc *proc, +@@ -1133,6 +1281,7 @@ static struct binder_node *binder_init_node_ilocked( + binder_uintptr_t ptr = fp ? fp->binder : 0; + binder_uintptr_t cookie = fp ? fp->cookie : 0; + __u32 flags = fp ? fp->flags : 0; ++ s8 priority; + + assert_spin_locked(&proc->inner_lock); + +@@ -1165,8 +1314,12 @@ static struct binder_node *binder_init_node_ilocked( + node->ptr = ptr; + node->cookie = cookie; + node->work.type = BINDER_WORK_NODE; +- node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; ++ priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; ++ node->sched_policy = (flags & FLAT_BINDER_FLAG_SCHED_POLICY_MASK) >> ++ FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT; ++ node->min_priority = to_kernel_prio(node->sched_policy, priority); + node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); ++ node->inherit_rt = !!(flags & FLAT_BINDER_FLAG_INHERIT_RT); + node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); + spin_lock_init(&node->lock); + INIT_LIST_HEAD(&node->work.entry); +@@ -2777,11 +2930,15 @@ static bool binder_proc_transaction(struct binder_transaction *t, + struct binder_thread *thread) + { + struct binder_node *node = t->buffer->target_node; ++ struct binder_priority node_prio; + bool oneway = !!(t->flags & TF_ONE_WAY); + bool pending_async = false; + + BUG_ON(!node); + binder_node_lock(node); ++ node_prio.prio = node->min_priority; ++ node_prio.sched_policy = node->sched_policy; ++ + if (oneway) { + BUG_ON(thread); + if (node->has_async_transaction) { +@@ -2802,12 +2959,15 @@ static bool binder_proc_transaction(struct binder_transaction *t, + if (!thread && !pending_async) + thread = binder_select_thread_ilocked(proc); + +- if (thread) ++ if (thread) { ++ binder_transaction_priority(thread->task, t, node_prio, ++ node->inherit_rt); + binder_enqueue_thread_work_ilocked(thread, &t->work); +- else if (!pending_async) ++ } else if (!pending_async) { + binder_enqueue_work_ilocked(&t->work, &proc->todo); +- else ++ } else { + binder_enqueue_work_ilocked(&t->work, &node->async_todo); ++ } + + if (!pending_async) + binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); +@@ -2928,7 +3088,6 @@ static void binder_transaction(struct binder_proc *proc, + } + thread->transaction_stack = in_reply_to->to_parent; + binder_inner_proc_unlock(proc); +- binder_set_nice(in_reply_to->saved_priority); + target_thread = binder_get_txn_from_and_acq_inner(in_reply_to); + if (target_thread == NULL) { + /* annotation for sparse */ +@@ -3127,7 +3286,15 @@ static void binder_transaction(struct binder_proc *proc, + t->to_thread = target_thread; + t->code = tr->code; + t->flags = tr->flags; +- t->priority = task_nice(current); ++ if (!(t->flags & TF_ONE_WAY) && ++ binder_supported_policy(current->policy)) { ++ /* Inherit supported policies for synchronous transactions */ ++ t->priority.sched_policy = current->policy; ++ t->priority.prio = current->normal_prio; ++ } else { ++ /* Otherwise, fall back to the default priority */ ++ t->priority = target_proc->default_priority; ++ } + + if (target_node && target_node->txn_security_ctx) { + u32 secid; +@@ -3454,6 +3621,7 @@ static void binder_transaction(struct binder_proc *proc, + binder_enqueue_thread_work_ilocked(target_thread, &t->work); + binder_inner_proc_unlock(target_proc); + wake_up_interruptible_sync(&target_thread->wait); ++ binder_restore_priority(current, in_reply_to->saved_priority); + binder_free_transaction(in_reply_to); + } else if (!(t->flags & TF_ONE_WAY)) { + BUG_ON(t->buffer->async_transaction != 0); +@@ -3564,6 +3732,7 @@ static void binder_transaction(struct binder_proc *proc, + + BUG_ON(thread->return_error.cmd != BR_OK); + if (in_reply_to) { ++ binder_restore_priority(current, in_reply_to->saved_priority); + thread->return_error.cmd = BR_TRANSACTION_COMPLETE; + binder_enqueue_thread_work(thread, &thread->return_error.work); + binder_send_failed_reply(in_reply_to, return_error); +@@ -4230,7 +4399,7 @@ static int binder_thread_read(struct binder_proc *proc, + wait_event_interruptible(binder_user_error_wait, + binder_stop_on_user_error < 2); + } +- binder_set_nice(proc->default_priority); ++ binder_restore_priority(current, proc->default_priority); + } + + if (non_block) { +@@ -4452,16 +4621,14 @@ static int binder_thread_read(struct binder_proc *proc, + BUG_ON(t->buffer == NULL); + if (t->buffer->target_node) { + struct binder_node *target_node = t->buffer->target_node; ++ struct binder_priority node_prio; + + trd->target.ptr = target_node->ptr; + trd->cookie = target_node->cookie; +- t->saved_priority = task_nice(current); +- if (t->priority < target_node->min_priority && +- !(t->flags & TF_ONE_WAY)) +- binder_set_nice(t->priority); +- else if (!(t->flags & TF_ONE_WAY) || +- t->saved_priority > target_node->min_priority) +- binder_set_nice(target_node->min_priority); ++ node_prio.sched_policy = target_node->sched_policy; ++ node_prio.prio = target_node->min_priority; ++ binder_transaction_priority(current, t, node_prio, ++ target_node->inherit_rt); + cmd = BR_TRANSACTION; + } else { + trd->target.ptr = 0; +@@ -4673,6 +4840,8 @@ static struct binder_thread *binder_get_thread_ilocked( + binder_stats_created(BINDER_STAT_THREAD); + thread->proc = proc; + thread->pid = current->pid; ++ get_task_struct(current); ++ thread->task = current; + atomic_set(&thread->tmp_ref, 0); + init_waitqueue_head(&thread->wait); + INIT_LIST_HEAD(&thread->todo); +@@ -4723,6 +4892,7 @@ static void binder_free_thread(struct binder_thread *thread) + BUG_ON(!list_empty(&thread->todo)); + binder_stats_deleted(BINDER_STAT_THREAD); + binder_proc_dec_tmpref(thread->proc); ++ put_task_struct(thread->task); + kfree(thread); + } + +@@ -5242,7 +5412,14 @@ static int binder_open(struct inode *nodp, struct file *filp) + get_task_struct(current->group_leader); + proc->tsk = current->group_leader; + INIT_LIST_HEAD(&proc->todo); +- proc->default_priority = task_nice(current); ++ if (binder_supported_policy(current->policy)) { ++ proc->default_priority.sched_policy = current->policy; ++ proc->default_priority.prio = current->normal_prio; ++ } else { ++ proc->default_priority.sched_policy = SCHED_NORMAL; ++ proc->default_priority.prio = NICE_TO_PRIO(0); ++ } ++ + /* binderfs stashes devices in i_private */ + if (is_binderfs_device(nodp)) + binder_dev = nodp->i_private; +@@ -5525,13 +5702,14 @@ static void print_binder_transaction_ilocked(struct seq_file *m, + spin_lock(&t->lock); + to_proc = t->to_proc; + seq_printf(m, +- "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d", ++ "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", + prefix, t->debug_id, t, + t->from ? t->from->proc->pid : 0, + t->from ? t->from->pid : 0, + to_proc ? to_proc->pid : 0, + t->to_thread ? t->to_thread->pid : 0, +- t->code, t->flags, t->priority, t->need_reply); ++ t->code, t->flags, t->priority.sched_policy, ++ t->priority.prio, t->need_reply); + spin_unlock(&t->lock); + + if (proc != to_proc) { +@@ -5649,8 +5827,9 @@ static void print_binder_node_nilocked(struct seq_file *m, + hlist_for_each_entry(ref, &node->refs, node_entry) + count++; + +- seq_printf(m, " node %d: u%016llx c%016llx hs %d hw %d ls %d lw %d is %d iw %d tr %d", ++ seq_printf(m, " node %d: u%016llx c%016llx pri %d:%d hs %d hw %d ls %d lw %d is %d iw %d tr %d", + node->debug_id, (u64)node->ptr, (u64)node->cookie, ++ node->sched_policy, node->min_priority, + node->has_strong_ref, node->has_weak_ref, + node->local_strong_refs, node->local_weak_refs, + node->internal_strong_refs, count, node->tmp_refs); +diff --git a/drivers/android/binder_trace.h b/drivers/android/binder_trace.h +index 6731c3cd81455..a70e23716ad04 100644 +--- a/drivers/android/binder_trace.h ++++ b/drivers/android/binder_trace.h +@@ -76,6 +76,30 @@ DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done); + DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_write_done); + DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_read_done); + ++TRACE_EVENT(binder_set_priority, ++ TP_PROTO(int proc, int thread, unsigned int old_prio, ++ unsigned int desired_prio, unsigned int new_prio), ++ TP_ARGS(proc, thread, old_prio, new_prio, desired_prio), ++ ++ TP_STRUCT__entry( ++ __field(int, proc) ++ __field(int, thread) ++ __field(unsigned int, old_prio) ++ __field(unsigned int, new_prio) ++ __field(unsigned int, desired_prio) ++ ), ++ TP_fast_assign( ++ __entry->proc = proc; ++ __entry->thread = thread; ++ __entry->old_prio = old_prio; ++ __entry->new_prio = new_prio; ++ __entry->desired_prio = desired_prio; ++ ), ++ TP_printk("proc=%d thread=%d old=%d => new=%d desired=%d", ++ __entry->proc, __entry->thread, __entry->old_prio, ++ __entry->new_prio, __entry->desired_prio) ++); ++ + TRACE_EVENT(binder_wait_for_work, + TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo), + TP_ARGS(proc_work, transaction_stack, thread_todo), +diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h +index 2832134e53971..11babae0339f2 100644 +--- a/include/uapi/linux/android/binder.h ++++ b/include/uapi/linux/android/binder.h +@@ -38,10 +38,58 @@ enum { + BINDER_TYPE_PTR = B_PACK_CHARS('p', 't', '*', B_TYPE_LARGE), + }; + +-enum { ++/** ++ * enum flat_binder_object_shifts: shift values for flat_binder_object_flags ++ * @FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT: shift for getting scheduler policy. ++ * ++ */ ++enum flat_binder_object_shifts { ++ FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT = 9, ++}; ++ ++/** ++ * enum flat_binder_object_flags - flags for use in flat_binder_object.flags ++ */ ++enum flat_binder_object_flags { ++ /** ++ * @FLAT_BINDER_FLAG_PRIORITY_MASK: bit-mask for min scheduler priority ++ * ++ * These bits can be used to set the minimum scheduler priority ++ * at which transactions into this node should run. Valid values ++ * in these bits depend on the scheduler policy encoded in ++ * @FLAT_BINDER_FLAG_SCHED_POLICY_MASK. ++ * ++ * For SCHED_NORMAL/SCHED_BATCH, the valid range is between [-20..19] ++ * For SCHED_FIFO/SCHED_RR, the value can run between [1..99] ++ */ + FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, ++ /** ++ * @FLAT_BINDER_FLAG_ACCEPTS_FDS: whether the node accepts fds. ++ */ + FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, + ++ /** ++ * @FLAT_BINDER_FLAG_SCHED_POLICY_MASK: bit-mask for scheduling policy ++ * ++ * These two bits can be used to set the min scheduling policy at which ++ * transactions on this node should run. These match the UAPI ++ * scheduler policy values, eg: ++ * 00b: SCHED_NORMAL ++ * 01b: SCHED_FIFO ++ * 10b: SCHED_RR ++ * 11b: SCHED_BATCH ++ */ ++ FLAT_BINDER_FLAG_SCHED_POLICY_MASK = ++ 3U << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT, ++ ++ /** ++ * @FLAT_BINDER_FLAG_INHERIT_RT: whether the node inherits RT policy ++ * ++ * Only when set, calls into this node will inherit a real-time ++ * scheduling policy from the caller (for synchronous transactions). ++ */ ++ FLAT_BINDER_FLAG_INHERIT_RT = 0x800, ++ + /** + * @FLAT_BINDER_FLAG_TXN_SECURITY_CTX: request security contexts + * +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch b/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch new file mode 100644 index 000000000000..5df92e79c6c4 --- /dev/null +++ b/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch @@ -0,0 +1,72 @@ +From dbb653c4e2acb8205d230506edaa89c311205303 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Mon, 8 Jul 2019 22:21:06 +0100 +Subject: ANDROID: build configs: switch prebuilt path location + +Move to a kernel specific prebuilt path. + +Bug: 135922132 +Change-Id: I8755f8f0154eecc86ad598be7a7811e9d8f068ed +Signed-off-by: Matthias Maennich +--- + build.config.cuttlefish.aarch64 | 2 +- + build.config.cuttlefish.x86_64 | 2 +- + build.config.gki.aarch64 | 2 +- + build.config.gki.x86_64 | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index 40c8d7a5219cc..b9115335e3fc1 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -8,7 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 ++BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index c9496b0d2ce6a..bdcbecea3ce11 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -8,7 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 ++BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 +index fce42ab0daa34..b2399812513ef 100644 +--- a/build.config.gki.aarch64 ++++ b/build.config.gki.aarch64 +@@ -8,7 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 ++BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 +index 3ce45e962732b..b5a7f46001017 100644 +--- a/build.config.gki.x86_64 ++++ b/build.config.gki.x86_64 +@@ -8,7 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 ++BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpu.patch b/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpu.patch new file mode 100644 index 000000000000..e12039dc4e8e --- /dev/null +++ b/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpu.patch @@ -0,0 +1,45 @@ +From a927064ed74a75193e0990bbce7b9f3b777cd94b Mon Sep 17 00:00:00 2001 +From: Thierry Strudel +Date: Tue, 14 Jun 2016 17:46:44 -0700 +Subject: ANDROID: cpu: send KOBJ_ONLINE event when enabling + cpus + +In case some sysfs nodes needs to be labeled with a different label than +sysfs then user needs to be notified when a core is brought back online. + +Bug: 29359497 +Bug: 120444461 +Change-Id: I0395c86e01cd49c348fda8f93087d26f88557c91 +Signed-off-by: Thierry Strudel +--- + kernel/cpu.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index e84c0873559ed..517da586013fe 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1266,6 +1266,7 @@ void __weak arch_enable_nonboot_cpus_end(void) + void enable_nonboot_cpus(void) + { + int cpu, error; ++ struct device *cpu_device; + + /* Allow everyone to use the CPU hotplug again */ + cpu_maps_update_begin(); +@@ -1283,6 +1284,12 @@ void enable_nonboot_cpus(void) + trace_suspend_resume(TPS("CPU_ON"), cpu, false); + if (!error) { + pr_info("CPU%d is up\n", cpu); ++ cpu_device = get_cpu_device(cpu); ++ if (!cpu_device) ++ pr_err("%s: failed to get cpu%d device\n", ++ __func__, cpu); ++ else ++ kobject_uevent(&cpu_device->kobj, KOBJ_ONLINE); + continue; + } + pr_warn("Error taking CPU%d up: %d\n", cpu, error); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-direct.patch b/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-direct.patch new file mode 100644 index 000000000000..18c6be985def --- /dev/null +++ b/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-direct.patch @@ -0,0 +1,143 @@ +From 569e63e00af55d9f96cf0a32a8c4b10c21439480 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Mon, 22 Jan 2018 18:28:08 -0800 +Subject: ANDROID: cpufreq: Add time_in_state to /proc/uid + directories + +Add per-uid files that report the data in binary format rather than +text, to allow faster reading & parsing by userspace. + +Signed-off-by: Connor O'Brien +Bug: 72339335 +Bug: 127641090 +Test: compare values to those reported in /proc/uid_time_in_state +Change-Id: I463039ea7f17b842be4c70024fe772539fe2ce02 +--- + drivers/cpufreq/cpufreq_times.c | 49 +++++++++++++++++++++++++++++++++ + fs/proc/uid.c | 16 ++++++++++- + include/linux/cpufreq_times.h | 1 + + 3 files changed, 65 insertions(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index 15b52e1f82fc6..a43eeee30e8e1 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -58,6 +58,19 @@ static struct cpu_freqs *all_freqs[NR_CPUS]; + + static unsigned int next_offset; + ++ ++/* Caller must hold rcu_read_lock() */ ++static struct uid_entry *find_uid_entry_rcu(uid_t uid) ++{ ++ struct uid_entry *uid_entry; ++ ++ hash_for_each_possible_rcu(uid_hash_table, uid_entry, hash, uid) { ++ if (uid_entry->uid == uid) ++ return uid_entry; ++ } ++ return NULL; ++} ++ + /* Caller must hold uid lock */ + static struct uid_entry *find_uid_entry_locked(uid_t uid) + { +@@ -127,6 +140,36 @@ static bool freq_index_invalid(unsigned int index) + return true; + } + ++static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) ++{ ++ struct uid_entry *uid_entry; ++ unsigned int i; ++ u64 time; ++ uid_t uid = from_kuid_munged(current_user_ns(), *(kuid_t *)m->private); ++ ++ if (uid == overflowuid) ++ return -EINVAL; ++ ++ rcu_read_lock(); ++ ++ uid_entry = find_uid_entry_rcu(uid); ++ if (!uid_entry) { ++ rcu_read_unlock(); ++ return 0; ++ } ++ ++ for (i = 0; i < uid_entry->max_state; ++i) { ++ if (freq_index_invalid(i)) ++ continue; ++ time = nsec_to_clock_t(uid_entry->time_in_state[i]); ++ seq_write(m, &time, sizeof(time)); ++ } ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ + static void *uid_seq_start(struct seq_file *seq, loff_t *pos) + { + if (*pos >= HASH_SIZE(uid_hash_table)) +@@ -397,6 +440,12 @@ static int uid_time_in_state_open(struct inode *inode, struct file *file) + return seq_open(file, &uid_time_in_state_seq_ops); + } + ++int single_uid_time_in_state_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, single_uid_time_in_state_show, ++ &(inode->i_uid)); ++} ++ + static const struct file_operations uid_time_in_state_fops = { + .open = uid_time_in_state_open, + .read = seq_read, +diff --git a/fs/proc/uid.c b/fs/proc/uid.c +index ae720b93a0ed2..311717ea199ab 100644 +--- a/fs/proc/uid.c ++++ b/fs/proc/uid.c +@@ -2,6 +2,7 @@ + * /proc/uid support + */ + ++#include + #include + #include + #include +@@ -82,7 +83,20 @@ struct uid_entry { + .fop = FOP, \ + } + +-static const struct uid_entry uid_base_stuff[] = {}; ++#ifdef CONFIG_CPU_FREQ_TIMES ++static const struct file_operations proc_uid_time_in_state_operations = { ++ .open = single_uid_time_in_state_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++#endif ++ ++static const struct uid_entry uid_base_stuff[] = { ++#ifdef CONFIG_CPU_FREQ_TIMES ++ NOD("time_in_state", 0444, NULL, &proc_uid_time_in_state_operations), ++#endif ++}; + + static const struct inode_operations proc_uid_def_inode_operations = { + .setattr = proc_setattr, +diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h +index a03157f649a4f..757bf0cb60704 100644 +--- a/include/linux/cpufreq_times.h ++++ b/include/linux/cpufreq_times.h +@@ -29,6 +29,7 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); + void cpufreq_times_create_policy(struct cpufreq_policy *policy); + void cpufreq_times_record_transition(struct cpufreq_freqs *freq); + void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); ++int single_uid_time_in_state_open(struct inode *inode, struct file *file); + #else + static inline void cpufreq_task_times_init(struct task_struct *p) {} + static inline void cpufreq_task_times_alloc(struct task_struct *p) {} +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-arch_topology-implement-max-frequenc.patch b/patches/ANDROID-cpufreq-arch_topology-implement-max-frequenc.patch new file mode 100644 index 000000000000..720c4b4d5473 --- /dev/null +++ b/patches/ANDROID-cpufreq-arch_topology-implement-max-frequenc.patch @@ -0,0 +1,139 @@ +From 0cfe39fe403ea6dbe2fdfb38edd36022b35d4d66 Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann +Date: Thu, 10 May 2018 16:52:33 +0100 +Subject: ANDROID: cpufreq: arch_topology: implement max + frequency capping + +Implements the Max Frequency Capping Engine (MFCE) getter function +topology_get_max_freq_scale() to provide the scheduler with a +maximum frequency scaling correction factor for more accurate cpu +capacity handling by being able to deal with max frequency capping. + +This scaling factor describes the influence of running a cpu with a +current maximum frequency (policy) lower than the maximum possible +frequency (cpuinfo). + +The factor is: + + policy_max_freq(cpu) << SCHED_CAPACITY_SHIFT / cpuinfo_max_freq(cpu) + +It also implements the MFCE setter function arch_set_max_freq_scale() +which is called from cpufreq_set_policy(). + +Change-Id: I59e52861ee260755ab0518fe1f7183a2e4e3d0fc +Signed-off-by: Ionela Voinescu +Signed-off-by: Dietmar Eggemann +[Trivial cherry-pick issue in cpufreq.c] +Signed-off-by: Quentin Perret +--- + drivers/base/arch_topology.c | 25 ++++++++++++++++++++++++- + drivers/cpufreq/cpufreq.c | 8 ++++++++ + include/linux/arch_topology.h | 8 ++++++++ + include/linux/cpufreq.h | 2 ++ + 4 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c +index 1eb81f113786..c0cf9ef5c2f5 100644 +--- a/drivers/base/arch_topology.c ++++ b/drivers/base/arch_topology.c +@@ -22,6 +22,8 @@ + #include + + DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE; ++DEFINE_PER_CPU(unsigned long, max_cpu_freq); ++DEFINE_PER_CPU(unsigned long, max_freq_scale) = SCHED_CAPACITY_SCALE; + + void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + unsigned long max_freq) +@@ -31,8 +33,29 @@ void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + + scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq; + +- for_each_cpu(i, cpus) ++ for_each_cpu(i, cpus) { + per_cpu(freq_scale, i) = scale; ++ per_cpu(max_cpu_freq, i) = max_freq; ++ } ++} ++ ++void arch_set_max_freq_scale(struct cpumask *cpus, ++ unsigned long policy_max_freq) ++{ ++ unsigned long scale, max_freq; ++ int cpu = cpumask_first(cpus); ++ ++ if (cpu > nr_cpu_ids) ++ return; ++ ++ max_freq = per_cpu(max_cpu_freq, cpu); ++ if (!max_freq) ++ return; ++ ++ scale = (policy_max_freq << SCHED_CAPACITY_SHIFT) / max_freq; ++ ++ for_each_cpu(cpu, cpus) ++ per_cpu(max_freq_scale, cpu) = scale; + } + + DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index c52d6fa32aac..cf118aa0a83e 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -152,6 +152,12 @@ __weak void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + } + EXPORT_SYMBOL_GPL(arch_set_freq_scale); + ++__weak void arch_set_max_freq_scale(struct cpumask *cpus, ++ unsigned long policy_max_freq) ++{ ++} ++EXPORT_SYMBOL_GPL(arch_set_max_freq_scale); ++ + /* + * This is a generic cpufreq init() routine which can be used by cpufreq + * drivers of SMP systems. It will do following: +@@ -2398,6 +2404,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, + policy->max = new_policy->max; + trace_cpu_frequency_limits(policy); + ++ arch_set_max_freq_scale(policy->cpus, policy->max); ++ + policy->cached_target_freq = UINT_MAX; + + pr_debug("new min and max freqs are %u - %u kHz\n", +diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h +index 42f2b5126094..5402bc0e2b1e 100644 +--- a/include/linux/arch_topology.h ++++ b/include/linux/arch_topology.h +@@ -33,6 +33,14 @@ unsigned long topology_get_freq_scale(int cpu) + return per_cpu(freq_scale, cpu); + } + ++DECLARE_PER_CPU(unsigned long, max_freq_scale); ++ ++static inline ++unsigned long topology_get_max_freq_scale(struct sched_domain *sd, int cpu) ++{ ++ return per_cpu(max_freq_scale, cpu); ++} ++ + struct cpu_topology { + int thread_id; + int core_id; +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index c57e88e85c41..fca45a2749d4 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -984,6 +984,8 @@ extern unsigned int arch_freq_get_on_cpu(int cpu); + + extern void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + unsigned long max_freq); ++extern void arch_set_max_freq_scale(struct cpumask *cpus, ++ unsigned long policy_max_freq); + + /* the following are really really optional */ + extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-activ.patch b/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-activ.patch new file mode 100644 index 000000000000..027147183948 --- /dev/null +++ b/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-activ.patch @@ -0,0 +1,343 @@ +From d3266405f31f52159b55db03097131a6a201c041 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Fri, 5 Oct 2018 19:20:54 -0700 +Subject: ANDROID: cpufreq: times: add + /proc/uid_concurrent_{active,policy}_time + +In order to model the energy used by the cpu, we need to expose cpu +time information to userspace. We can use this information to blame +uids for the energy they are using. + +This patch adds 2 files: + +/proc/uid_concurrent_active_time outputs the time each uid spent +running with 1 to num_possible_cpus online and not idle. + +For instance, if 4 cores are online and active for 50ms and the uid is +running on one of the cores, the uid should be blamed for 1/4 of the +base energy used by the cpu when 1 or more cores is active. + +/proc/uid_concurrent_policy_time outputs the time each uid spent +running on group of cpu's with the same policy with 1 to +num_related_cpus online and not idle. + +For instance, if 2 cores that are a part of the same policy are online +and active for 50ms and the uid is running on one of the cores, the +uid should be blamed for 1/2 of the energy that is used everytime one +or more cpus in the same policy is active. + +This patch is based on commit c89e69136fec ("ANDROID: cpufreq: +uid_concurrent_active_time") and commit 989212536842 ("ANDROID: +cpufreq: uid_concurrent_policy_time") in the android-msm-wahoo-4.4 +kernel by Marissa Wall. + +Bug: 111216804 +Bug: 127641090 +Test: cat files on hikey960 and confirm output is reasonable +Change-Id: I1a342361af5c04ecee58d1ab667c91c1bce42445 +Signed-off-by: Connor O'Brien +--- + .../ABI/testing/procfs-concurrent_time | 16 ++ + drivers/cpufreq/cpufreq_times.c | 190 +++++++++++++++++- + 2 files changed, 204 insertions(+), 2 deletions(-) + create mode 100644 Documentation/ABI/testing/procfs-concurrent_time + +diff --git a/Documentation/ABI/testing/procfs-concurrent_time b/Documentation/ABI/testing/procfs-concurrent_time +new file mode 100644 +index 0000000000000..55b414289b406 +--- /dev/null ++++ b/Documentation/ABI/testing/procfs-concurrent_time +@@ -0,0 +1,16 @@ ++What: /proc/uid_concurrent_active_time ++Date: December 2018 ++Contact: Connor O'Brien ++Description: ++ The /proc/uid_concurrent_active_time file displays aggregated cputime ++ numbers for each uid, broken down by the total number of cores that were ++ active while the uid's task was running. ++ ++What: /proc/uid_concurrent_policy_time ++Date: December 2018 ++Contact: Connor O'Brien ++Description: ++ The /proc/uid_concurrent_policy_time file displays aggregated cputime ++ numbers for each uid, broken down based on the cpufreq policy ++ of the core used by the uid's task and the number of cores associated ++ with that policy that were active while the uid's task was running. +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index a43eeee30e8e1..aaded60c9a21c 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -32,11 +32,17 @@ static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); + static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ + static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */ + ++struct concurrent_times { ++ atomic64_t active[NR_CPUS]; ++ atomic64_t policy[NR_CPUS]; ++}; ++ + struct uid_entry { + uid_t uid; + unsigned int max_state; + struct hlist_node hash; + struct rcu_head rcu; ++ struct concurrent_times *concurrent_times; + u64 time_in_state[0]; + }; + +@@ -87,6 +93,7 @@ static struct uid_entry *find_uid_entry_locked(uid_t uid) + static struct uid_entry *find_or_register_uid_locked(uid_t uid) + { + struct uid_entry *uid_entry, *temp; ++ struct concurrent_times *times; + unsigned int max_state = READ_ONCE(next_offset); + size_t alloc_size = sizeof(*uid_entry) + max_state * + sizeof(uid_entry->time_in_state[0]); +@@ -115,9 +122,15 @@ static struct uid_entry *find_or_register_uid_locked(uid_t uid) + uid_entry = kzalloc(alloc_size, GFP_ATOMIC); + if (!uid_entry) + return NULL; ++ times = kzalloc(sizeof(*times), GFP_ATOMIC); ++ if (!times) { ++ kfree(uid_entry); ++ return NULL; ++ } + + uid_entry->uid = uid; + uid_entry->max_state = max_state; ++ uid_entry->concurrent_times = times; + + hash_add_rcu(uid_hash_table, &uid_entry->hash, uid); + +@@ -232,6 +245,86 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) + return 0; + } + ++static int concurrent_time_seq_show(struct seq_file *m, void *v, ++ atomic64_t *(*get_times)(struct concurrent_times *)) ++{ ++ struct uid_entry *uid_entry; ++ int i, num_possible_cpus = num_possible_cpus(); ++ ++ rcu_read_lock(); ++ ++ hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { ++ atomic64_t *times = get_times(uid_entry->concurrent_times); ++ ++ seq_put_decimal_ull(m, "", (u64)uid_entry->uid); ++ seq_putc(m, ':'); ++ ++ for (i = 0; i < num_possible_cpus; ++i) { ++ u64 time = nsec_to_clock_t(atomic64_read(×[i])); ++ ++ seq_put_decimal_ull(m, " ", time); ++ } ++ seq_putc(m, '\n'); ++ } ++ ++ rcu_read_unlock(); ++ ++ return 0; ++} ++ ++static inline atomic64_t *get_active_times(struct concurrent_times *times) ++{ ++ return times->active; ++} ++ ++static int concurrent_active_time_seq_show(struct seq_file *m, void *v) ++{ ++ if (v == uid_hash_table) { ++ seq_put_decimal_ull(m, "cpus: ", num_possible_cpus()); ++ seq_putc(m, '\n'); ++ } ++ ++ return concurrent_time_seq_show(m, v, get_active_times); ++} ++ ++static inline atomic64_t *get_policy_times(struct concurrent_times *times) ++{ ++ return times->policy; ++} ++ ++static int concurrent_policy_time_seq_show(struct seq_file *m, void *v) ++{ ++ int i; ++ struct cpu_freqs *freqs, *last_freqs = NULL; ++ ++ if (v == uid_hash_table) { ++ int cnt = 0; ++ ++ for_each_possible_cpu(i) { ++ freqs = all_freqs[i]; ++ if (!freqs) ++ continue; ++ if (freqs != last_freqs) { ++ if (last_freqs) { ++ seq_put_decimal_ull(m, ": ", cnt); ++ seq_putc(m, ' '); ++ cnt = 0; ++ } ++ seq_put_decimal_ull(m, "policy", i); ++ ++ last_freqs = freqs; ++ } ++ cnt++; ++ } ++ if (last_freqs) { ++ seq_put_decimal_ull(m, ": ", cnt); ++ seq_putc(m, '\n'); ++ } ++ } ++ ++ return concurrent_time_seq_show(m, v, get_policy_times); ++} ++ + void cpufreq_task_times_init(struct task_struct *p) + { + unsigned long flags; +@@ -326,11 +419,16 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) + { + unsigned long flags; + unsigned int state; ++ unsigned int active_cpu_cnt = 0; ++ unsigned int policy_cpu_cnt = 0; ++ unsigned int policy_first_cpu; + struct uid_entry *uid_entry; + struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; ++ struct cpufreq_policy *policy; + uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p)); ++ int cpu = 0; + +- if (!freqs || p->flags & PF_EXITING) ++ if (!freqs || is_idle_task(p) || p->flags & PF_EXITING) + return; + + state = freqs->offset + READ_ONCE(freqs->last_index); +@@ -346,6 +444,42 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) + if (uid_entry && state < uid_entry->max_state) + uid_entry->time_in_state[state] += cputime; + spin_unlock_irqrestore(&uid_lock, flags); ++ ++ rcu_read_lock(); ++ uid_entry = find_uid_entry_rcu(uid); ++ if (!uid_entry) { ++ rcu_read_unlock(); ++ return; ++ } ++ ++ for_each_possible_cpu(cpu) ++ if (!idle_cpu(cpu)) ++ ++active_cpu_cnt; ++ ++ atomic64_add(cputime, ++ &uid_entry->concurrent_times->active[active_cpu_cnt - 1]); ++ ++ policy = cpufreq_cpu_get(task_cpu(p)); ++ if (!policy) { ++ /* ++ * This CPU may have just come up and not have a cpufreq policy ++ * yet. ++ */ ++ rcu_read_unlock(); ++ return; ++ } ++ ++ for_each_cpu(cpu, policy->related_cpus) ++ if (!idle_cpu(cpu)) ++ ++policy_cpu_cnt; ++ ++ policy_first_cpu = cpumask_first(policy->related_cpus); ++ cpufreq_cpu_put(policy); ++ ++ atomic64_add(cputime, ++ &uid_entry->concurrent_times->policy[policy_first_cpu + ++ policy_cpu_cnt - 1]); ++ rcu_read_unlock(); + } + + void cpufreq_times_create_policy(struct cpufreq_policy *policy) +@@ -387,6 +521,14 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) + all_freqs[cpu] = freqs; + } + ++static void uid_entry_reclaim(struct rcu_head *rcu) ++{ ++ struct uid_entry *uid_entry = container_of(rcu, struct uid_entry, rcu); ++ ++ kfree(uid_entry->concurrent_times); ++ kfree(uid_entry); ++} ++ + void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) + { + struct uid_entry *uid_entry; +@@ -400,7 +542,7 @@ void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) + hash, uid_start) { + if (uid_start == uid_entry->uid) { + hash_del_rcu(&uid_entry->hash); +- kfree_rcu(uid_entry, rcu); ++ call_rcu(&uid_entry->rcu, uid_entry_reclaim); + } + } + } +@@ -453,11 +595,55 @@ static const struct file_operations uid_time_in_state_fops = { + .release = seq_release, + }; + ++static const struct seq_operations concurrent_active_time_seq_ops = { ++ .start = uid_seq_start, ++ .next = uid_seq_next, ++ .stop = uid_seq_stop, ++ .show = concurrent_active_time_seq_show, ++}; ++ ++static int concurrent_active_time_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &concurrent_active_time_seq_ops); ++} ++ ++static const struct file_operations concurrent_active_time_fops = { ++ .open = concurrent_active_time_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++}; ++ ++static const struct seq_operations concurrent_policy_time_seq_ops = { ++ .start = uid_seq_start, ++ .next = uid_seq_next, ++ .stop = uid_seq_stop, ++ .show = concurrent_policy_time_seq_show, ++}; ++ ++static int concurrent_policy_time_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &concurrent_policy_time_seq_ops); ++} ++ ++static const struct file_operations concurrent_policy_time_fops = { ++ .open = concurrent_policy_time_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++}; ++ + static int __init cpufreq_times_init(void) + { + proc_create_data("uid_time_in_state", 0444, NULL, + &uid_time_in_state_fops, NULL); + ++ proc_create_data("uid_concurrent_active_time", 0444, NULL, ++ &concurrent_active_time_fops, NULL); ++ ++ proc_create_data("uid_concurrent_policy_time", 0444, NULL, ++ &concurrent_policy_time_fops, NULL); ++ + return 0; + } + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-.patch b/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-.patch new file mode 100644 index 000000000000..13448eb77679 --- /dev/null +++ b/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-.patch @@ -0,0 +1,155 @@ +From ad7e0a2419f3f4c589d39a53b04720c9cd1ef5ae Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Fri, 1 Mar 2019 15:40:30 -0800 +Subject: ANDROID: cpufreq: times: don't copy invalid freqs + from freq table + +Invalid frequency checks are a bottleneck in reading +/proc/uid_time_in_state, but there's no reason to include invalid +frequencies in our local copies of frequency tables. Revise +cpufreq_times_create_policy() to only copy valid frequencies, and +eliminate all the checks this change makes unnecessary. + +Bug: 111216804 +Test: cat /proc/uid_time_in_state & confirm values & format are sane +Test: /proc/uid_time_in_state read times reduced by ~40% +Change-Id: I506420a6ac5fe8a6c87d01b16ad267b192d43f1d +Signed-off-by: Connor O'Brien +--- + drivers/cpufreq/cpufreq_times.c | 55 ++++++++++++--------------------- + 1 file changed, 19 insertions(+), 36 deletions(-) + +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index 2883d675b1eb7..5b5248a7c87c4 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -137,27 +137,10 @@ static struct uid_entry *find_or_register_uid_locked(uid_t uid) + return uid_entry; + } + +-static bool freq_index_invalid(unsigned int index) +-{ +- unsigned int cpu; +- struct cpu_freqs *freqs; +- +- for_each_possible_cpu(cpu) { +- freqs = all_freqs[cpu]; +- if (!freqs || index < freqs->offset || +- freqs->offset + freqs->max_state <= index) +- continue; +- return freqs->freq_table[index - freqs->offset] == +- CPUFREQ_ENTRY_INVALID; +- } +- return true; +-} +- + static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) + { + struct uid_entry *uid_entry; + unsigned int i; +- u64 time; + uid_t uid = from_kuid_munged(current_user_ns(), *(kuid_t *)m->private); + + if (uid == overflowuid) +@@ -172,9 +155,7 @@ static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) + } + + for (i = 0; i < uid_entry->max_state; ++i) { +- if (freq_index_invalid(i)) +- continue; +- time = nsec_to_clock_t(uid_entry->time_in_state[i]); ++ u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]); + seq_write(m, &time, sizeof(time)); + } + +@@ -219,9 +200,6 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) + continue; + last_freqs = freqs; + for (i = 0; i < freqs->max_state; i++) { +- if (freqs->freq_table[i] == +- CPUFREQ_ENTRY_INVALID) +- continue; + seq_put_decimal_ull(m, " ", + freqs->freq_table[i]); + } +@@ -237,10 +215,7 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) + seq_putc(m, ':'); + } + for (i = 0; i < uid_entry->max_state; ++i) { +- u64 time; +- if (freq_index_invalid(i)) +- continue; +- time = nsec_to_clock_t(uid_entry->time_in_state[i]); ++ u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]); + seq_put_decimal_ull(m, " ", time); + } + if (uid_entry->max_state) +@@ -407,8 +382,6 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, + + seq_printf(m, "cpu%u\n", cpu); + for (i = 0; i < freqs->max_state; i++) { +- if (freqs->freq_table[i] == CPUFREQ_ENTRY_INVALID) +- continue; + cputime = 0; + if (freqs->offset + i < p->max_state && + p->time_in_state) +@@ -488,9 +461,19 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) + rcu_read_unlock(); + } + ++static int cpufreq_times_get_index(struct cpu_freqs *freqs, unsigned int freq) ++{ ++ int index; ++ for (index = 0; index < freqs->max_state; ++index) { ++ if (freqs->freq_table[index] == freq) ++ return index; ++ } ++ return -1; ++} ++ + void cpufreq_times_create_policy(struct cpufreq_policy *policy) + { +- int cpu, index; ++ int cpu, index = 0; + unsigned int count = 0; + struct cpufreq_frequency_table *pos, *table; + struct cpu_freqs *freqs; +@@ -503,7 +486,7 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) + if (!table) + return; + +- cpufreq_for_each_entry(pos, table) ++ cpufreq_for_each_valid_entry(pos, table) + count++; + + tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count, +@@ -514,13 +497,13 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) + freqs = tmp; + freqs->max_state = count; + +- index = cpufreq_frequency_table_get_index(policy, policy->cur); ++ cpufreq_for_each_valid_entry(pos, table) ++ freqs->freq_table[index++] = pos->frequency; ++ ++ index = cpufreq_times_get_index(freqs, policy->cur); + if (index >= 0) + WRITE_ONCE(freqs->last_index, index); + +- cpufreq_for_each_entry(pos, table) +- freqs->freq_table[pos - table] = pos->frequency; +- + freqs->offset = next_offset; + WRITE_ONCE(next_offset, freqs->offset + count); + for_each_cpu(cpu, policy->related_cpus) +@@ -564,7 +547,7 @@ void cpufreq_times_record_transition(struct cpufreq_policy *policy, + if (!freqs) + return; + +- index = cpufreq_frequency_table_get_index(policy, new_freq); ++ index = cpufreq_times_get_index(freqs, new_freq); + if (index >= 0) + WRITE_ONCE(freqs->last_index, index); + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-times-optimize-proc-files.patch b/patches/ANDROID-cpufreq-times-optimize-proc-files.patch new file mode 100644 index 000000000000..b0f17ea1b25a --- /dev/null +++ b/patches/ANDROID-cpufreq-times-optimize-proc-files.patch @@ -0,0 +1,75 @@ +From 7a7f965f733e896d06d2d3151bdea372551178b5 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Wed, 20 Feb 2019 12:17:48 -0800 +Subject: ANDROID: cpufreq: times: optimize proc files + +The majority of the time spent reading /proc/uid_time_in_state is due +to seq_printf calls. Use the faster seq_put_* variations instead. + +Also skip empty hash buckets in uid_seq_next for a further performance +improvement. + +Bug: 111216804 +Bug: 127641090 +Test: Read /proc/uid_time_in_state and confirm output is sane +Test: Compare read times to confirm performance improvement +Change-Id: If8783b498ed73d2ddb186a49438af41ac5ab9957 +Signed-off-by: Connor O'Brien +--- + drivers/cpufreq/cpufreq_times.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index 42420c5e1e6fc..2883d675b1eb7 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -193,10 +193,12 @@ static void *uid_seq_start(struct seq_file *seq, loff_t *pos) + + static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { +- (*pos)++; ++ do { ++ (*pos)++; + +- if (*pos >= HASH_SIZE(uid_hash_table)) +- return NULL; ++ if (*pos >= HASH_SIZE(uid_hash_table)) ++ return NULL; ++ } while (hlist_empty(&uid_hash_table[*pos])); + + return &uid_hash_table[*pos]; + } +@@ -220,7 +222,8 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) + if (freqs->freq_table[i] == + CPUFREQ_ENTRY_INVALID) + continue; +- seq_printf(m, " %d", freqs->freq_table[i]); ++ seq_put_decimal_ull(m, " ", ++ freqs->freq_table[i]); + } + } + seq_putc(m, '\n'); +@@ -229,13 +232,16 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) + rcu_read_lock(); + + hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { +- if (uid_entry->max_state) +- seq_printf(m, "%d:", uid_entry->uid); ++ if (uid_entry->max_state) { ++ seq_put_decimal_ull(m, "", uid_entry->uid); ++ seq_putc(m, ':'); ++ } + for (i = 0; i < uid_entry->max_state; ++i) { ++ u64 time; + if (freq_index_invalid(i)) + continue; +- seq_printf(m, " %lu", (unsigned long)nsec_to_clock_t( +- uid_entry->time_in_state[i])); ++ time = nsec_to_clock_t(uid_entry->time_in_state[i]); ++ seq_put_decimal_ull(m, " ", time); + } + if (uid_entry->max_state) + seq_putc(m, '\n'); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-t.patch b/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-t.patch new file mode 100644 index 000000000000..f3d2004c1604 --- /dev/null +++ b/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-t.patch @@ -0,0 +1,115 @@ +From dbf9a52e7afcf85ed8344a2db63172cd05940c43 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Fri, 8 Feb 2019 12:30:41 -0800 +Subject: ANDROID: cpufreq: times: record fast switch frequency + transitions + +cpufreq_times_record_transition() is not called when fast switch is +enabled, leading /proc/uid_time_in_state to attribute all time on a +cluster to a single frequency. To fix this, add a call to +cpufreq_times_record_transition() in the fast switch path. + +Also revise cpufreq_times_record_transition() to simplify the new call +and more closely align with cpufreq_stats_record_transition(). + +Bug: 121287027 +Bug: 127641090 +Test: /proc/uid_time_in_state shows times for more than one freq per +cluster +Change-Id: Ib63d19006878fafb88475e401ef243bdd8b11979 +Signed-off-by: Connor O'Brien +--- + drivers/cpufreq/cpufreq.c | 10 ++++++++-- + drivers/cpufreq/cpufreq_times.c | 15 ++++----------- + include/linux/cpufreq_times.h | 5 +++-- + 3 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index e1cb6e99c76df..642fc08b6c821 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -380,7 +380,7 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy, + CPUFREQ_POSTCHANGE, freqs); + + cpufreq_stats_record_transition(policy, freqs->new); +- cpufreq_times_record_transition(freqs); ++ cpufreq_times_record_transition(policy, freqs->new); + policy->cur = freqs->new; + } + } +@@ -2010,9 +2010,15 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); + unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) + { ++ int ret; ++ + target_freq = clamp_val(target_freq, policy->min, policy->max); + +- return cpufreq_driver->fast_switch(policy, target_freq); ++ ret = cpufreq_driver->fast_switch(policy, target_freq); ++ if (ret) ++ cpufreq_times_record_transition(policy, ret); ++ ++ return ret; + } + EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch); + +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index aaded60c9a21c..42420c5e1e6fc 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -550,24 +550,17 @@ void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) + spin_unlock_irqrestore(&uid_lock, flags); + } + +-void cpufreq_times_record_transition(struct cpufreq_freqs *freq) ++void cpufreq_times_record_transition(struct cpufreq_policy *policy, ++ unsigned int new_freq) + { + int index; +- struct cpu_freqs *freqs = all_freqs[freq->cpu]; +- struct cpufreq_policy *policy; +- ++ struct cpu_freqs *freqs = all_freqs[policy->cpu]; + if (!freqs) + return; + +- policy = cpufreq_cpu_get(freq->cpu); +- if (!policy) +- return; +- +- index = cpufreq_frequency_table_get_index(policy, freq->new); ++ index = cpufreq_frequency_table_get_index(policy, new_freq); + if (index >= 0) + WRITE_ONCE(freqs->last_index, index); +- +- cpufreq_cpu_put(policy); + } + + static const struct seq_operations uid_time_in_state_seq_ops = { +diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h +index 757bf0cb60704..0eb6dc9d0fe29 100644 +--- a/include/linux/cpufreq_times.h ++++ b/include/linux/cpufreq_times.h +@@ -27,7 +27,8 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *p); + void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); + void cpufreq_times_create_policy(struct cpufreq_policy *policy); +-void cpufreq_times_record_transition(struct cpufreq_freqs *freq); ++void cpufreq_times_record_transition(struct cpufreq_policy *policy, ++ unsigned int new_freq); + void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); + int single_uid_time_in_state_open(struct inode *inode, struct file *file); + #else +@@ -38,7 +39,7 @@ static inline void cpufreq_acct_update_power(struct task_struct *p, + u64 cputime) {} + static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} + static inline void cpufreq_times_record_transition( +- struct cpufreq_freqs *freq) {} ++ struct cpufreq_policy *policy, unsigned int new_freq) {} + static inline void cpufreq_task_times_remove_uids(uid_t uid_start, + uid_t uid_end) {} + #endif /* CONFIG_CPU_FREQ_TIMES */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch b/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch new file mode 100644 index 000000000000..de3bdc436873 --- /dev/null +++ b/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch @@ -0,0 +1,331 @@ +From 1ec486602e746651cb113cb6ae53df02a7c80031 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Tue, 6 Feb 2018 13:30:27 -0800 +Subject: ANDROID: cpufreq: times: track per-uid time in state + +Add /proc/uid_time_in_state showing per uid/frequency/cluster +times. Allow uid removal through /proc/uid_cputime/remove_uid_range. + +Signed-off-by: Connor O'Brien +Bug: 72339335 +Bug: 127641090 +Test: Read /proc/uid_time_in_state +Change-Id: I20ba3546a27c25b7e7991e2a86986e158aafa58c +--- + drivers/cpufreq/cpufreq_times.c | 208 ++++++++++++++++++++++++++++++++ + drivers/misc/uid_sys_stats.c | 4 + + include/linux/cpufreq_times.h | 3 + + 3 files changed, 215 insertions(+) + +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +index 339a3e9cf0821..15b52e1f82fc6 100644 +--- a/drivers/cpufreq/cpufreq_times.c ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -15,14 +15,30 @@ + + #include + #include ++#include ++#include + #include ++#include + #include + #include + #include + #include + #include + ++#define UID_HASH_BITS 10 ++ ++static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); ++ + static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ ++static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */ ++ ++struct uid_entry { ++ uid_t uid; ++ unsigned int max_state; ++ struct hlist_node hash; ++ struct rcu_head rcu; ++ u64 time_in_state[0]; ++}; + + /** + * struct cpu_freqs - per-cpu frequency information +@@ -42,6 +58,137 @@ static struct cpu_freqs *all_freqs[NR_CPUS]; + + static unsigned int next_offset; + ++/* Caller must hold uid lock */ ++static struct uid_entry *find_uid_entry_locked(uid_t uid) ++{ ++ struct uid_entry *uid_entry; ++ ++ hash_for_each_possible(uid_hash_table, uid_entry, hash, uid) { ++ if (uid_entry->uid == uid) ++ return uid_entry; ++ } ++ return NULL; ++} ++ ++/* Caller must hold uid lock */ ++static struct uid_entry *find_or_register_uid_locked(uid_t uid) ++{ ++ struct uid_entry *uid_entry, *temp; ++ unsigned int max_state = READ_ONCE(next_offset); ++ size_t alloc_size = sizeof(*uid_entry) + max_state * ++ sizeof(uid_entry->time_in_state[0]); ++ ++ uid_entry = find_uid_entry_locked(uid); ++ if (uid_entry) { ++ if (uid_entry->max_state == max_state) ++ return uid_entry; ++ /* uid_entry->time_in_state is too small to track all freqs, so ++ * expand it. ++ */ ++ temp = __krealloc(uid_entry, alloc_size, GFP_ATOMIC); ++ if (!temp) ++ return uid_entry; ++ temp->max_state = max_state; ++ memset(temp->time_in_state + uid_entry->max_state, 0, ++ (max_state - uid_entry->max_state) * ++ sizeof(uid_entry->time_in_state[0])); ++ if (temp != uid_entry) { ++ hlist_replace_rcu(&uid_entry->hash, &temp->hash); ++ kfree_rcu(uid_entry, rcu); ++ } ++ return temp; ++ } ++ ++ uid_entry = kzalloc(alloc_size, GFP_ATOMIC); ++ if (!uid_entry) ++ return NULL; ++ ++ uid_entry->uid = uid; ++ uid_entry->max_state = max_state; ++ ++ hash_add_rcu(uid_hash_table, &uid_entry->hash, uid); ++ ++ return uid_entry; ++} ++ ++static bool freq_index_invalid(unsigned int index) ++{ ++ unsigned int cpu; ++ struct cpu_freqs *freqs; ++ ++ for_each_possible_cpu(cpu) { ++ freqs = all_freqs[cpu]; ++ if (!freqs || index < freqs->offset || ++ freqs->offset + freqs->max_state <= index) ++ continue; ++ return freqs->freq_table[index - freqs->offset] == ++ CPUFREQ_ENTRY_INVALID; ++ } ++ return true; ++} ++ ++static void *uid_seq_start(struct seq_file *seq, loff_t *pos) ++{ ++ if (*pos >= HASH_SIZE(uid_hash_table)) ++ return NULL; ++ ++ return &uid_hash_table[*pos]; ++} ++ ++static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) ++{ ++ (*pos)++; ++ ++ if (*pos >= HASH_SIZE(uid_hash_table)) ++ return NULL; ++ ++ return &uid_hash_table[*pos]; ++} ++ ++static void uid_seq_stop(struct seq_file *seq, void *v) { } ++ ++static int uid_time_in_state_seq_show(struct seq_file *m, void *v) ++{ ++ struct uid_entry *uid_entry; ++ struct cpu_freqs *freqs, *last_freqs = NULL; ++ int i, cpu; ++ ++ if (v == uid_hash_table) { ++ seq_puts(m, "uid:"); ++ for_each_possible_cpu(cpu) { ++ freqs = all_freqs[cpu]; ++ if (!freqs || freqs == last_freqs) ++ continue; ++ last_freqs = freqs; ++ for (i = 0; i < freqs->max_state; i++) { ++ if (freqs->freq_table[i] == ++ CPUFREQ_ENTRY_INVALID) ++ continue; ++ seq_printf(m, " %d", freqs->freq_table[i]); ++ } ++ } ++ seq_putc(m, '\n'); ++ } ++ ++ rcu_read_lock(); ++ ++ hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { ++ if (uid_entry->max_state) ++ seq_printf(m, "%d:", uid_entry->uid); ++ for (i = 0; i < uid_entry->max_state; ++i) { ++ if (freq_index_invalid(i)) ++ continue; ++ seq_printf(m, " %lu", (unsigned long)nsec_to_clock_t( ++ uid_entry->time_in_state[i])); ++ } ++ if (uid_entry->max_state) ++ seq_putc(m, '\n'); ++ } ++ ++ rcu_read_unlock(); ++ return 0; ++} ++ + void cpufreq_task_times_init(struct task_struct *p) + { + unsigned long flags; +@@ -90,6 +237,9 @@ void cpufreq_task_times_exit(struct task_struct *p) + unsigned long flags; + void *temp; + ++ if (!p->time_in_state) ++ return; ++ + spin_lock_irqsave(&task_time_in_state_lock, flags); + temp = p->time_in_state; + p->time_in_state = NULL; +@@ -133,7 +283,9 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) + { + unsigned long flags; + unsigned int state; ++ struct uid_entry *uid_entry; + struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; ++ uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p)); + + if (!freqs || p->flags & PF_EXITING) + return; +@@ -145,6 +297,12 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) + p->time_in_state) + p->time_in_state[state] += cputime; + spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++ ++ spin_lock_irqsave(&uid_lock, flags); ++ uid_entry = find_or_register_uid_locked(uid); ++ if (uid_entry && state < uid_entry->max_state) ++ uid_entry->time_in_state[state] += cputime; ++ spin_unlock_irqrestore(&uid_lock, flags); + } + + void cpufreq_times_create_policy(struct cpufreq_policy *policy) +@@ -186,6 +344,27 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) + all_freqs[cpu] = freqs; + } + ++void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) ++{ ++ struct uid_entry *uid_entry; ++ struct hlist_node *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&uid_lock, flags); ++ ++ for (; uid_start <= uid_end; uid_start++) { ++ hash_for_each_possible_safe(uid_hash_table, uid_entry, tmp, ++ hash, uid_start) { ++ if (uid_start == uid_entry->uid) { ++ hash_del_rcu(&uid_entry->hash); ++ kfree_rcu(uid_entry, rcu); ++ } ++ } ++ } ++ ++ spin_unlock_irqrestore(&uid_lock, flags); ++} ++ + void cpufreq_times_record_transition(struct cpufreq_freqs *freq) + { + int index; +@@ -205,3 +384,32 @@ void cpufreq_times_record_transition(struct cpufreq_freqs *freq) + + cpufreq_cpu_put(policy); + } ++ ++static const struct seq_operations uid_time_in_state_seq_ops = { ++ .start = uid_seq_start, ++ .next = uid_seq_next, ++ .stop = uid_seq_stop, ++ .show = uid_time_in_state_seq_show, ++}; ++ ++static int uid_time_in_state_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &uid_time_in_state_seq_ops); ++} ++ ++static const struct file_operations uid_time_in_state_fops = { ++ .open = uid_time_in_state_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++}; ++ ++static int __init cpufreq_times_init(void) ++{ ++ proc_create_data("uid_time_in_state", 0444, NULL, ++ &uid_time_in_state_fops, NULL); ++ ++ return 0; ++} ++ ++early_initcall(cpufreq_times_init); +diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c +index 36b5f37fca2f8..88dc1cd3a2046 100644 +--- a/drivers/misc/uid_sys_stats.c ++++ b/drivers/misc/uid_sys_stats.c +@@ -14,6 +14,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -420,6 +421,9 @@ static ssize_t uid_remove_write(struct file *file, + return -EINVAL; + } + ++ /* Also remove uids from /proc/uid_time_in_state */ ++ cpufreq_task_times_remove_uids(uid_start, uid_end); ++ + rt_mutex_lock(&uid_lock); + + for (; uid_start <= uid_end; uid_start++) { +diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h +index bfef6e62c68a1..a03157f649a4f 100644 +--- a/include/linux/cpufreq_times.h ++++ b/include/linux/cpufreq_times.h +@@ -28,6 +28,7 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, + void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); + void cpufreq_times_create_policy(struct cpufreq_policy *policy); + void cpufreq_times_record_transition(struct cpufreq_freqs *freq); ++void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); + #else + static inline void cpufreq_task_times_init(struct task_struct *p) {} + static inline void cpufreq_task_times_alloc(struct task_struct *p) {} +@@ -37,5 +38,7 @@ static inline void cpufreq_acct_update_power(struct task_struct *p, + static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} + static inline void cpufreq_times_record_transition( + struct cpufreq_freqs *freq) {} ++static inline void cpufreq_task_times_remove_uids(uid_t uid_start, ++ uid_t uid_end) {} + #endif /* CONFIG_CPU_FREQ_TIMES */ + #endif /* _LINUX_CPUFREQ_TIMES_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch b/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch new file mode 100644 index 000000000000..c17d35fb5900 --- /dev/null +++ b/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch @@ -0,0 +1,476 @@ +From f9d4d5e2608b11e0af1c62a0b4f451294f9ab2f1 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Wed, 31 Jan 2018 18:11:57 -0800 +Subject: ANDROID: cpufreq: track per-task time in state + +Add time in state data to task structs, and create +/proc//time_in_state files to show how long each individual task +has run at each frequency. +Create a CONFIG_CPU_FREQ_TIMES option to enable/disable this tracking. + +Bug: 72339335 +Bug: 127641090 +Test: Read /proc//time_in_state +Change-Id: Ia6456754f4cb1e83b2bc35efa8fbe9f8696febc8 +Signed-off-by: Connor O'Brien +[astrachan: Folded the following changes into this patch: + a6d3de6a7fba ("ANDROID: Reduce use of #ifdef CONFIG_CPU_FREQ_TIMES") + b89ada5d9c09 ("ANDROID: Fix massive cpufreq_times memory leaks")] +Signed-off-by: Alistair Strachan +--- + drivers/cpufreq/Kconfig | 7 ++ + drivers/cpufreq/Makefile | 5 +- + drivers/cpufreq/cpufreq.c | 3 + + drivers/cpufreq/cpufreq_times.c | 207 ++++++++++++++++++++++++++++++++ + fs/proc/base.c | 7 ++ + include/linux/cpufreq_times.h | 41 +++++++ + include/linux/sched.h | 4 + + kernel/fork.c | 7 ++ + kernel/sched/cputime.c | 7 ++ + 9 files changed, 287 insertions(+), 1 deletion(-) + create mode 100644 drivers/cpufreq/cpufreq_times.c + create mode 100644 include/linux/cpufreq_times.h + +diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig +index bff5295016ae0..f711715aa5797 100644 +--- a/drivers/cpufreq/Kconfig ++++ b/drivers/cpufreq/Kconfig +@@ -34,6 +34,13 @@ config CPU_FREQ_STAT + + If in doubt, say N. + ++config CPU_FREQ_TIMES ++ bool "CPU frequency time-in-state statistics" ++ help ++ Export CPU time-in-state information through procfs. ++ ++ If in doubt, say N. ++ + choice + prompt "Default CPUFreq governor" + default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ +diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile +index 5a6c70d26c985..d28709da43de5 100644 +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -5,7 +5,10 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o + # CPUfreq stats + obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o + +-# CPUfreq governors ++# CPUfreq times ++obj-$(CONFIG_CPU_FREQ_TIMES) += cpufreq_times.o ++ ++# CPUfreq governors + obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o + obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o + obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index c28ebf2810f11..e1cb6e99c76df 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -16,6 +16,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -379,6 +380,7 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy, + CPUFREQ_POSTCHANGE, freqs); + + cpufreq_stats_record_transition(policy, freqs->new); ++ cpufreq_times_record_transition(freqs); + policy->cur = freqs->new; + } + } +@@ -1447,6 +1449,7 @@ static int cpufreq_online(unsigned int cpu) + goto out_destroy_policy; + + cpufreq_stats_create_table(policy); ++ cpufreq_times_create_policy(policy); + + write_lock_irqsave(&cpufreq_driver_lock, flags); + list_add(&policy->policy_list, &cpufreq_policy_list); +diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c +new file mode 100644 +index 0000000000000..339a3e9cf0821 +--- /dev/null ++++ b/drivers/cpufreq/cpufreq_times.c +@@ -0,0 +1,207 @@ ++/* drivers/cpufreq/cpufreq_times.c ++ * ++ * Copyright (C) 2018 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ ++ ++/** ++ * struct cpu_freqs - per-cpu frequency information ++ * @offset: start of these freqs' stats in task time_in_state array ++ * @max_state: number of entries in freq_table ++ * @last_index: index in freq_table of last frequency switched to ++ * @freq_table: list of available frequencies ++ */ ++struct cpu_freqs { ++ unsigned int offset; ++ unsigned int max_state; ++ unsigned int last_index; ++ unsigned int freq_table[0]; ++}; ++ ++static struct cpu_freqs *all_freqs[NR_CPUS]; ++ ++static unsigned int next_offset; ++ ++void cpufreq_task_times_init(struct task_struct *p) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&task_time_in_state_lock, flags); ++ p->time_in_state = NULL; ++ spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++ p->max_state = 0; ++} ++ ++void cpufreq_task_times_alloc(struct task_struct *p) ++{ ++ void *temp; ++ unsigned long flags; ++ unsigned int max_state = READ_ONCE(next_offset); ++ ++ /* We use one array to avoid multiple allocs per task */ ++ temp = kcalloc(max_state, sizeof(p->time_in_state[0]), GFP_ATOMIC); ++ if (!temp) ++ return; ++ ++ spin_lock_irqsave(&task_time_in_state_lock, flags); ++ p->time_in_state = temp; ++ spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++ p->max_state = max_state; ++} ++ ++/* Caller must hold task_time_in_state_lock */ ++static int cpufreq_task_times_realloc_locked(struct task_struct *p) ++{ ++ void *temp; ++ unsigned int max_state = READ_ONCE(next_offset); ++ ++ temp = krealloc(p->time_in_state, max_state * sizeof(u64), GFP_ATOMIC); ++ if (!temp) ++ return -ENOMEM; ++ p->time_in_state = temp; ++ memset(p->time_in_state + p->max_state, 0, ++ (max_state - p->max_state) * sizeof(u64)); ++ p->max_state = max_state; ++ return 0; ++} ++ ++void cpufreq_task_times_exit(struct task_struct *p) ++{ ++ unsigned long flags; ++ void *temp; ++ ++ spin_lock_irqsave(&task_time_in_state_lock, flags); ++ temp = p->time_in_state; ++ p->time_in_state = NULL; ++ spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++ kfree(temp); ++} ++ ++int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, ++ struct pid *pid, struct task_struct *p) ++{ ++ unsigned int cpu, i; ++ u64 cputime; ++ unsigned long flags; ++ struct cpu_freqs *freqs; ++ struct cpu_freqs *last_freqs = NULL; ++ ++ spin_lock_irqsave(&task_time_in_state_lock, flags); ++ for_each_possible_cpu(cpu) { ++ freqs = all_freqs[cpu]; ++ if (!freqs || freqs == last_freqs) ++ continue; ++ last_freqs = freqs; ++ ++ seq_printf(m, "cpu%u\n", cpu); ++ for (i = 0; i < freqs->max_state; i++) { ++ if (freqs->freq_table[i] == CPUFREQ_ENTRY_INVALID) ++ continue; ++ cputime = 0; ++ if (freqs->offset + i < p->max_state && ++ p->time_in_state) ++ cputime = p->time_in_state[freqs->offset + i]; ++ seq_printf(m, "%u %lu\n", freqs->freq_table[i], ++ (unsigned long)nsec_to_clock_t(cputime)); ++ } ++ } ++ spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++ return 0; ++} ++ ++void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) ++{ ++ unsigned long flags; ++ unsigned int state; ++ struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; ++ ++ if (!freqs || p->flags & PF_EXITING) ++ return; ++ ++ state = freqs->offset + READ_ONCE(freqs->last_index); ++ ++ spin_lock_irqsave(&task_time_in_state_lock, flags); ++ if ((state < p->max_state || !cpufreq_task_times_realloc_locked(p)) && ++ p->time_in_state) ++ p->time_in_state[state] += cputime; ++ spin_unlock_irqrestore(&task_time_in_state_lock, flags); ++} ++ ++void cpufreq_times_create_policy(struct cpufreq_policy *policy) ++{ ++ int cpu, index; ++ unsigned int count = 0; ++ struct cpufreq_frequency_table *pos, *table; ++ struct cpu_freqs *freqs; ++ void *tmp; ++ ++ if (all_freqs[policy->cpu]) ++ return; ++ ++ table = policy->freq_table; ++ if (!table) ++ return; ++ ++ cpufreq_for_each_entry(pos, table) ++ count++; ++ ++ tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count, ++ GFP_KERNEL); ++ if (!tmp) ++ return; ++ ++ freqs = tmp; ++ freqs->max_state = count; ++ ++ index = cpufreq_frequency_table_get_index(policy, policy->cur); ++ if (index >= 0) ++ WRITE_ONCE(freqs->last_index, index); ++ ++ cpufreq_for_each_entry(pos, table) ++ freqs->freq_table[pos - table] = pos->frequency; ++ ++ freqs->offset = next_offset; ++ WRITE_ONCE(next_offset, freqs->offset + count); ++ for_each_cpu(cpu, policy->related_cpus) ++ all_freqs[cpu] = freqs; ++} ++ ++void cpufreq_times_record_transition(struct cpufreq_freqs *freq) ++{ ++ int index; ++ struct cpu_freqs *freqs = all_freqs[freq->cpu]; ++ struct cpufreq_policy *policy; ++ ++ if (!freqs) ++ return; ++ ++ policy = cpufreq_cpu_get(freq->cpu); ++ if (!policy) ++ return; ++ ++ index = cpufreq_frequency_table_get_index(policy, freq->new); ++ if (index >= 0) ++ WRITE_ONCE(freqs->last_index, index); ++ ++ cpufreq_cpu_put(policy); ++} +diff --git a/fs/proc/base.c b/fs/proc/base.c +index ebea9501afb84..7d13501910ee7 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -94,6 +94,7 @@ + #include + #include + #include ++#include + #include + #include "internal.h" + #include "fd.h" +@@ -3091,6 +3092,9 @@ static const struct pid_entry tgid_base_stuff[] = { + #ifdef CONFIG_LIVEPATCH + ONE("patch_state", S_IRUSR, proc_pid_patch_state), + #endif ++#ifdef CONFIG_CPU_FREQ_TIMES ++ ONE("time_in_state", 0444, proc_time_in_state_show), ++#endif + #ifdef CONFIG_STACKLEAK_METRICS + ONE("stack_depth", S_IRUGO, proc_stack_depth), + #endif +@@ -3487,6 +3491,9 @@ static const struct pid_entry tid_base_stuff[] = { + #ifdef CONFIG_PROC_PID_ARCH_STATUS + ONE("arch_status", S_IRUGO, proc_pid_arch_status), + #endif ++#ifdef CONFIG_CPU_FREQ_TIMES ++ ONE("time_in_state", 0444, proc_time_in_state_show), ++#endif + }; + + static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) +diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h +new file mode 100644 +index 0000000000000..bfef6e62c68a1 +--- /dev/null ++++ b/include/linux/cpufreq_times.h +@@ -0,0 +1,41 @@ ++/* drivers/cpufreq/cpufreq_times.c ++ * ++ * Copyright (C) 2018 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_CPUFREQ_TIMES_H ++#define _LINUX_CPUFREQ_TIMES_H ++ ++#include ++#include ++ ++#ifdef CONFIG_CPU_FREQ_TIMES ++void cpufreq_task_times_init(struct task_struct *p); ++void cpufreq_task_times_alloc(struct task_struct *p); ++void cpufreq_task_times_exit(struct task_struct *p); ++int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, ++ struct pid *pid, struct task_struct *p); ++void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); ++void cpufreq_times_create_policy(struct cpufreq_policy *policy); ++void cpufreq_times_record_transition(struct cpufreq_freqs *freq); ++#else ++static inline void cpufreq_task_times_init(struct task_struct *p) {} ++static inline void cpufreq_task_times_alloc(struct task_struct *p) {} ++static inline void cpufreq_task_times_exit(struct task_struct *p) {} ++static inline void cpufreq_acct_update_power(struct task_struct *p, ++ u64 cputime) {} ++static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} ++static inline void cpufreq_times_record_transition( ++ struct cpufreq_freqs *freq) {} ++#endif /* CONFIG_CPU_FREQ_TIMES */ ++#endif /* _LINUX_CPUFREQ_TIMES_H */ +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 9f51932bd543f..47c90085f5e73 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -854,6 +854,10 @@ struct task_struct { + u64 stimescaled; + #endif + u64 gtime; ++#ifdef CONFIG_CPU_FREQ_TIMES ++ u64 *time_in_state; ++ unsigned int max_state; ++#endif + struct prev_cputime prev_cputime; + #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN + struct vtime vtime; +diff --git a/kernel/fork.c b/kernel/fork.c +index 541fd805fb888..6cde9f0e923d1 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -93,6 +93,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -442,6 +443,8 @@ void put_task_stack(struct task_struct *tsk) + + void free_task(struct task_struct *tsk) + { ++ cpufreq_task_times_exit(tsk); ++ + #ifndef CONFIG_THREAD_INFO_IN_TASK + /* + * The task is finally done with both the stack and thread_info, +@@ -1857,6 +1860,8 @@ static __latent_entropy struct task_struct *copy_process( + if (!p) + goto fork_out; + ++ cpufreq_task_times_init(p); ++ + /* + * This _must_ happen before we call free_task(), i.e. before we jump + * to any of the bad_fork_* labels. This is to avoid freeing +@@ -2374,6 +2379,8 @@ long _do_fork(struct kernel_clone_args *args) + if (IS_ERR(p)) + return PTR_ERR(p); + ++ cpufreq_task_times_alloc(p); ++ + /* + * Do this prior waking up the new thread - the thread pointer + * might get invalid after that point, if the thread exits quickly. +diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c +index 2305ce89a26cf..cdcb00b5dc5ee 100644 +--- a/kernel/sched/cputime.c ++++ b/kernel/sched/cputime.c +@@ -2,6 +2,7 @@ + /* + * Simple CPU accounting cgroup controller + */ ++#include + #include "sched.h" + + #ifdef CONFIG_IRQ_TIME_ACCOUNTING +@@ -129,6 +130,9 @@ void account_user_time(struct task_struct *p, u64 cputime) + + /* Account for user time used */ + acct_account_cputime(p); ++ ++ /* Account power usage for user time */ ++ cpufreq_acct_update_power(p, cputime); + } + + /* +@@ -173,6 +177,9 @@ void account_system_index_time(struct task_struct *p, + + /* Account for system time used */ + acct_account_cputime(p); ++ ++ /* Account power usage for system time */ ++ cpufreq_acct_update_power(p, cputime); + } + + /* +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-create-build.configs-for-allmodconfig.patch b/patches/ANDROID-create-build.configs-for-allmodconfig.patch new file mode 100644 index 000000000000..94e7508a9e6e --- /dev/null +++ b/patches/ANDROID-create-build.configs-for-allmodconfig.patch @@ -0,0 +1,57 @@ +From 884416f5176aeddc5b8d66b64407db8a4e5abe70 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Thu, 29 Aug 2019 12:41:43 +0100 +Subject: ANDROID: create build.configs for allmodconfig + +Bug: 140224784 +Change-Id: I920e8737ee596e1b80428ff9831981c775570070 +Signed-off-by: Matthias Maennich +--- + build.config.allmodconfig | 11 +++++++++++ + build.config.allmodconfig.aarch64 | 4 ++++ + build.config.allmodconfig.x86_64 | 4 ++++ + 3 files changed, 19 insertions(+) + create mode 100644 build.config.allmodconfig + create mode 100644 build.config.allmodconfig.aarch64 + create mode 100644 build.config.allmodconfig.x86_64 + +diff --git a/build.config.allmodconfig b/build.config.allmodconfig +new file mode 100644 +index 000000000000..43b1a70d5800 +--- /dev/null ++++ b/build.config.allmodconfig +@@ -0,0 +1,11 @@ ++DEFCONFIG=allmodconfig ++ ++# XFS_FS is currently broken on this branch with clang-9 ++POST_DEFCONFIG_CMDS="update_config" ++function update_config() { ++ ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \ ++ -d TEST_KMOD \ ++ -d XFS_FS ++ (cd ${OUT_DIR} && \ ++ make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) ++} +diff --git a/build.config.allmodconfig.aarch64 b/build.config.allmodconfig.aarch64 +new file mode 100644 +index 000000000000..863ab1caddab +--- /dev/null ++++ b/build.config.allmodconfig.aarch64 +@@ -0,0 +1,4 @@ ++. ${ROOT_DIR}/common/build.config.common ++. ${ROOT_DIR}/common/build.config.aarch64 ++. ${ROOT_DIR}/common/build.config.allmodconfig ++ +diff --git a/build.config.allmodconfig.x86_64 b/build.config.allmodconfig.x86_64 +new file mode 100644 +index 000000000000..bedb3869d99b +--- /dev/null ++++ b/build.config.allmodconfig.x86_64 +@@ -0,0 +1,4 @@ ++. ${ROOT_DIR}/common/build.config.common ++. ${ROOT_DIR}/common/build.config.x86_64 ++. ${ROOT_DIR}/common/build.config.allmodconfig ++ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_INET_UDP_DIAG-y.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_INET_UDP_DIAG-y.patch new file mode 100644 index 000000000000..86ccfba1e858 --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_INET_UDP_DIAG-y.patch @@ -0,0 +1,45 @@ +From 1fdc8c1e4dbae081228965ed9235e573740b6400 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Fri, 8 Mar 2019 12:59:37 -0800 +Subject: ANDROID: cuttlefish: enable CONFIG_INET_UDP_DIAG=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror: + https://android-review.googlesource.com/c/kernel/configs/+/721208 + android-base.cfg: enable CONFIG_INET_UDP_DIAG + +Generated via: + echo 'CONFIG_INET_UDP_DIAG=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_INET_UDP_DIAG=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + rm defconfig + +Bug: 127981801 +Signed-off-by: Maciej Å»enczykowski +Change-Id: I5d4533b7c3b9a11e45e96b0346a70b3f93d4a812 +--- + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 6bc11c09af2be..e0729ca6bd0e0 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -96,6 +96,7 @@ CONFIG_SYN_COOKIES=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y + # CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_UDP_DIAG=y + CONFIG_INET_DIAG_DESTROY=y + CONFIG_TCP_CONG_ADVANCED=y + # CONFIG_TCP_CONG_BIC is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_NETFILTER_XT_TARGET.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_NETFILTER_XT_TARGET.patch new file mode 100644 index 000000000000..d58a83f10770 --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_NETFILTER_XT_TARGET.patch @@ -0,0 +1,59 @@ +From e3ace526f9d00eed15557bb2425a4ff307a806ae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Tue, 5 Mar 2019 23:04:17 -0800 +Subject: ANDROID: cuttlefish: enable + CONFIG_NETFILTER_XT_TARGET_CT=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror: + https://android-review.googlesource.com/c/kernel/configs/+/919855 + android-4.9+: add CONFIG_NETFILTER_XT_TARGET_CT=y to base config + +Generated via: + echo 'CONFIG_NETFILTER_XT_TARGET_CT=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_NETFILTER_XT_TARGET_CT=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + rm defconfig + +Bug: 124361845 +Signed-off-by: Maciej Å»enczykowski +Change-Id: I6035ef8e75f9daada706a9233999368a22904c4e +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 622db3a8c04b1..2bff38b2701fc 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -123,6 +123,7 @@ CONFIG_NF_CT_NETLINK=y + CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y + CONFIG_NETFILTER_XT_TARGET_CONNMARK=y + CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y + CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y + CONFIG_NETFILTER_XT_TARGET_MARK=y + CONFIG_NETFILTER_XT_TARGET_NFLOG=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index e8da561819039..f2682d56232ba 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -127,6 +127,7 @@ CONFIG_NF_CT_NETLINK=y + CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y + CONFIG_NETFILTER_XT_TARGET_CONNMARK=y + CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y + CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y + CONFIG_NETFILTER_XT_TARGET_MARK=y + CONFIG_NETFILTER_XT_TARGET_NFLOG=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_NET_CLS_BPF-y.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_CLS_BPF-y.patch new file mode 100644 index 000000000000..2db9df0c618c --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_CLS_BPF-y.patch @@ -0,0 +1,57 @@ +From 4d401c69ddd4131e1fd9a73e229686e1c6785dd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Tue, 15 Jan 2019 16:35:27 -0800 +Subject: ANDROID: cuttlefish: enable CONFIG_NET_CLS_BPF=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror + https://android-review.googlesource.com/c/kernel/configs/+/870517 + android-4.9+: add CONFIG_NET_CLS_BPF to base + +Generated via: + echo 'CONFIG_NET_CLS_BPF=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_NET_CLS_BPF=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + +Bug: 65674744 +Change-Id: I8e4dfe7a99d38fd5942001a1aab83b7ac9df30dd +Signed-off-by: Maciej Å»enczykowski +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 730006337b2c3..0aaf923e8c5a0 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -178,6 +178,7 @@ CONFIG_L2TP=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y + CONFIG_NET_CLS_U32=y ++CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y + CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 3bd7f24a945f5..183dd803421eb 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -183,6 +183,7 @@ CONFIG_IP6_NF_RAW=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y + CONFIG_NET_CLS_U32=y ++CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y + CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_INGRESS-y.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_INGRESS-y.patch new file mode 100644 index 000000000000..a71305e8f459 --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_INGRESS-y.patch @@ -0,0 +1,58 @@ +From b9b64c04b9ba674d30ad0445f3fed0ac3be16eff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Thu, 4 Apr 2019 00:40:13 -0700 +Subject: ANDROID: cuttlefish: enable CONFIG_NET_SCH_INGRESS=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror: + https://android-review.googlesource.com/c/kernel/configs/+/939600 + android-4.9+ for Q: require CONFIG_NET_SCH_INGRESS=y + +Generated via: + echo 'CONFIG_NET_SCH_INGRESS=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_NET_SCH_INGRESS=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + rm defconfig + +Bug: 65674744 +Signed-off-by: Maciej Å»enczykowski +Change-Id: I3ad4fb15e450392e527563208587b18b8285b3a8 +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 76a68561f2fb1..3e13e7149946a 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -182,6 +182,7 @@ CONFIG_L2TP=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y + CONFIG_NET_SCH_NETEM=y ++CONFIG_NET_SCH_INGRESS=y + CONFIG_NET_CLS_U32=y + CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index b2ad519f11c70..bc44933298024 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -188,6 +188,7 @@ CONFIG_IP6_NF_RAW=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y + CONFIG_NET_SCH_NETEM=y ++CONFIG_NET_SCH_INGRESS=y + CONFIG_NET_CLS_U32=y + CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_NETEM-y.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_NETEM-y.patch new file mode 100644 index 000000000000..61b47c8543d0 --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_NET_SCH_NETEM-y.patch @@ -0,0 +1,58 @@ +From d3e51465208595209e34219aac3e6dd3a4360275 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Thu, 14 Feb 2019 15:32:55 -0800 +Subject: ANDROID: cuttlefish: enable CONFIG_NET_SCH_NETEM=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror: + https://android-review.googlesource.com/c/kernel/configs/+/906713 + android-4.9+: add CONFIG_NET_SCH_NETEM=y to recommended config + +Generated via: + echo 'CONFIG_NET_SCH_NETEM=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_NET_SCH_NETEM=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + rm defconfig + +Bug: 124467469 +Signed-off-by: Maciej Å»enczykowski +Change-Id: If06da8f0e77d5523c56fea5d520131e456f9b529 +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 87a90ea32c2de..622db3a8c04b1 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -178,6 +178,7 @@ CONFIG_IP6_NF_RAW=y + CONFIG_L2TP=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y ++CONFIG_NET_SCH_NETEM=y + CONFIG_NET_CLS_U32=y + CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index e889c64f64f80..e8da561819039 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -183,6 +183,7 @@ CONFIG_IP6_NF_MANGLE=y + CONFIG_IP6_NF_RAW=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y ++CONFIG_NET_SCH_NETEM=y + CONFIG_NET_CLS_U32=y + CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-enable-CONFIG_USB_RTL8152-y.patch b/patches/ANDROID-cuttlefish-enable-CONFIG_USB_RTL8152-y.patch new file mode 100644 index 000000000000..8449b3b6e136 --- /dev/null +++ b/patches/ANDROID-cuttlefish-enable-CONFIG_USB_RTL8152-y.patch @@ -0,0 +1,58 @@ +From 9f4a749fc616c0da15a339d8aa740b66df81bf2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Wed, 6 Mar 2019 17:02:40 -0800 +Subject: ANDROID: cuttlefish: enable CONFIG_USB_RTL8152=y +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to mirror: + https://android-review.googlesource.com/c/kernel/configs/+/920741 + Require CONFIG_USB_RTL8152 != n if we have host usb support. + +Generated via: + echo 'CONFIG_USB_RTL8152=y' >> arch/x86/configs/x86_64_cuttlefish_defconfig + echo 'CONFIG_USB_RTL8152=y' >> arch/arm64/configs/cuttlefish_defconfig + make ARCH=x86_64 x86_64_cuttlefish_defconfig + make ARCH=x86_64 savedefconfig + cat defconfig > arch/x86/configs/x86_64_cuttlefish_defconfig + make ARCH=arm64 cuttlefish_defconfig + make ARCH=arm64 savedefconfig + cat defconfig > arch/arm64/configs/cuttlefish_defconfig + rm defconfig + +Bug: 110755806 +Signed-off-by: Maciej Å»enczykowski +Change-Id: Iadca2a11b76296532aa42dde999ee73f58e0bd97 +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 9740f417f74e8..4db58d634d7e4 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -230,6 +230,7 @@ CONFIG_PPP_DEFLATE=y + CONFIG_PPP_MPPE=y + CONFIG_PPTP=y + CONFIG_PPPOL2TP=y ++CONFIG_USB_RTL8152=y + CONFIG_USB_USBNET=y + # CONFIG_USB_NET_AX8817X is not set + # CONFIG_USB_NET_AX88179_178A is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index cef416b3a97d2..6bc11c09af2be 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -235,6 +235,7 @@ CONFIG_PPP=y + CONFIG_PPP_BSDCOMP=y + CONFIG_PPP_DEFLATE=y + CONFIG_PPP_MPPE=y ++CONFIG_USB_RTL8152=y + CONFIG_USB_USBNET=y + # CONFIG_USB_NET_AX8817X is not set + # CONFIG_USB_NET_AX88179_178A is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCA.patch b/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCA.patch new file mode 100644 index 000000000000..8d49f7f8f765 --- /dev/null +++ b/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCA.patch @@ -0,0 +1,67 @@ +From 25659a1636e7fc447417d7d0fab7a78d01562aa1 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 26 Oct 2018 10:02:08 -0700 +Subject: ANDROID: {cuttlefish,gki}_defconfig: Enable + CONFIG_SDCARD_FS + +Bug: 118439987 +Change-Id: I020ec721d98c5612bfe76dcfc05caabb1f3588c1 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 4 files changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 0b89a91037a84..b84aad53e6d69 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -409,6 +409,7 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 140804afdd325..18e8f81cc0fb9 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -379,6 +379,7 @@ CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y + CONFIG_ECRYPT_FS=y ++CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 65c67797fb74d..eacebe96e4224 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -304,6 +304,7 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 5baf17714b0c9..cad481541d690 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -430,6 +430,7 @@ CONFIG_PROC_KCORE=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y + CONFIG_HUGETLBFS=y ++CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish-overlayfs-regression.patch b/patches/ANDROID-cuttlefish-overlayfs-regression.patch new file mode 100644 index 000000000000..a66282621e04 --- /dev/null +++ b/patches/ANDROID-cuttlefish-overlayfs-regression.patch @@ -0,0 +1,35 @@ +From 91ba1c1ab413488ffb50058863bd55296a8ebc97 Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Wed, 28 Aug 2019 09:38:07 -0700 +Subject: ANDROID: cuttlefish: overlayfs: regression + +commit a77712c342a56420013625c93d8aa1501455a984 +("ANDROID: Remove unused cuttlefish build infra") caused a +regression in availability of CONFIG_OVERLAY_FS configuration. + +NB: The upstream work to add override_creds to overlayfs is + required in order to pass adb-remount-test.sh. + +Signed-off-by: Mark Salyzyn +Test: confirm overlay filesystem available in the build +Bug: 138649540 +Change-Id: I9e51475f1025f726e69c6f513099248bf452cc2d +--- + arch/x86/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index a37fa09bd107a..b3dad521ee8a2 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -311,6 +311,7 @@ CONFIG_FS_ENCRYPTION=y + CONFIG_QUOTA=y + CONFIG_QFMT_V2=y + CONFIG_FUSE_FS=y ++CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Add-support-for-AC97-au.patch b/patches/ANDROID-cuttlefish_defconfig-Add-support-for-AC97-au.patch new file mode 100644 index 000000000000..bdf2574d1853 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Add-support-for-AC97-au.patch @@ -0,0 +1,56 @@ +From 9486a5baff11f9471265b5bc0a3d6430c92daecd Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 5 Mar 2019 11:11:34 -0800 +Subject: ANDROID: cuttlefish_defconfig: Add support for AC97 + audio + +Enable driver support for the ac97 emulation provided by QEMU and +crosvm. This is for the older 'ac97' soundhw, not 'hda'. + +Bug: 120439617 +Bug: 126955561 +Test: local build and test of sound from cuttlefish +Change-Id: I6c29e352e0be161e2a1dc35fde50b888b7dbf86e +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 6 ++++++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 09b07573dc669..9740f417f74e8 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -300,6 +300,12 @@ CONFIG_DRM=y + CONFIG_DRM_VIRTIO_GPU=y + CONFIG_SOUND=y + CONFIG_SND=y ++CONFIG_SND_HRTIMER=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_DRIVERS is not set ++CONFIG_SND_INTEL8X0=y ++# CONFIG_SND_USB is not set + CONFIG_HIDRAW=y + CONFIG_UHID=y + CONFIG_HID_A4TECH=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index de163e79ee0a9..cef416b3a97d2 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -312,6 +312,12 @@ CONFIG_DRM=y + CONFIG_DRM_VIRTIO_GPU=y + CONFIG_SOUND=y + CONFIG_SND=y ++CONFIG_SND_HRTIMER=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_DRIVERS is not set ++CONFIG_SND_INTEL8X0=y ++# CONFIG_SND_USB is not set + CONFIG_HIDRAW=y + CONFIG_UHID=y + CONFIG_HID_A4TECH=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_ARM64_LSE.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_ARM64_LSE.patch new file mode 100644 index 000000000000..883bd78800e7 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_ARM64_LSE.patch @@ -0,0 +1,32 @@ +From 73ded33c53d5c358a50ece801c57fcbac0cffad2 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 7 Dec 2018 11:50:07 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_ARM64_LSE_ATOMICS + +Enabling this was previously blocked by a lack of support for this +feature in clang, but that problem has been resolved in a newer version +of the compiler. + +Bug: 120439617 +Change-Id: I0f5fd2439c5a71ee0988648970576b46b2c4d20b +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 8d379eb47d343..3c799383ff401 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -45,7 +45,6 @@ CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y + CONFIG_ARM64_SW_TTBR0_PAN=y +-# CONFIG_ARM64_LSE_ATOMICS is not set + CONFIG_RANDOMIZE_BASE=y + CONFIG_CMDLINE="console=ttyAMA0" + CONFIG_CMDLINE_EXTEND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CMDLINE_E.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CMDLINE_E.patch new file mode 100644 index 000000000000..4c40ff9414cc --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CMDLINE_E.patch @@ -0,0 +1,29 @@ +From e6e20b789d3b91a28dd07c7627f80aaf6a1691a1 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 4 Dec 2018 17:49:30 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_CMDLINE_EXTEND + +Bug: 118439987 +Bug: 120439617 +Change-Id: Ib00ea9b9fd0d841d23bc902ed57a0c910cad2310 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index e9cfb27a7af31..b5ec7e3c81aae 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -46,6 +46,7 @@ CONFIG_ARM64_SW_TTBR0_PAN=y + # CONFIG_ARM64_LSE_ATOMICS is not set + CONFIG_RANDOMIZE_BASE=y + CONFIG_CMDLINE="console=ttyAMA0" ++CONFIG_CMDLINE_EXTEND=y + # CONFIG_EFI is not set + CONFIG_COMPAT=y + CONFIG_PM_WAKELOCKS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPUSETS.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPUSETS.patch new file mode 100644 index 000000000000..86d5ff1211af --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPUSETS.patch @@ -0,0 +1,43 @@ +From bfc2be7fdbbfd01101a260678caa186072330b66 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:34:22 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable CONFIG_CPUSETS + +Bug: 118439987 +Bug: 120439617 +Change-Id: I2e730890db891b7c258ce21004b382556af434f5 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 2 ++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index ca9d2b3413f20..fce6de5c89a10 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -12,6 +12,8 @@ CONFIG_MEMCG=y + CONFIG_MEMCG_SWAP=y + CONFIG_RT_GROUP_SCHED=y + CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++# CONFIG_PROC_PID_CPUSET is not set + CONFIG_CGROUP_CPUACCT=y + CONFIG_CGROUP_BPF=y + CONFIG_SCHED_AUTOGROUP=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 918218ed6cf69..9b323d60aae56 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -17,6 +17,8 @@ CONFIG_MEMCG_SWAP=y + CONFIG_CGROUP_SCHED=y + CONFIG_RT_GROUP_SCHED=y + CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++# CONFIG_PROC_PID_CPUSET is not set + CONFIG_CGROUP_CPUACCT=y + CONFIG_CGROUP_BPF=y + CONFIG_NAMESPACES=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPU_FREQ_.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPU_FREQ_.patch new file mode 100644 index 000000000000..6cc68fe20b55 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPU_FREQ_.patch @@ -0,0 +1,42 @@ +From c7dd7fbd8c9e1b8972f6563a5d655b5c8e489212 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 30 Oct 2018 17:29:12 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_CPU_FREQ_TIMES + +Bug: 118439987 +Bug: 127641090 +Change-Id: If2a7c773f74dd9351815daa5a935eacc40fa5b84 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 2bff38b2701fc..09b07573dc669 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -58,6 +58,7 @@ CONFIG_ENERGY_MODEL=y + CONFIG_CPU_IDLE=y + CONFIG_ARM_CPUIDLE=y + CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_TIMES=y + CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=y + CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index f2682d56232ba..de163e79ee0a9 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -58,6 +58,7 @@ CONFIG_ACPI_PROCFS_POWER=y + # CONFIG_ACPI_FAN is not set + # CONFIG_ACPI_THERMAL is not set + # CONFIG_X86_PM_TIMER is not set ++CONFIG_CPU_FREQ_TIMES=y + CONFIG_CPU_FREQ_GOV_ONDEMAND=y + CONFIG_X86_ACPI_CPUFREQ=y + CONFIG_PCI_MSI=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CRYPTO_AD.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CRYPTO_AD.patch new file mode 100644 index 000000000000..1bb013154f77 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_CRYPTO_AD.patch @@ -0,0 +1,42 @@ +From d1218cd77b0708ad858206a6b536b81aeae230c4 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 3 Dec 2018 12:53:02 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_CRYPTO_ADIANTUM + +Bug: 118439987 +Bug: 120439617 +Change-Id: I0a192256b4bbf101221a3bb31c4f288581bbddc5 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 2a6b0a950bc92..8d379eb47d343 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -407,6 +407,7 @@ CONFIG_SECURITY_NETWORK=y + CONFIG_LSM_MMAP_MIN_ADDR=65536 + CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y ++CONFIG_CRYPTO_ADIANTUM=y + CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 937f715f5fee4..5fd2be0402c52 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -426,6 +426,7 @@ CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y + CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 + # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set ++CONFIG_CRYPTO_ADIANTUM=y + CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_DM_VERITY.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_DM_VERITY.patch new file mode 100644 index 000000000000..2b836dc5decc --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_DM_VERITY.patch @@ -0,0 +1,42 @@ +From 81f3a056934fe8cdec7468bb73b0abeb69eb22b2 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:35:52 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_DM_VERITY_AVB + +Bug: 118439987 +Bug: 120439617 +Change-Id: If92a3c2f23f211ab9b73ea2b41ee339727ad1018 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index fce6de5c89a10..86a3707faf27b 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -208,6 +208,7 @@ CONFIG_BLK_DEV_DM=y + CONFIG_DM_CRYPT=y + CONFIG_DM_UEVENT=y + CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_AVB=y + CONFIG_DM_VERITY_FEC=y + CONFIG_NETDEVICES=y + CONFIG_NETCONSOLE=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 9b323d60aae56..1c362f19e073f 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -215,6 +215,7 @@ CONFIG_DM_MIRROR=y + CONFIG_DM_ZERO=y + CONFIG_DM_UEVENT=y + CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_AVB=y + CONFIG_DM_VERITY_FEC=y + CONFIG_NETDEVICES=y + CONFIG_NETCONSOLE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_FUSE_FS.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_FUSE_FS.patch new file mode 100644 index 000000000000..0ec3db9c50c4 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_FUSE_FS.patch @@ -0,0 +1,41 @@ +From 742453be0b48330ad8ee253416a12d7ab28e8a70 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 2 Apr 2019 23:59:58 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable CONFIG_FUSE_FS + +Bug: 120439617 +Bug: 129901600 +Change-Id: Iff554123147f7761ca639b89612138b82a4a400a +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 420ff37f91fb0..435332a066621 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -411,6 +411,7 @@ CONFIG_F2FS_FS_ENCRYPTION=y + # CONFIG_DNOTIFY is not set + CONFIG_QUOTA=y + CONFIG_QFMT_V2=y ++CONFIG_FUSE_FS=y + CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index e93ce3c519d65..304c572750edb 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -424,6 +424,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y + # CONFIG_PRINT_QUOTA_WARNING is not set + CONFIG_QFMT_V2=y + CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=y + CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_INPUT_MOU.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_INPUT_MOU.patch new file mode 100644 index 000000000000..45dbbda5f63a --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_INPUT_MOU.patch @@ -0,0 +1,29 @@ +From a0b707e7e51c42b4732567d4bd9d8f7f8b806f35 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 22 Mar 2019 16:52:47 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_INPUT_MOUSEDEV + +Bug: 120439617 +Bug: 128633328 +Change-Id: I2186d8070f7885937925a25e85ce7b5722a73d57 +Signed-off-by: Alistair Strachan +--- + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 3deac5da306a3..abd24a4f017d4 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -264,6 +264,7 @@ CONFIG_USB_USBNET=y + # CONFIG_WLAN_VENDOR_QUANTENNA is not set + CONFIG_MAC80211_HWSIM=y + CONFIG_VIRT_WIFI=y ++CONFIG_INPUT_MOUSEDEV=y + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_MMC.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_MMC.patch new file mode 100644 index 000000000000..710348f1e97d --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_MMC.patch @@ -0,0 +1,47 @@ +From f5d4491da3480bf720f863958e82ae55ad846ab0 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:37:18 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable CONFIG_MMC + +Bug: 118439987 +Bug: 120439617 +Change-Id: I7c63e4b9462bfe6fe46c6f7d5661b48dcecdb5e8 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 4 ++++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 97a45ba040a22..fa86d0682e214 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -356,6 +356,10 @@ CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_MMC=y ++# CONFIG_PWRSEQ_EMMC is not set ++# CONFIG_PWRSEQ_SIMPLE is not set ++# CONFIG_MMC_BLOCK is not set + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + # CONFIG_RTC_SYSTOHC is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 3ad5e6d87a5d8..5ce93372e6a77 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -368,6 +368,10 @@ CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_MMC=y ++# CONFIG_PWRSEQ_EMMC is not set ++# CONFIG_PWRSEQ_SIMPLE is not set ++# CONFIG_MMC_BLOCK is not set + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + CONFIG_SW_SYNC=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_NETFILTER.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_NETFILTER.patch new file mode 100644 index 000000000000..a51afbc3e67b --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_NETFILTER.patch @@ -0,0 +1,42 @@ +From 24500b897442f71355972f49f2fd41a5af55023c Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 30 Oct 2018 17:29:12 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_NETFILTER_XT_MATCH_QUOTA2 + +Bug: 118439987 +Bug: 120439617 +Change-Id: I88fad3590ef2f37daedfd4fe005bd196649f2384 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 86a3707faf27b..8897572788d26 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -147,6 +147,7 @@ CONFIG_NETFILTER_XT_MATCH_MARK=y + CONFIG_NETFILTER_XT_MATCH_POLICY=y + CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y + CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA2=y + CONFIG_NETFILTER_XT_MATCH_SOCKET=y + CONFIG_NETFILTER_XT_MATCH_STATE=y + CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 1c362f19e073f..40026fb95672c 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -150,6 +150,7 @@ CONFIG_NETFILTER_XT_MATCH_MARK=y + CONFIG_NETFILTER_XT_MATCH_POLICY=y + CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y + CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA2=y + CONFIG_NETFILTER_XT_MATCH_SOCKET=y + CONFIG_NETFILTER_XT_MATCH_STATE=y + CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_OVERLAY_F.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_OVERLAY_F.patch new file mode 100644 index 000000000000..c610d4868099 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_OVERLAY_F.patch @@ -0,0 +1,42 @@ +From bbfb66341dafb76585b4d58cabdb1573cb0e5132 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 2 Apr 2019 23:59:58 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_OVERLAY_FS + +Bug: 120439617 +Bug: 123755887 +Change-Id: I5e1225c0ba82ac6d12133ed0e118bf31c21b8da5 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 3e13e7149946a..420ff37f91fb0 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -411,6 +411,7 @@ CONFIG_F2FS_FS_ENCRYPTION=y + # CONFIG_DNOTIFY is not set + CONFIG_QUOTA=y + CONFIG_QFMT_V2=y ++CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index bc44933298024..e93ce3c519d65 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -424,6 +424,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y + # CONFIG_PRINT_QUOTA_WARNING is not set + CONFIG_QFMT_V2=y + CONFIG_AUTOFS4_FS=y ++CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_PROC_KCORE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_PSI.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_PSI.patch new file mode 100644 index 000000000000..144c10ab2ecf --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_PSI.patch @@ -0,0 +1,41 @@ +From 91370a10193baa0d4ce99942cfa0ca2ab73095f6 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 22 Mar 2019 14:10:59 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable CONFIG_PSI + +Bug: 120439617 +Bug: 127712811 +Change-Id: Id3531e3573ccea1720047d502288f60ee151cbff +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 4db58d634d7e4..b3116d935c841 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -6,6 +6,7 @@ CONFIG_TASKSTATS=y + CONFIG_TASK_DELAY_ACCT=y + CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_PSI=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_MEMCG=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index e0729ca6bd0e0..3deac5da306a3 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -9,6 +9,7 @@ CONFIG_TASKSTATS=y + CONFIG_TASK_DELAY_ACCT=y + CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_PSI=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_CGROUPS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_RTC_HCTOS.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_RTC_HCTOS.patch new file mode 100644 index 000000000000..2f0371be3138 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_RTC_HCTOS.patch @@ -0,0 +1,45 @@ +From baaf5f3a09d9e415492b8dae667291f894c0f910 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Mon, 4 Feb 2019 17:33:19 +0000 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_RTC_HCTOSYS + +This configuration is required for the VTS test +VtsKernelApiSysfsTest#testRtcHctosys to pass. + +Bug: 123860857 +Test: run vts-kernel -m VtsKernelApiSysfsTest +Signed-off-by: Matthias Maennich +Change-Id: Icae17c74460bcd2aef4cf4e3ec5381de9ea0a66c +--- + arch/arm64/configs/cuttlefish_defconfig | 1 - + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index ec0149bf7246c..d74af2e0e4b1f 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -369,7 +369,6 @@ CONFIG_MMC=y + # CONFIG_PWRSEQ_SIMPLE is not set + # CONFIG_MMC_BLOCK is not set + CONFIG_RTC_CLASS=y +-# CONFIG_RTC_HCTOSYS is not set + # CONFIG_RTC_SYSTOHC is not set + CONFIG_RTC_DRV_PL031=y + CONFIG_VIRTIO_PCI=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index ab7fced951fa6..35c800c4bb40e 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -382,7 +382,6 @@ CONFIG_MMC=y + # CONFIG_PWRSEQ_SIMPLE is not set + # CONFIG_MMC_BLOCK is not set + CONFIG_RTC_CLASS=y +-# CONFIG_RTC_HCTOSYS is not set + CONFIG_SW_SYNC=y + CONFIG_VIRTIO_PCI=y + CONFIG_VIRTIO_BALLOON=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_UID_SYS_S.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_UID_SYS_S.patch new file mode 100644 index 000000000000..28b7e200045e --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_UID_SYS_S.patch @@ -0,0 +1,42 @@ +From 8e5cc068cd10e9301bef8d9545360f73ae579f76 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 30 Oct 2018 17:29:25 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_UID_SYS_STATS + +Bug: 118439987 +Bug: 120439617 +Change-Id: I0a62a9c17f58d79201640be311ea7280a2a040fd +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index fa86d0682e214..ca9d2b3413f20 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -195,6 +195,7 @@ CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_SIZE=8192 + CONFIG_VIRTIO_BLK=y ++CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + # CONFIG_SCSI_MQ_DEFAULT is not set + # CONFIG_SCSI_PROC_FS is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 5ce93372e6a77..918218ed6cf69 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -197,6 +197,7 @@ CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_SIZE=8192 + CONFIG_VIRTIO_BLK=y ++CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + CONFIG_BLK_DEV_SD=y + CONFIG_BLK_DEV_SR=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch new file mode 100644 index 000000000000..2315f94b0fab --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch @@ -0,0 +1,42 @@ +From d174edb2240488dc38d66489d3e9797078f5c582 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:38:12 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_USB_CONFIGFS_F_ACC + +Bug: 118439987 +Bug: 120439617 +Change-Id: I16cd3772a5511842b02ed6114ccc0b0eee5126f8 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index c3f86180e65c6..bb22c11a7eb38 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -353,6 +353,7 @@ CONFIG_USB_GADGET=y + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 0f72dfca13faf..6de2240beeb91 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -365,6 +365,7 @@ CONFIG_USB_DUMMY_HCD=y + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch new file mode 100644 index 000000000000..0220b886c214 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch @@ -0,0 +1,42 @@ +From b284c67579d35e779e2e066fa8b29413d2f0d43d Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:38:37 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_USB_CONFIGFS_F_AUDIO_SRC + +Bug: 118439987 +Bug: 120439617 +Change-Id: I0efbdae061dc79eb4a006b2499c9afd82fbd62fc +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index bb22c11a7eb38..97a45ba040a22 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -354,6 +354,7 @@ CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y ++CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 6de2240beeb91..3ad5e6d87a5d8 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -366,6 +366,7 @@ CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y ++CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch new file mode 100644 index 000000000000..3fa71c5105b2 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch @@ -0,0 +1,42 @@ +From e02ada4da4a9c7d18433aff958515be9e68a0fc9 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 14:36:30 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + CONFIG_USB_CONFIGFS_UEVENT + +Bug: 118439987 +Bug: 120439617 +Change-Id: Iab0c48a56c74ce6240bac696494a8de6e936660b +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index b5ec7e3c81aae..c3f86180e65c6 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -351,6 +351,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_GADGET=y + CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index a30f92646583a..0f72dfca13faf 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -363,6 +363,7 @@ CONFIG_USB_EHCI_HCD=y + CONFIG_USB_GADGET=y + CONFIG_USB_DUMMY_HCD=y + CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_RTC_CLASS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-EAS-related-defi.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-EAS-related-defi.patch new file mode 100644 index 000000000000..4e043de46eb7 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-EAS-related-defi.patch @@ -0,0 +1,89 @@ +From 9cef562da62ab8a54fc9f73dc0fba2b3a4a91b56 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Thu, 8 Nov 2018 11:16:03 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable EAS related + defines + +Provides build coverage for features coming from eas-dev. For now, make +this specific to the arm64 defconfig. + +Bug: 118439987 +Bug: 120439617 +Test: make ARCH=arm64 cuttlefish_defconfig && make ARCH=arm64 +Change-Id: Id018290a2d38631b4b88f15ee7a1a85fcce25798 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 26 ++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index e6f0856cd7903..e9cfb27a7af31 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -8,14 +8,14 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y +-CONFIG_CGROUPS=y + CONFIG_MEMCG=y + CONFIG_MEMCG_SWAP=y +-CONFIG_CGROUP_SCHED=y + CONFIG_RT_GROUP_SCHED=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CGROUP_CPUACCT=y + CONFIG_CGROUP_BPF=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_SCHED_TUNE=y + CONFIG_BLK_DEV_INITRD=y + # CONFIG_RD_BZIP2 is not set + # CONFIG_RD_LZMA is not set +@@ -52,8 +52,22 @@ CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set + CONFIG_PM_DEBUG=y ++CONFIG_ENERGY_MODEL=y ++CONFIG_CPU_IDLE=y ++CONFIG_ARM_CPUIDLE=y + CONFIG_CPU_FREQ=y +-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPUFREQ_DT=y ++CONFIG_ARM_BIG_LITTLE_CPUFREQ=y ++CONFIG_ARM_DT_BL_CPUFREQ=y ++CONFIG_ARM_SCPI_CPUFREQ=y ++CONFIG_ARM_SCMI_CPUFREQ=y ++CONFIG_ARM_SCMI_PROTOCOL=y ++# CONFIG_ARM_SCMI_POWER_DOMAIN is not set ++CONFIG_ARM_SCPI_PROTOCOL=y ++# CONFIG_ARM_SCPI_POWER_DOMAIN is not set + CONFIG_KPROBES=y + CONFIG_JUMP_LABEL=y + CONFIG_MODULES=y +@@ -264,6 +278,8 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set + # CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_CPU_THERMAL=y + CONFIG_MEDIA_SUPPORT=y + # CONFIG_VGA_ARB is not set + CONFIG_DRM=y +@@ -349,9 +365,13 @@ CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y ++CONFIG_COMMON_CLK_SCPI=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_MAILBOX=y + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_LEGACY_ENERGY_MODEL_DT=y + CONFIG_EXT4_FS=y + CONFIG_EXT4_FS_SECURITY=y + CONFIG_EXT4_ENCRYPTION=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-SECURITY_PERF_EV.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-SECURITY_PERF_EV.patch new file mode 100644 index 000000000000..d25179f0053e --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-SECURITY_PERF_EV.patch @@ -0,0 +1,42 @@ +From 08c5f74595a9ce0707b57e37a30d904bb47a5013 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 26 Oct 2018 10:02:08 -0700 +Subject: ANDROID: cuttlefish_defconfig: Enable + SECURITY_PERF_EVENTS_RESTRICT + +Bug: 118439987 +Bug: 120439617 +Change-Id: Ic7dd653292a565a2d4323d68692318e8d881aaeb +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 8897572788d26..2a6b0a950bc92 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -401,6 +401,7 @@ CONFIG_TMPFS_POSIX_ACL=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y + CONFIG_SECURITY=y + CONFIG_SECURITY_NETWORK=y + CONFIG_LSM_MMAP_MIN_ADDR=65536 +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 40026fb95672c..937f715f5fee4 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -418,6 +418,7 @@ CONFIG_NLS_CODEPAGE_437=y + CONFIG_NLS_ASCII=y + CONFIG_NLS_ISO8859_1=y + CONFIG_NLS_UTF8=y ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y + CONFIG_SECURITY=y + CONFIG_SECURITY_NETWORK=y + CONFIG_SECURITY_PATH=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-VIRTIO_INPUT.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-VIRTIO_INPUT.patch new file mode 100644 index 000000000000..398d8f7bdb4f --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-VIRTIO_INPUT.patch @@ -0,0 +1,40 @@ +From 812391f188cfdf1a43a6247232daef6b2bb9bf9f Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Wed, 2 Jan 2019 15:24:37 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable VIRTIO_INPUT + +Bug: 120439617 +Change-Id: I83fdb2088f17e71f377e5864d217655b47839267 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 7506d19bd6fb6..730006337b2c3 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -372,6 +372,7 @@ CONFIG_RTC_DRV_PL031=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set + CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + CONFIG_STAGING=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 94ca3e49694c6..3bd7f24a945f5 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -383,6 +383,7 @@ CONFIG_RTC_CLASS=y + CONFIG_SW_SYNC=y + CONFIG_VIRTIO_PCI=y + CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_INPUT=y + CONFIG_VIRTIO_MMIO=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + CONFIG_STAGING=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-VIRT_WIFI.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-VIRT_WIFI.patch new file mode 100644 index 000000000000..073326270755 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-VIRT_WIFI.patch @@ -0,0 +1,41 @@ +From 54bd9f05c9a6225c22b3b11c1dc1436a2ab7a183 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Fri, 7 Dec 2018 16:40:23 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable VIRT_WIFI + +Bug: 120439617 +Bug: 120682817 +Change-Id: Ia1b66528bd9cb1e6e95bd75ac60f393978caa582 +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 3c799383ff401..7506d19bd6fb6 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -247,6 +247,7 @@ CONFIG_USB_USBNET=y + # CONFIG_WLAN_VENDOR_TI is not set + # CONFIG_WLAN_VENDOR_ZYDAS is not set + # CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_VIRT_WIFI=y + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 5fd2be0402c52..94ca3e49694c6 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -253,6 +253,7 @@ CONFIG_USB_USBNET=y + # CONFIG_WLAN_VENDOR_ZYDAS is not set + # CONFIG_WLAN_VENDOR_QUANTENNA is not set + CONFIG_MAC80211_HWSIM=y ++CONFIG_VIRT_WIFI=y + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-Enable-vsock-options.patch b/patches/ANDROID-cuttlefish_defconfig-Enable-vsock-options.patch new file mode 100644 index 000000000000..a6de4ff31267 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-Enable-vsock-options.patch @@ -0,0 +1,43 @@ +From 29ffbfff62711b002c6b8c398dc8f3e972e88ef8 Mon Sep 17 00:00:00 2001 +From: Cody Schuffelen +Date: Mon, 14 Jan 2019 18:37:28 -0800 +Subject: ANDROID: cuttlefish_defconfig: Enable vsock options + +Bug: 121166534 +Test: Ran cuttlefish with common kernel + vsock adb tunnel +Signed-off-by: Cody Schuffelen +Change-Id: I8168a710052c7daada306a915c56230c961accd4 +--- + arch/arm64/configs/cuttlefish_defconfig | 2 ++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 0aaf923e8c5a0..ec0149bf7246c 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -182,6 +182,8 @@ CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y + CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y ++CONFIG_VSOCKETS=y ++CONFIG_VIRTIO_VSOCKETS=y + CONFIG_CFG80211=y + # CONFIG_CFG80211_DEFAULT_PS is not set + # CONFIG_CFG80211_CRDA_SUPPORT is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 183dd803421eb..ab7fced951fa6 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -187,6 +187,8 @@ CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y + CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y ++CONFIG_VSOCKETS=y ++CONFIG_VIRTIO_VSOCKETS=y + CONFIG_CFG80211=y + CONFIG_MAC80211=y + CONFIG_RFKILL=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-1.patch b/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-1.patch new file mode 100644 index 000000000000..5eff927cc50b --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-1.patch @@ -0,0 +1,119 @@ +From b2929e314249bcf776aa79b260052e180fd57747 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Mon, 13 May 2019 10:05:49 -0700 +Subject: ANDROID: cuttlefish_defconfig: sync with + android-mainline-tracking + +Note that savedefconfig dropped CONFIG_SCHED_TUNE, which is not present +on this branch (yet). + +Test: boot cuttlefish on arm64 +Signed-off-by: Tri Vo +--- + arch/arm64/configs/cuttlefish_defconfig | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 435332a066621..5f7157425a316 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -14,11 +14,9 @@ CONFIG_MEMCG_SWAP=y + CONFIG_RT_GROUP_SCHED=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y +-# CONFIG_PROC_PID_CPUSET is not set + CONFIG_CGROUP_CPUACCT=y + CONFIG_CGROUP_BPF=y + CONFIG_SCHED_AUTOGROUP=y +-CONFIG_SCHED_TUNE=y + CONFIG_BLK_DEV_INITRD=y + # CONFIG_RD_BZIP2 is not set + # CONFIG_RD_LZMA is not set +@@ -36,8 +34,7 @@ CONFIG_EMBEDDED=y + # CONFIG_COMPAT_BRK is not set + # CONFIG_SLAB_MERGE_DEFAULT is not set + CONFIG_PROFILING=y +-CONFIG_PCI=y +-CONFIG_PCI_HOST_GENERIC=y ++CONFIG_SCHED_MC=y + CONFIG_HZ_100=y + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y +@@ -47,8 +44,6 @@ CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y + CONFIG_ARM64_SW_TTBR0_PAN=y + CONFIG_RANDOMIZE_BASE=y +-CONFIG_CMDLINE="console=ttyAMA0" +-CONFIG_CMDLINE_EXTEND=y + # CONFIG_EFI is not set + CONFIG_COMPAT=y + CONFIG_PM_WAKELOCKS=y +@@ -64,8 +59,6 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=y + CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y + CONFIG_CPUFREQ_DT=y +-CONFIG_ARM_BIG_LITTLE_CPUFREQ=y +-CONFIG_ARM_DT_BL_CPUFREQ=y + CONFIG_ARM_SCPI_CPUFREQ=y + CONFIG_ARM_SCMI_CPUFREQ=y + CONFIG_ARM_SCMI_PROTOCOL=y +@@ -86,6 +79,8 @@ CONFIG_NET=y + CONFIG_PACKET=y + CONFIG_UNIX=y + CONFIG_XFRM_USER=y ++CONFIG_XFRM_INTERFACE=y ++CONFIG_XFRM_STATISTICS=y + CONFIG_NET_KEY=y + CONFIG_INET=y + CONFIG_IP_MULTICAST=y +@@ -196,6 +191,8 @@ CONFIG_CFG80211=y + CONFIG_MAC80211=y + # CONFIG_MAC80211_RC_MINSTREL is not set + CONFIG_RFKILL=y ++CONFIG_PCI=y ++CONFIG_PCI_HOST_GENERIC=y + # CONFIG_UEVENT_HELPER is not set + CONFIG_DEVTMPFS=y + # CONFIG_ALLOW_DEV_COREDUMP is not set +@@ -208,7 +205,6 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 + CONFIG_VIRTIO_BLK=y + CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y +-# CONFIG_SCSI_MQ_DEFAULT is not set + # CONFIG_SCSI_PROC_FS is not set + CONFIG_BLK_DEV_SD=y + CONFIG_SCSI_VIRTIO=y +@@ -285,6 +281,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 + CONFIG_SERIAL_8250_EXTENDED=y + CONFIG_SERIAL_8250_MANY_PORTS=y + CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_OF_PLATFORM=y + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + CONFIG_VIRTIO_CONSOLE=y +@@ -384,6 +381,7 @@ CONFIG_MMC=y + # CONFIG_MMC_BLOCK is not set + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set ++CONFIG_RTC_DRV_PL030=y + CONFIG_RTC_DRV_PL031=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set +@@ -401,13 +399,11 @@ CONFIG_MAILBOX=y + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y +-CONFIG_LEGACY_ENERGY_MODEL_DT=y + CONFIG_EXT4_FS=y + CONFIG_EXT4_FS_SECURITY=y +-CONFIG_EXT4_ENCRYPTION=y + CONFIG_F2FS_FS=y + CONFIG_F2FS_FS_SECURITY=y +-CONFIG_F2FS_FS_ENCRYPTION=y ++CONFIG_FS_ENCRYPTION=y + # CONFIG_DNOTIFY is not set + CONFIG_QUOTA=y + CONFIG_QFMT_V2=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-2.patch b/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-2.patch new file mode 100644 index 000000000000..898068ca4b79 --- /dev/null +++ b/patches/ANDROID-cuttlefish_defconfig-sync-with-android-mainl-2.patch @@ -0,0 +1,29 @@ +From b5621fb46a927017f1370525ea2dfe8daaf42b63 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Tue, 14 May 2019 16:04:54 -0700 +Subject: ANDROID: cuttlefish_defconfig: sync with + android-mainline-tracking (#2) + +Synchronize the x86_64 defconfig too. + +Change-Id: If959b35778b645a9443d9620a9a77283b71edd04 +Signed-off-by: Alistair Strachan +--- + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 304c572750edb..d1f0fa08eacfb 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -450,6 +450,7 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 + # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set + CONFIG_CRYPTO_ADIANTUM=y + CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_AES_NI_INTEL=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_DEV_VIRTIO=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-defconfig-build-config-for-cuttlefish.patch b/patches/ANDROID-defconfig-build-config-for-cuttlefish.patch new file mode 100644 index 000000000000..87167da667d0 --- /dev/null +++ b/patches/ANDROID-defconfig-build-config-for-cuttlefish.patch @@ -0,0 +1,917 @@ +From 0213ff42b9467eacc9d800c749ab2d380c5d0bc4 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Thu, 5 Apr 2018 18:01:04 -0700 +Subject: ANDROID: defconfig / build config for cuttlefish + +Add defconfigs for x86_64 and arm64 for the cuttlefish virtual device +platform. This change also add the build.config files needed by the +kernel/build project. + +Bug: 120439617 +Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 +Test: make ARCH=arm64 cuttlefish_defconfig && make ARCH=arm64 +Change-Id: I61bde941e8cfef2dd83cb4ff040f7380922cc44e +Signed-off-by: Alistair Strachan +--- + arch/arm64/configs/cuttlefish_defconfig | 396 +++++++++++++++++ + arch/x86/configs/x86_64_cuttlefish_defconfig | 437 +++++++++++++++++++ + build.config.cuttlefish.aarch64 | 16 + + build.config.cuttlefish.x86_64 | 16 + + 4 files changed, 865 insertions(+) + create mode 100644 arch/arm64/configs/cuttlefish_defconfig + create mode 100644 arch/x86/configs/x86_64_cuttlefish_defconfig + create mode 100644 build.config.cuttlefish.aarch64 + create mode 100644 build.config.cuttlefish.x86_64 + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +new file mode 100644 +index 0000000000000..e6f0856cd7903 +--- /dev/null ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -0,0 +1,396 @@ ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUPS=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_BPF=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++# CONFIG_RD_LZ4 is not set ++CONFIG_SGETMASK_SYSCALL=y ++# CONFIG_SYSFS_SYSCALL is not set ++# CONFIG_FHANDLE is not set ++CONFIG_KALLSYMS_ALL=y ++CONFIG_BPF_SYSCALL=y ++# CONFIG_RSEQ is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_PROFILING=y ++CONFIG_PCI=y ++CONFIG_PCI_HOST_GENERIC=y ++CONFIG_HZ_100=y ++CONFIG_SECCOMP=y ++CONFIG_PARAVIRT=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++CONFIG_ARM64_SW_TTBR0_PAN=y ++# CONFIG_ARM64_LSE_ATOMICS is not set ++CONFIG_RANDOMIZE_BASE=y ++CONFIG_CMDLINE="console=ttyAMA0" ++# CONFIG_EFI is not set ++CONFIG_COMPAT=y ++CONFIG_PM_WAKELOCKS=y ++CONFIG_PM_WAKELOCKS_LIMIT=0 ++# CONFIG_PM_WAKELOCKS_GC is not set ++CONFIG_PM_DEBUG=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++# CONFIG_SPARSEMEM_VMEMMAP is not set ++CONFIG_KSM=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_ZSMALLOC=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_NET_IPGRE_DEMUX=y ++CONFIG_NET_IPVTI=y ++CONFIG_INET_ESP=y ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_UDP_DIAG=y ++CONFIG_INET_DIAG_DESTROY=y ++CONFIG_TCP_CONG_ADVANCED=y ++# CONFIG_TCP_CONG_BIC is not set ++# CONFIG_TCP_CONG_WESTWOOD is not set ++# CONFIG_TCP_CONG_HTCP is not set ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_ESP=y ++CONFIG_INET6_IPCOMP=y ++CONFIG_IPV6_MIP6=y ++CONFIG_IPV6_VTI=y ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_AMANDA=y ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_H323=y ++CONFIG_NF_CONNTRACK_IRC=y ++CONFIG_NF_CONNTRACK_NETBIOS_NS=y ++CONFIG_NF_CONNTRACK_PPTP=y ++CONFIG_NF_CONNTRACK_SANE=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NF_CT_NETLINK=y ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NETFILTER_XT_TARGET_NFLOG=y ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y ++CONFIG_NETFILTER_XT_TARGET_TPROXY=y ++CONFIG_NETFILTER_XT_TARGET_TRACE=y ++CONFIG_NETFILTER_XT_TARGET_SECMARK=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_MATCH_COMMENT=y ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y ++CONFIG_NETFILTER_XT_MATCH_LENGTH=y ++CONFIG_NETFILTER_XT_MATCH_LIMIT=y ++CONFIG_NETFILTER_XT_MATCH_MAC=y ++CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_POLICY=y ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_SOCKET=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y ++CONFIG_NETFILTER_XT_MATCH_STRING=y ++CONFIG_NETFILTER_XT_MATCH_TIME=y ++CONFIG_NETFILTER_XT_MATCH_U32=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_NETMAP=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_SECURITY=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_L2TP=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_HTB=y ++CONFIG_NET_CLS_U32=y ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_U32=y ++CONFIG_NET_CLS_ACT=y ++CONFIG_CFG80211=y ++# CONFIG_CFG80211_DEFAULT_PS is not set ++# CONFIG_CFG80211_CRDA_SUPPORT is not set ++CONFIG_MAC80211=y ++# CONFIG_MAC80211_RC_MINSTREL is not set ++CONFIG_RFKILL=y ++# CONFIG_UEVENT_HELPER is not set ++CONFIG_DEVTMPFS=y ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++CONFIG_DEBUG_DEVRES=y ++CONFIG_OF_UNITTEST=y ++CONFIG_ZRAM=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_VIRTIO_BLK=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_VIRTIO=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_UEVENT=y ++CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_FEC=y ++CONFIG_NETDEVICES=y ++CONFIG_NETCONSOLE=y ++CONFIG_NETCONSOLE_DYNAMIC=y ++CONFIG_TUN=y ++CONFIG_VIRTIO_NET=y ++# CONFIG_ETHERNET is not set ++CONFIG_PHYLIB=y ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_MPPE=y ++CONFIG_PPTP=y ++CONFIG_PPPOL2TP=y ++CONFIG_USB_USBNET=y ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_XPAD=y ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_XPAD_LEDS=y ++CONFIG_INPUT_TABLET=y ++CONFIG_TABLET_USB_ACECAD=y ++CONFIG_TABLET_USB_AIPTEK=y ++CONFIG_TABLET_USB_GTCO=y ++CONFIG_TABLET_USB_HANWANG=y ++CONFIG_TABLET_USB_KBTAB=y ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_UINPUT=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_EXAR is not set ++CONFIG_SERIAL_8250_NR_UARTS=48 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_MANY_PORTS=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_VIRTIO=y ++# CONFIG_HW_RANDOM_CAVIUM is not set ++# CONFIG_DEVPORT is not set ++# CONFIG_I2C_COMPAT is not set ++# CONFIG_I2C_HELPER_AUTO is not set ++# CONFIG_HWMON is not set ++CONFIG_MEDIA_SUPPORT=y ++# CONFIG_VGA_ARB is not set ++CONFIG_DRM=y ++# CONFIG_DRM_FBDEV_EMULATION is not set ++CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_A4TECH=y ++CONFIG_HID_ACRUX=y ++CONFIG_HID_ACRUX_FF=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_BELKIN=y ++CONFIG_HID_CHERRY=y ++CONFIG_HID_CHICONY=y ++CONFIG_HID_PRODIKEYS=y ++CONFIG_HID_CYPRESS=y ++CONFIG_HID_DRAGONRISE=y ++CONFIG_DRAGONRISE_FF=y ++CONFIG_HID_EMS_FF=y ++CONFIG_HID_ELECOM=y ++CONFIG_HID_EZKEY=y ++CONFIG_HID_HOLTEK=y ++CONFIG_HID_KEYTOUCH=y ++CONFIG_HID_KYE=y ++CONFIG_HID_UCLOGIC=y ++CONFIG_HID_WALTOP=y ++CONFIG_HID_GYRATION=y ++CONFIG_HID_TWINHAN=y ++CONFIG_HID_KENSINGTON=y ++CONFIG_HID_LCPOWER=y ++CONFIG_HID_LOGITECH=y ++CONFIG_HID_LOGITECH_DJ=y ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_HID_MAGICMOUSE=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MONTEREY=y ++CONFIG_HID_MULTITOUCH=y ++CONFIG_HID_NTRIG=y ++CONFIG_HID_ORTEK=y ++CONFIG_HID_PANTHERLORD=y ++CONFIG_PANTHERLORD_FF=y ++CONFIG_HID_PETALYNX=y ++CONFIG_HID_PICOLCD=y ++CONFIG_HID_PRIMAX=y ++CONFIG_HID_ROCCAT=y ++CONFIG_HID_SAITEK=y ++CONFIG_HID_SAMSUNG=y ++CONFIG_HID_SONY=y ++CONFIG_HID_SPEEDLINK=y ++CONFIG_HID_SUNPLUS=y ++CONFIG_HID_GREENASIA=y ++CONFIG_GREENASIA_FF=y ++CONFIG_HID_SMARTJOYPLUS=y ++CONFIG_SMARTJOYPLUS_FF=y ++CONFIG_HID_TIVO=y ++CONFIG_HID_TOPSEED=y ++CONFIG_HID_THRUSTMASTER=y ++CONFIG_HID_WACOM=y ++CONFIG_HID_WIIMOTE=y ++CONFIG_HID_ZEROPLUS=y ++CONFIG_HID_ZYDACRON=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++# CONFIG_RTC_SYSTOHC is not set ++CONFIG_RTC_DRV_PL031=y ++CONFIG_VIRTIO_PCI=y ++# CONFIG_VIRTIO_PCI_LEGACY is not set ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_STAGING=y ++CONFIG_ASHMEM=y ++CONFIG_ANDROID_VSOC=y ++CONFIG_ION=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_ANDROID=y ++CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_EXT4_ENCRYPTION=y ++CONFIG_F2FS_FS=y ++CONFIG_F2FS_FS_SECURITY=y ++CONFIG_F2FS_FS_ENCRYPTION=y ++# CONFIG_DNOTIFY is not set ++CONFIG_QUOTA=y ++CONFIG_QFMT_V2=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_SECURITY=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_LSM_MMAP_MIN_ADDR=65536 ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_SECURITY_SELINUX=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_XZ_DEC=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_SOFTLOCKUP_DETECTOR=y ++# CONFIG_DETECT_HUNG_TASK is not set ++CONFIG_PANIC_TIMEOUT=5 ++CONFIG_SCHEDSTATS=y ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++CONFIG_ENABLE_DEFAULT_TRACERS=y ++# CONFIG_RUNTIME_TESTING_MENU is not set +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +new file mode 100644 +index 0000000000000..a30f92646583a +--- /dev/null ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -0,0 +1,437 @@ ++CONFIG_POSIX_MQUEUE=y ++# CONFIG_USELIB is not set ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUPS=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_BPF=y ++CONFIG_NAMESPACES=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_RD_LZ4 is not set ++# CONFIG_FHANDLE is not set ++# CONFIG_PCSPKR_PLATFORM is not set ++CONFIG_KALLSYMS_ALL=y ++CONFIG_BPF_SYSCALL=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_SMP=y ++CONFIG_HYPERVISOR_GUEST=y ++CONFIG_PARAVIRT=y ++CONFIG_PARAVIRT_SPINLOCKS=y ++CONFIG_MCORE2=y ++CONFIG_PROCESSOR_SELECT=y ++# CONFIG_CPU_SUP_CENTAUR is not set ++CONFIG_NR_CPUS=8 ++# CONFIG_MICROCODE is not set ++CONFIG_X86_MSR=y ++CONFIG_X86_CPUID=y ++# CONFIG_MTRR is not set ++CONFIG_HZ_100=y ++CONFIG_KEXEC=y ++CONFIG_CRASH_DUMP=y ++CONFIG_PHYSICAL_START=0x200000 ++CONFIG_PHYSICAL_ALIGN=0x1000000 ++CONFIG_CMDLINE_BOOL=y ++CONFIG_CMDLINE="console=ttyS0 reboot=p" ++CONFIG_PM_WAKELOCKS=y ++CONFIG_PM_WAKELOCKS_LIMIT=0 ++# CONFIG_PM_WAKELOCKS_GC is not set ++CONFIG_PM_DEBUG=y ++CONFIG_ACPI_PROCFS_POWER=y ++# CONFIG_ACPI_FAN is not set ++# CONFIG_ACPI_THERMAL is not set ++# CONFIG_X86_PM_TIMER is not set ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_X86_ACPI_CPUFREQ=y ++CONFIG_PCI_MSI=y ++CONFIG_IA32_EMULATION=y ++# CONFIG_FIRMWARE_MEMMAP is not set ++CONFIG_OPROFILE=y ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_REFCOUNT_FULL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_BINFMT_MISC=y ++CONFIG_KSM=y ++CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_ZSMALLOC=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_NET_IPVTI=y ++CONFIG_INET_ESP=y ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG_DESTROY=y ++CONFIG_TCP_CONG_ADVANCED=y ++# CONFIG_TCP_CONG_BIC is not set ++# CONFIG_TCP_CONG_WESTWOOD is not set ++# CONFIG_TCP_CONG_HTCP is not set ++CONFIG_TCP_MD5SIG=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=y ++CONFIG_INET6_ESP=y ++CONFIG_INET6_IPCOMP=y ++CONFIG_IPV6_MIP6=y ++CONFIG_IPV6_VTI=y ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETLABEL=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_AMANDA=y ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_H323=y ++CONFIG_NF_CONNTRACK_IRC=y ++CONFIG_NF_CONNTRACK_NETBIOS_NS=y ++CONFIG_NF_CONNTRACK_PPTP=y ++CONFIG_NF_CONNTRACK_SANE=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NF_CT_NETLINK=y ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NETFILTER_XT_TARGET_NFLOG=y ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y ++CONFIG_NETFILTER_XT_TARGET_TPROXY=y ++CONFIG_NETFILTER_XT_TARGET_TRACE=y ++CONFIG_NETFILTER_XT_TARGET_SECMARK=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_MATCH_COMMENT=y ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y ++CONFIG_NETFILTER_XT_MATCH_LENGTH=y ++CONFIG_NETFILTER_XT_MATCH_LIMIT=y ++CONFIG_NETFILTER_XT_MATCH_MAC=y ++CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_POLICY=y ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_SOCKET=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y ++CONFIG_NETFILTER_XT_MATCH_STRING=y ++CONFIG_NETFILTER_XT_MATCH_TIME=y ++CONFIG_NETFILTER_XT_MATCH_U32=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_NETMAP=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_SECURITY=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_IPV6HEADER=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_HTB=y ++CONFIG_NET_CLS_U32=y ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_U32=y ++CONFIG_NET_CLS_ACT=y ++CONFIG_CFG80211=y ++CONFIG_MAC80211=y ++CONFIG_RFKILL=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEBUG_DEVRES=y ++CONFIG_OF=y ++CONFIG_OF_UNITTEST=y ++# CONFIG_PNP_DEBUG_MESSAGES is not set ++CONFIG_ZRAM=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_VIRTIO_BLK=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_DEV_SR=y ++CONFIG_BLK_DEV_SR_VENDOR=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_SPI_ATTRS=y ++CONFIG_SCSI_VIRTIO=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_MIRROR=y ++CONFIG_DM_ZERO=y ++CONFIG_DM_UEVENT=y ++CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_FEC=y ++CONFIG_NETDEVICES=y ++CONFIG_NETCONSOLE=y ++CONFIG_NETCONSOLE_DYNAMIC=y ++CONFIG_TUN=y ++CONFIG_VIRTIO_NET=y ++# CONFIG_ETHERNET is not set ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_MPPE=y ++CONFIG_USB_USBNET=y ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_MAC80211_HWSIM=y ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_XPAD=y ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_XPAD_LEDS=y ++CONFIG_INPUT_TABLET=y ++CONFIG_TABLET_USB_ACECAD=y ++CONFIG_TABLET_USB_AIPTEK=y ++CONFIG_TABLET_USB_GTCO=y ++CONFIG_TABLET_USB_HANWANG=y ++CONFIG_TABLET_USB_KBTAB=y ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_UINPUT=y ++# CONFIG_SERIO_I8042 is not set ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_EXAR is not set ++CONFIG_SERIAL_8250_NR_UARTS=48 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_MANY_PORTS=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_HW_RANDOM=y ++# CONFIG_HW_RANDOM_INTEL is not set ++# CONFIG_HW_RANDOM_AMD is not set ++# CONFIG_HW_RANDOM_VIA is not set ++CONFIG_HW_RANDOM_VIRTIO=y ++CONFIG_HPET=y ++# CONFIG_HPET_MMAP_DEFAULT is not set ++# CONFIG_DEVPORT is not set ++# CONFIG_ACPI_I2C_OPREGION is not set ++# CONFIG_I2C_COMPAT is not set ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_PTP_1588_CLOCK=y ++# CONFIG_HWMON is not set ++# CONFIG_X86_PKG_TEMP_THERMAL is not set ++CONFIG_WATCHDOG=y ++CONFIG_SOFT_WATCHDOG=y ++CONFIG_MEDIA_SUPPORT=y ++# CONFIG_VGA_ARB is not set ++CONFIG_DRM=y ++# CONFIG_DRM_FBDEV_EMULATION is not set ++CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_A4TECH=y ++CONFIG_HID_ACRUX=y ++CONFIG_HID_ACRUX_FF=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_BELKIN=y ++CONFIG_HID_CHERRY=y ++CONFIG_HID_CHICONY=y ++CONFIG_HID_PRODIKEYS=y ++CONFIG_HID_CYPRESS=y ++CONFIG_HID_DRAGONRISE=y ++CONFIG_DRAGONRISE_FF=y ++CONFIG_HID_EMS_FF=y ++CONFIG_HID_ELECOM=y ++CONFIG_HID_EZKEY=y ++CONFIG_HID_HOLTEK=y ++CONFIG_HID_KEYTOUCH=y ++CONFIG_HID_KYE=y ++CONFIG_HID_UCLOGIC=y ++CONFIG_HID_WALTOP=y ++CONFIG_HID_GYRATION=y ++CONFIG_HID_TWINHAN=y ++CONFIG_HID_KENSINGTON=y ++CONFIG_HID_LCPOWER=y ++CONFIG_HID_LOGITECH=y ++CONFIG_HID_LOGITECH_DJ=y ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_HID_MAGICMOUSE=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MONTEREY=y ++CONFIG_HID_MULTITOUCH=y ++CONFIG_HID_NTRIG=y ++CONFIG_HID_ORTEK=y ++CONFIG_HID_PANTHERLORD=y ++CONFIG_PANTHERLORD_FF=y ++CONFIG_HID_PETALYNX=y ++CONFIG_HID_PICOLCD=y ++CONFIG_HID_PRIMAX=y ++CONFIG_HID_ROCCAT=y ++CONFIG_HID_SAITEK=y ++CONFIG_HID_SAMSUNG=y ++CONFIG_HID_SONY=y ++CONFIG_HID_SPEEDLINK=y ++CONFIG_HID_SUNPLUS=y ++CONFIG_HID_GREENASIA=y ++CONFIG_GREENASIA_FF=y ++CONFIG_HID_SMARTJOYPLUS=y ++CONFIG_SMARTJOYPLUS_FF=y ++CONFIG_HID_TIVO=y ++CONFIG_HID_TOPSEED=y ++CONFIG_HID_THRUSTMASTER=y ++CONFIG_HID_WACOM=y ++CONFIG_HID_WIIMOTE=y ++CONFIG_HID_ZEROPLUS=y ++CONFIG_HID_ZYDACRON=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_DUMMY_HCD=y ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_SW_SYNC=y ++CONFIG_VIRTIO_PCI=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_STAGING=y ++CONFIG_ASHMEM=y ++CONFIG_ANDROID_VSOC=y ++CONFIG_ION=y ++# CONFIG_X86_PLATFORM_DEVICES is not set ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_ANDROID=y ++CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_EXT4_ENCRYPTION=y ++CONFIG_F2FS_FS=y ++CONFIG_F2FS_FS_SECURITY=y ++CONFIG_F2FS_FS_ENCRYPTION=y ++CONFIG_QUOTA=y ++CONFIG_QUOTA_NETLINK_INTERFACE=y ++# CONFIG_PRINT_QUOTA_WARNING is not set ++CONFIG_QFMT_V2=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_PROC_KCORE=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_HUGETLBFS=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_UTF8=y ++CONFIG_SECURITY=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_SECURITY_PATH=y ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_SECURITY_SELINUX=y ++CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 ++# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_UNUSED_SYMBOLS is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DEBUG_STACKOVERFLOW=y ++CONFIG_HARDLOCKUP_DETECTOR=y ++CONFIG_PANIC_TIMEOUT=5 ++CONFIG_SCHEDSTATS=y ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++CONFIG_ENABLE_DEFAULT_TRACERS=y ++CONFIG_IO_DELAY_NONE=y ++CONFIG_DEBUG_BOOT_PARAMS=y ++CONFIG_OPTIMIZE_INLINING=y ++CONFIG_UNWINDER_FRAME_POINTER=y +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +new file mode 100644 +index 0000000000000..bfb1f560b2986 +--- /dev/null ++++ b/build.config.cuttlefish.aarch64 +@@ -0,0 +1,16 @@ ++ARCH=arm64 ++BRANCH=android-4.19 ++CLANG_TRIPLE=aarch64-linux-gnu- ++CROSS_COMPILE=aarch64-linux-androidkernel- ++DEFCONFIG=cuttlefish_defconfig ++EXTRA_CMDS='' ++KERNEL_DIR=common ++POST_DEFCONFIG_CMDS="check_defconfig" ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin ++FILES=" ++arch/arm64/boot/Image.gz ++vmlinux ++System.map ++" ++STOP_SHIP_TRACEPRINTK=1 +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +new file mode 100644 +index 0000000000000..69813b30c8ea4 +--- /dev/null ++++ b/build.config.cuttlefish.x86_64 +@@ -0,0 +1,16 @@ ++ARCH=x86_64 ++BRANCH=android-4.19 ++CLANG_TRIPLE=x86_64-linux-gnu- ++CROSS_COMPILE=x86_64-linux-androidkernel- ++DEFCONFIG=x86_64_cuttlefish_defconfig ++EXTRA_CMDS='' ++KERNEL_DIR=common ++POST_DEFCONFIG_CMDS="check_defconfig" ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin ++FILES=" ++arch/x86/boot/bzImage ++vmlinux ++System.map ++" ++STOP_SHIP_TRACEPRINTK=1 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch b/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch new file mode 100644 index 000000000000..a450959591ec --- /dev/null +++ b/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch @@ -0,0 +1,1447 @@ +From 695ab5d15770a6be00e6561e6f0a29652755c191 Mon Sep 17 00:00:00 2001 +From: Paul Lawrence +Date: Tue, 23 Oct 2018 08:56:04 -0700 +Subject: ANDROID: dm-bow: Add dm-bow feature + +Based on https://www.redhat.com/archives/dm-devel/2019-March/msg00025.html + +Third version of dm-bow. Key changes: + +Free list added +Support for block sizes other than 4k +Handles writes during trim phase, and overlapping trims +Integer overflow error +Support trims even if underlying device doesn't +Numerous small bug fixes + +bow == backup on write + +USE CASE: + +dm-bow takes a snapshot of an existing file system before mounting. +The user may, before removing the device, commit the snapshot. +Alternatively the user may remove the device and then run a command +line utility to restore the device to its original state. + +dm-bow does not require an external device + +dm-bow efficiently uses all the available free space on the file system. + +IMPLEMENTATION: + +dm-bow can be in one of three states. + +In state one, the free blocks on the device are identified by issuing +an FSTRIM to the filesystem. + +In state two, any writes cause the overwritten data to be backup up +to the available free space. While in this state, the device can be +restored by unmounting the filesystem, removing the dm-bow device +and running a usermode tool over the underlying device. + +In state three, the changes are committed, dm-bow is in pass-through +mode and the drive can no longer be restored. + +It is planned to use this driver to enable restoration of a failed +update attempt on Android devices using ext4. + +Test: Can boot Android with userdata mounted on this device. Can commit +userdata after SUW has run. Can then reboot, make changes and roll back. + +Known issues: + +Mutex is held around entire flush operation, including lengthy I/O. Plan +is to convert to state machine with pending queues. + +Interaction with block encryption is unknown, especially with respect +to sector 0. + +Bug: 119769411 +Bug: 129280212 +Test: Dogfooded on Wahoo. + Ran under Cuttlefish, running VtsKernelBowTest & + VtsKernelCheckpointTest tests against 4.19, 4.14 & 4.9 kernels +Change-Id: Id70988bbd797ebe3e76fc175094388b423c8da8c +Signed-off-by: Paul Lawrence +--- + Documentation/device-mapper/dm-bow.txt | 99 ++ + drivers/md/Kconfig | 12 + + drivers/md/Makefile | 1 + + drivers/md/dm-bow.c | 1226 ++++++++++++++++++++++++ + 4 files changed, 1338 insertions(+) + create mode 100644 Documentation/device-mapper/dm-bow.txt + create mode 100644 drivers/md/dm-bow.c + +diff --git a/Documentation/device-mapper/dm-bow.txt b/Documentation/device-mapper/dm-bow.txt +new file mode 100644 +index 0000000000000..e3fc4d22e0f40 +--- /dev/null ++++ b/Documentation/device-mapper/dm-bow.txt +@@ -0,0 +1,99 @@ ++dm_bow (backup on write) ++======================== ++ ++dm_bow is a device mapper driver that uses the free space on a device to back up ++data that is overwritten. The changes can then be committed by a simple state ++change, or rolled back by removing the dm_bow device and running a command line ++utility over the underlying device. ++ ++dm_bow has three states, set by writing ‘1’ or ‘2’ to /sys/block/dm-?/bow/state. ++It is only possible to go from state 0 (initial state) to state 1, and then from ++state 1 to state 2. ++ ++State 0: dm_bow collects all trims to the device and assumes that these mark ++free space on the overlying file system that can be safely used. Typically the ++mount code would create the dm_bow device, mount the file system, call the ++FITRIM ioctl on the file system then switch to state 1. These trims are not ++propagated to the underlying device. ++ ++State 1: All writes to the device cause the underlying data to be backed up to ++the free (trimmed) area as needed in such a way as they can be restored. ++However, the writes, with one exception, then happen exactly as they would ++without dm_bow, so the device is always in a good final state. The exception is ++that sector 0 is used to keep a log of the latest changes, both to indicate that ++we are in this state and to allow rollback. See below for all details. If there ++isn't enough free space, writes are failed with -ENOSPC. ++ ++State 2: The transition to state 2 triggers replacing the special sector 0 with ++the normal sector 0, and the freeing of all state information. dm_bow then ++becomes a pass-through driver, allowing the device to continue to be used with ++minimal performance impact. ++ ++Usage ++===== ++dm-bow takes one command line parameter, the name of the underlying device. ++ ++dm-bow will typically be used in the following way. dm-bow will be loaded with a ++suitable underlying device and the resultant device will be mounted. A file ++system trim will be issued via the FITRIM ioctl, then the device will be ++switched to state 1. The file system will now be used as normal. At some point, ++the changes can either be committed by switching to state 2, or rolled back by ++unmounting the file system, removing the dm-bow device and running the command ++line utility. Note that rebooting the device will be equivalent to unmounting ++and removing, but the command line utility must still be run ++ ++Details of operation in state 1 ++=============================== ++ ++dm_bow maintains a type for all sectors. A sector can be any of: ++ ++SECTOR0 ++SECTOR0_CURRENT ++UNCHANGED ++FREE ++CHANGED ++BACKUP ++ ++SECTOR0 is the first sector on the device, and is used to hold the log of ++changes. This is the one exception. ++ ++SECTOR0_CURRENT is a sector picked from the FREE sectors, and is where reads and ++writes from the true sector zero are redirected to. Note that like any backup ++sector, if the sector is written to directly, it must be moved again. ++ ++UNCHANGED means that the sector has not been changed since we entered state 1. ++Thus if it is written to or trimmed, the contents must first be backed up. ++ ++FREE means that the sector was trimmed in state 0 and has not yet been written ++to or used for backup. On being written to, a FREE sector is changed to CHANGED. ++ ++CHANGED means that the sector has been modified, and can be further modified ++without further backup. ++ ++BACKUP means that this is a free sector being used as a backup. On being written ++to, the contents must first be backed up again. ++ ++All backup operations are logged to the first sector. The log sector has the ++format: ++-------------------------------------------------------- ++| Magic | Count | Sequence | Log entry | Log entry | … ++-------------------------------------------------------- ++ ++Magic is a magic number. Count is the number of log entries. Sequence is 0 ++initially. A log entry is ++ ++----------------------------------- ++| Source | Dest | Size | Checksum | ++----------------------------------- ++ ++When SECTOR0 is full, the log sector is backed up and another empty log sector ++created with sequence number one higher. The first entry in any log entry with ++sequence > 0 therefore must be the log of the backing up of the previous log ++sector. Note that sequence is not strictly needed, but is a useful sanity check ++and potentially limits the time spent trying to restore a corrupted snapshot. ++ ++On entering state 1, dm_bow has a list of free sectors. All other sectors are ++unchanged. Sector0_current is selected from the free sectors and the contents of ++sector 0 are copied there. The sector 0 is backed up, which triggers the first ++log entry to be written. ++ +diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig +index 9adb32c01ef1f..539ec6f110cce 100644 +--- a/drivers/md/Kconfig ++++ b/drivers/md/Kconfig +@@ -579,4 +579,16 @@ config DM_ZONED + + If unsure, say N. + ++config DM_BOW ++ tristate "Backup block device" ++ depends on BLK_DEV_DM ++ select DM_BUFIO ++ ---help--- ++ This device-mapper target takes a device and keeps a log of all ++ changes using free blocks identified by issuing a trim command. ++ This can then be restored by running a command line utility, ++ or committed by simply replacing the target. ++ ++ If unsure, say N. ++ + endif # MD +diff --git a/drivers/md/Makefile b/drivers/md/Makefile +index e07264750a3ba..d185e2e790c05 100644 +--- a/drivers/md/Makefile ++++ b/drivers/md/Makefile +@@ -69,6 +69,7 @@ obj-$(CONFIG_DM_LOG_WRITES) += dm-log-writes.o + obj-$(CONFIG_DM_INTEGRITY) += dm-integrity.o + obj-$(CONFIG_DM_ZONED) += dm-zoned.o + obj-$(CONFIG_DM_WRITECACHE) += dm-writecache.o ++obj-$(CONFIG_DM_BOW) += dm-bow.o + + ifeq ($(CONFIG_DM_INIT),y) + dm-mod-objs += dm-init.o +diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c +new file mode 100644 +index 0000000000000..0d176aa140dfb +--- /dev/null ++++ b/drivers/md/dm-bow.c +@@ -0,0 +1,1226 @@ ++/* ++ * Copyright (C) 2018 Google Limited. ++ * ++ * This file is released under the GPL. ++ */ ++ ++#include "dm.h" ++#include "dm-core.h" ++ ++#include ++#include ++#include ++ ++#define DM_MSG_PREFIX "bow" ++ ++struct log_entry { ++ u64 source; ++ u64 dest; ++ u32 size; ++ u32 checksum; ++} __packed; ++ ++struct log_sector { ++ u32 magic; ++ u16 header_version; ++ u16 header_size; ++ u32 block_size; ++ u32 count; ++ u32 sequence; ++ sector_t sector0; ++ struct log_entry entries[]; ++} __packed; ++ ++/* ++ * MAGIC is BOW in ascii ++ */ ++#define MAGIC 0x00574f42 ++#define HEADER_VERSION 0x0100 ++ ++/* ++ * A sorted set of ranges representing the state of the data on the device. ++ * Use an rb_tree for fast lookup of a given sector ++ * Consecutive ranges are always of different type - operations on this ++ * set must merge matching consecutive ranges. ++ * ++ * Top range is always of type TOP ++ */ ++struct bow_range { ++ struct rb_node node; ++ sector_t sector; ++ enum { ++ INVALID, /* Type not set */ ++ SECTOR0, /* First sector - holds log record */ ++ SECTOR0_CURRENT,/* Live contents of sector0 */ ++ UNCHANGED, /* Original contents */ ++ TRIMMED, /* Range has been trimmed */ ++ CHANGED, /* Range has been changed */ ++ BACKUP, /* Range is being used as a backup */ ++ TOP, /* Final range - sector is size of device */ ++ } type; ++ struct list_head trimmed_list; /* list of TRIMMED ranges */ ++}; ++ ++static const char * const readable_type[] = { ++ "Invalid", ++ "Sector0", ++ "Sector0_current", ++ "Unchanged", ++ "Free", ++ "Changed", ++ "Backup", ++ "Top", ++}; ++ ++enum state { ++ TRIM, ++ CHECKPOINT, ++ COMMITTED, ++}; ++ ++struct bow_context { ++ struct dm_dev *dev; ++ u32 block_size; ++ u32 block_shift; ++ struct workqueue_struct *workqueue; ++ struct dm_bufio_client *bufio; ++ struct mutex ranges_lock; /* Hold to access this struct and/or ranges */ ++ struct rb_root ranges; ++ struct dm_kobject_holder kobj_holder; /* for sysfs attributes */ ++ atomic_t state; /* One of the enum state values above */ ++ u64 trims_total; ++ struct log_sector *log_sector; ++ struct list_head trimmed_list; ++ bool forward_trims; ++}; ++ ++sector_t range_top(struct bow_range *br) ++{ ++ return container_of(rb_next(&br->node), struct bow_range, node) ++ ->sector; ++} ++ ++u64 range_size(struct bow_range *br) ++{ ++ return (range_top(br) - br->sector) * SECTOR_SIZE; ++} ++ ++static sector_t bvec_top(struct bvec_iter *bi_iter) ++{ ++ return bi_iter->bi_sector + bi_iter->bi_size / SECTOR_SIZE; ++} ++ ++/* ++ * Find the first range that overlaps with bi_iter ++ * bi_iter is set to the size of the overlapping sub-range ++ */ ++static struct bow_range *find_first_overlapping_range(struct rb_root *ranges, ++ struct bvec_iter *bi_iter) ++{ ++ struct rb_node *node = ranges->rb_node; ++ struct bow_range *br; ++ ++ while (node) { ++ br = container_of(node, struct bow_range, node); ++ ++ if (br->sector <= bi_iter->bi_sector ++ && bi_iter->bi_sector < range_top(br)) ++ break; ++ ++ if (bi_iter->bi_sector < br->sector) ++ node = node->rb_left; ++ else ++ node = node->rb_right; ++ } ++ ++ WARN_ON(!node); ++ if (!node) ++ return NULL; ++ ++ if (range_top(br) - bi_iter->bi_sector ++ < bi_iter->bi_size >> SECTOR_SHIFT) ++ bi_iter->bi_size = (range_top(br) - bi_iter->bi_sector) ++ << SECTOR_SHIFT; ++ ++ return br; ++} ++ ++void add_before(struct rb_root *ranges, struct bow_range *new_br, ++ struct bow_range *existing) ++{ ++ struct rb_node *parent = &(existing->node); ++ struct rb_node **link = &(parent->rb_left); ++ ++ while (*link) { ++ parent = *link; ++ link = &((*link)->rb_right); ++ } ++ ++ rb_link_node(&new_br->node, parent, link); ++ rb_insert_color(&new_br->node, ranges); ++} ++ ++/* ++ * Given a range br returned by find_first_overlapping_range, split br into a ++ * leading range, a range matching the bi_iter and a trailing range. ++ * Leading and trailing may end up size 0 and will then be deleted. The ++ * new range matching the bi_iter is then returned and should have its type ++ * and type specific fields populated. ++ * If bi_iter runs off the end of the range, bi_iter is truncated accordingly ++ */ ++static int split_range(struct bow_context *bc, struct bow_range **br, ++ struct bvec_iter *bi_iter) ++{ ++ struct bow_range *new_br; ++ ++ if (bi_iter->bi_sector < (*br)->sector) { ++ WARN_ON(true); ++ return BLK_STS_IOERR; ++ } ++ ++ if (bi_iter->bi_sector > (*br)->sector) { ++ struct bow_range *leading_br = ++ kzalloc(sizeof(*leading_br), GFP_KERNEL); ++ ++ if (!leading_br) ++ return BLK_STS_RESOURCE; ++ ++ *leading_br = **br; ++ if (leading_br->type == TRIMMED) ++ list_add(&leading_br->trimmed_list, &bc->trimmed_list); ++ ++ add_before(&bc->ranges, leading_br, *br); ++ (*br)->sector = bi_iter->bi_sector; ++ } ++ ++ if (bvec_top(bi_iter) >= range_top(*br)) { ++ bi_iter->bi_size = (range_top(*br) - (*br)->sector) ++ * SECTOR_SIZE; ++ return BLK_STS_OK; ++ } ++ ++ /* new_br will be the beginning, existing br will be the tail */ ++ new_br = kzalloc(sizeof(*new_br), GFP_KERNEL); ++ if (!new_br) ++ return BLK_STS_RESOURCE; ++ ++ new_br->sector = (*br)->sector; ++ (*br)->sector = bvec_top(bi_iter); ++ add_before(&bc->ranges, new_br, *br); ++ *br = new_br; ++ ++ return BLK_STS_OK; ++} ++ ++/* ++ * Sets type of a range. May merge range into surrounding ranges ++ * Since br may be invalidated, always sets br to NULL to prevent ++ * usage after this is called ++ */ ++static void set_type(struct bow_context *bc, struct bow_range **br, int type) ++{ ++ struct bow_range *prev = container_of(rb_prev(&(*br)->node), ++ struct bow_range, node); ++ struct bow_range *next = container_of(rb_next(&(*br)->node), ++ struct bow_range, node); ++ ++ if ((*br)->type == TRIMMED) { ++ bc->trims_total -= range_size(*br); ++ list_del(&(*br)->trimmed_list); ++ } ++ ++ if (type == TRIMMED) { ++ bc->trims_total += range_size(*br); ++ list_add(&(*br)->trimmed_list, &bc->trimmed_list); ++ } ++ ++ (*br)->type = type; ++ ++ if (next->type == type) { ++ if (type == TRIMMED) ++ list_del(&next->trimmed_list); ++ rb_erase(&next->node, &bc->ranges); ++ kfree(next); ++ } ++ ++ if (prev->type == type) { ++ if (type == TRIMMED) ++ list_del(&(*br)->trimmed_list); ++ rb_erase(&(*br)->node, &bc->ranges); ++ kfree(*br); ++ } ++ ++ *br = NULL; ++} ++ ++static struct bow_range *find_free_range(struct bow_context *bc) ++{ ++ if (list_empty(&bc->trimmed_list)) { ++ DMERR("Unable to find free space to back up to"); ++ return NULL; ++ } ++ ++ return list_first_entry(&bc->trimmed_list, struct bow_range, ++ trimmed_list); ++} ++ ++static sector_t sector_to_page(struct bow_context const *bc, sector_t sector) ++{ ++ WARN_ON(sector % (bc->block_size / SECTOR_SIZE) != 0); ++ return sector >> (bc->block_shift - SECTOR_SHIFT); ++} ++ ++static int copy_data(struct bow_context const *bc, ++ struct bow_range *source, struct bow_range *dest, ++ u32 *checksum) ++{ ++ int i; ++ ++ if (range_size(source) != range_size(dest)) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ if (checksum) ++ *checksum = sector_to_page(bc, source->sector); ++ ++ for (i = 0; i < range_size(source) >> bc->block_shift; ++i) { ++ struct dm_buffer *read_buffer, *write_buffer; ++ u8 *read, *write; ++ sector_t page = sector_to_page(bc, source->sector) + i; ++ ++ read = dm_bufio_read(bc->bufio, page, &read_buffer); ++ if (IS_ERR(read)) { ++ DMERR("Cannot read page %lu", page); ++ return PTR_ERR(read); ++ } ++ ++ if (checksum) ++ *checksum = crc32(*checksum, read, bc->block_size); ++ ++ write = dm_bufio_new(bc->bufio, ++ sector_to_page(bc, dest->sector) + i, ++ &write_buffer); ++ if (IS_ERR(write)) { ++ DMERR("Cannot write sector"); ++ dm_bufio_release(read_buffer); ++ return PTR_ERR(write); ++ } ++ ++ memcpy(write, read, bc->block_size); ++ ++ dm_bufio_mark_buffer_dirty(write_buffer); ++ dm_bufio_release(write_buffer); ++ dm_bufio_release(read_buffer); ++ } ++ ++ dm_bufio_write_dirty_buffers(bc->bufio); ++ return BLK_STS_OK; ++} ++ ++/****** logging functions ******/ ++ ++static int add_log_entry(struct bow_context *bc, sector_t source, sector_t dest, ++ unsigned int size, u32 checksum); ++ ++static int backup_log_sector(struct bow_context *bc) ++{ ++ struct bow_range *first_br, *free_br; ++ struct bvec_iter bi_iter; ++ u32 checksum = 0; ++ int ret; ++ ++ first_br = container_of(rb_first(&bc->ranges), struct bow_range, node); ++ ++ if (first_br->type != SECTOR0) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ if (range_size(first_br) != bc->block_size) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ free_br = find_free_range(bc); ++ /* No space left - return this error to userspace */ ++ if (!free_br) ++ return BLK_STS_NOSPC; ++ bi_iter.bi_sector = free_br->sector; ++ bi_iter.bi_size = bc->block_size; ++ ret = split_range(bc, &free_br, &bi_iter); ++ if (ret) ++ return ret; ++ if (bi_iter.bi_size != bc->block_size) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ ret = copy_data(bc, first_br, free_br, &checksum); ++ if (ret) ++ return ret; ++ ++ bc->log_sector->count = 0; ++ bc->log_sector->sequence++; ++ ret = add_log_entry(bc, first_br->sector, free_br->sector, ++ range_size(first_br), checksum); ++ if (ret) ++ return ret; ++ ++ set_type(bc, &free_br, BACKUP); ++ return BLK_STS_OK; ++} ++ ++static int add_log_entry(struct bow_context *bc, sector_t source, sector_t dest, ++ unsigned int size, u32 checksum) ++{ ++ struct dm_buffer *sector_buffer; ++ u8 *sector; ++ ++ if (sizeof(struct log_sector) ++ + sizeof(struct log_entry) * (bc->log_sector->count + 1) ++ > bc->block_size) { ++ int ret = backup_log_sector(bc); ++ ++ if (ret) ++ return ret; ++ } ++ ++ sector = dm_bufio_new(bc->bufio, 0, §or_buffer); ++ if (IS_ERR(sector)) { ++ DMERR("Cannot write boot sector"); ++ dm_bufio_release(sector_buffer); ++ return BLK_STS_NOSPC; ++ } ++ ++ bc->log_sector->entries[bc->log_sector->count].source = source; ++ bc->log_sector->entries[bc->log_sector->count].dest = dest; ++ bc->log_sector->entries[bc->log_sector->count].size = size; ++ bc->log_sector->entries[bc->log_sector->count].checksum = checksum; ++ bc->log_sector->count++; ++ ++ memcpy(sector, bc->log_sector, bc->block_size); ++ dm_bufio_mark_buffer_dirty(sector_buffer); ++ dm_bufio_release(sector_buffer); ++ dm_bufio_write_dirty_buffers(bc->bufio); ++ return BLK_STS_OK; ++} ++ ++static int prepare_log(struct bow_context *bc) ++{ ++ struct bow_range *free_br, *first_br; ++ struct bvec_iter bi_iter; ++ u32 checksum = 0; ++ int ret; ++ ++ /* Carve out first sector as log sector */ ++ first_br = container_of(rb_first(&bc->ranges), struct bow_range, node); ++ if (first_br->type != UNCHANGED) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ if (range_size(first_br) < bc->block_size) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ bi_iter.bi_sector = 0; ++ bi_iter.bi_size = bc->block_size; ++ ret = split_range(bc, &first_br, &bi_iter); ++ if (ret) ++ return ret; ++ first_br->type = SECTOR0; ++ if (range_size(first_br) != bc->block_size) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ /* Find free sector for active sector0 reads/writes */ ++ free_br = find_free_range(bc); ++ if (!free_br) ++ return BLK_STS_NOSPC; ++ bi_iter.bi_sector = free_br->sector; ++ bi_iter.bi_size = bc->block_size; ++ ret = split_range(bc, &free_br, &bi_iter); ++ if (ret) ++ return ret; ++ free_br->type = SECTOR0_CURRENT; ++ ++ /* Copy data */ ++ ret = copy_data(bc, first_br, free_br, NULL); ++ if (ret) ++ return ret; ++ ++ bc->log_sector->sector0 = free_br->sector; ++ ++ /* Find free sector to back up original sector zero */ ++ free_br = find_free_range(bc); ++ if (!free_br) ++ return BLK_STS_NOSPC; ++ bi_iter.bi_sector = free_br->sector; ++ bi_iter.bi_size = bc->block_size; ++ ret = split_range(bc, &free_br, &bi_iter); ++ if (ret) ++ return ret; ++ ++ /* Back up */ ++ ret = copy_data(bc, first_br, free_br, &checksum); ++ if (ret) ++ return ret; ++ ++ /* ++ * Set up our replacement boot sector - it will get written when we ++ * add the first log entry, which we do immediately ++ */ ++ bc->log_sector->magic = MAGIC; ++ bc->log_sector->header_version = HEADER_VERSION; ++ bc->log_sector->header_size = sizeof(*bc->log_sector); ++ bc->log_sector->block_size = bc->block_size; ++ bc->log_sector->count = 0; ++ bc->log_sector->sequence = 0; ++ ++ /* Add log entry */ ++ ret = add_log_entry(bc, first_br->sector, free_br->sector, ++ range_size(first_br), checksum); ++ if (ret) ++ return ret; ++ ++ set_type(bc, &free_br, BACKUP); ++ return BLK_STS_OK; ++} ++ ++static struct bow_range *find_sector0_current(struct bow_context *bc) ++{ ++ struct bvec_iter bi_iter; ++ ++ bi_iter.bi_sector = bc->log_sector->sector0; ++ bi_iter.bi_size = bc->block_size; ++ return find_first_overlapping_range(&bc->ranges, &bi_iter); ++} ++ ++/****** sysfs interface functions ******/ ++ ++static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf) ++{ ++ struct bow_context *bc = container_of(kobj, struct bow_context, ++ kobj_holder.kobj); ++ ++ return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&bc->state)); ++} ++ ++static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct bow_context *bc = container_of(kobj, struct bow_context, ++ kobj_holder.kobj); ++ enum state state, original_state; ++ int ret; ++ ++ state = buf[0] - '0'; ++ if (state < TRIM || state > COMMITTED) { ++ DMERR("State value %d out of range", state); ++ return -EINVAL; ++ } ++ ++ mutex_lock(&bc->ranges_lock); ++ original_state = atomic_read(&bc->state); ++ if (state != original_state + 1) { ++ DMERR("Invalid state change from %d to %d", ++ original_state, state); ++ ret = -EINVAL; ++ goto bad; ++ } ++ ++ DMINFO("Switching to state %s", state == CHECKPOINT ? "Checkpoint" ++ : state == COMMITTED ? "Committed" : "Unknown"); ++ ++ if (state == CHECKPOINT) { ++ ret = prepare_log(bc); ++ if (ret) { ++ DMERR("Failed to switch to checkpoint state"); ++ goto bad; ++ } ++ } else if (state == COMMITTED) { ++ struct bow_range *br = find_sector0_current(bc); ++ struct bow_range *sector0_br = ++ container_of(rb_first(&bc->ranges), struct bow_range, ++ node); ++ ++ ret = copy_data(bc, br, sector0_br, 0); ++ if (ret) { ++ DMERR("Failed to switch to committed state"); ++ goto bad; ++ } ++ } ++ atomic_inc(&bc->state); ++ ret = count; ++ ++bad: ++ mutex_unlock(&bc->ranges_lock); ++ return ret; ++} ++ ++static ssize_t free_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf) ++{ ++ struct bow_context *bc = container_of(kobj, struct bow_context, ++ kobj_holder.kobj); ++ u64 trims_total; ++ ++ mutex_lock(&bc->ranges_lock); ++ trims_total = bc->trims_total; ++ mutex_unlock(&bc->ranges_lock); ++ ++ return scnprintf(buf, PAGE_SIZE, "%llu\n", trims_total); ++} ++ ++static struct kobj_attribute attr_state = __ATTR_RW(state); ++static struct kobj_attribute attr_free = __ATTR_RO(free); ++ ++static struct attribute *bow_attrs[] = { ++ &attr_state.attr, ++ &attr_free.attr, ++ NULL ++}; ++ ++static struct kobj_type bow_ktype = { ++ .sysfs_ops = &kobj_sysfs_ops, ++ .default_attrs = bow_attrs, ++ .release = dm_kobject_release ++}; ++ ++/****** constructor/destructor ******/ ++ ++static void dm_bow_dtr(struct dm_target *ti) ++{ ++ struct bow_context *bc = (struct bow_context *) ti->private; ++ struct kobject *kobj; ++ ++ while (rb_first(&bc->ranges)) { ++ struct bow_range *br = container_of(rb_first(&bc->ranges), ++ struct bow_range, node); ++ ++ rb_erase(&br->node, &bc->ranges); ++ kfree(br); ++ } ++ if (bc->workqueue) ++ destroy_workqueue(bc->workqueue); ++ if (bc->bufio) ++ dm_bufio_client_destroy(bc->bufio); ++ ++ kobj = &bc->kobj_holder.kobj; ++ if (kobj->state_initialized) { ++ kobject_put(kobj); ++ wait_for_completion(dm_get_completion_from_kobject(kobj)); ++ } ++ ++ kfree(bc->log_sector); ++ kfree(bc); ++} ++ ++static int dm_bow_ctr(struct dm_target *ti, unsigned int argc, char **argv) ++{ ++ struct bow_context *bc; ++ struct bow_range *br; ++ int ret; ++ struct mapped_device *md = dm_table_get_md(ti->table); ++ ++ if (argc != 1) { ++ ti->error = "Invalid argument count"; ++ return -EINVAL; ++ } ++ ++ bc = kzalloc(sizeof(*bc), GFP_KERNEL); ++ if (!bc) { ++ ti->error = "Cannot allocate bow context"; ++ return -ENOMEM; ++ } ++ ++ ti->num_flush_bios = 1; ++ ti->num_discard_bios = 1; ++ ti->num_write_same_bios = 1; ++ ti->private = bc; ++ ++ ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), ++ &bc->dev); ++ if (ret) { ++ ti->error = "Device lookup failed"; ++ goto bad; ++ } ++ ++ if (bc->dev->bdev->bd_queue->limits.max_discard_sectors == 0) { ++ bc->dev->bdev->bd_queue->limits.discard_granularity = 1 << 12; ++ bc->dev->bdev->bd_queue->limits.max_hw_discard_sectors = 1 << 15; ++ bc->dev->bdev->bd_queue->limits.max_discard_sectors = 1 << 15; ++ bc->forward_trims = false; ++ } else { ++ bc->forward_trims = true; ++ } ++ ++ bc->block_size = bc->dev->bdev->bd_queue->limits.logical_block_size; ++ bc->block_shift = ilog2(bc->block_size); ++ bc->log_sector = kzalloc(bc->block_size, GFP_KERNEL); ++ if (!bc->log_sector) { ++ ti->error = "Cannot allocate log sector"; ++ goto bad; ++ } ++ ++ init_completion(&bc->kobj_holder.completion); ++ ret = kobject_init_and_add(&bc->kobj_holder.kobj, &bow_ktype, ++ &disk_to_dev(dm_disk(md))->kobj, "%s", ++ "bow"); ++ if (ret) { ++ ti->error = "Cannot create sysfs node"; ++ goto bad; ++ } ++ ++ mutex_init(&bc->ranges_lock); ++ bc->ranges = RB_ROOT; ++ bc->bufio = dm_bufio_client_create(bc->dev->bdev, bc->block_size, 1, 0, ++ NULL, NULL); ++ if (IS_ERR(bc->bufio)) { ++ ti->error = "Cannot initialize dm-bufio"; ++ ret = PTR_ERR(bc->bufio); ++ bc->bufio = NULL; ++ goto bad; ++ } ++ ++ bc->workqueue = alloc_workqueue("dm-bow", ++ WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM ++ | WQ_UNBOUND, num_online_cpus()); ++ if (!bc->workqueue) { ++ ti->error = "Cannot allocate workqueue"; ++ ret = -ENOMEM; ++ goto bad; ++ } ++ ++ INIT_LIST_HEAD(&bc->trimmed_list); ++ ++ br = kzalloc(sizeof(*br), GFP_KERNEL); ++ if (!br) { ++ ti->error = "Cannot allocate ranges"; ++ ret = -ENOMEM; ++ goto bad; ++ } ++ ++ br->sector = ti->len; ++ br->type = TOP; ++ rb_link_node(&br->node, NULL, &bc->ranges.rb_node); ++ rb_insert_color(&br->node, &bc->ranges); ++ ++ br = kzalloc(sizeof(*br), GFP_KERNEL); ++ if (!br) { ++ ti->error = "Cannot allocate ranges"; ++ ret = -ENOMEM; ++ goto bad; ++ } ++ ++ br->sector = 0; ++ br->type = UNCHANGED; ++ rb_link_node(&br->node, bc->ranges.rb_node, ++ &bc->ranges.rb_node->rb_left); ++ rb_insert_color(&br->node, &bc->ranges); ++ ++ ti->discards_supported = true; ++ ++ return 0; ++ ++bad: ++ dm_bow_dtr(ti); ++ return ret; ++} ++ ++/****** Handle writes ******/ ++ ++static int prepare_unchanged_range(struct bow_context *bc, struct bow_range *br, ++ struct bvec_iter *bi_iter, ++ bool record_checksum) ++{ ++ struct bow_range *backup_br; ++ struct bvec_iter backup_bi; ++ sector_t log_source, log_dest; ++ unsigned int log_size; ++ u32 checksum = 0; ++ int ret; ++ int original_type; ++ sector_t sector0; ++ ++ /* Find a free range */ ++ backup_br = find_free_range(bc); ++ if (!backup_br) ++ return BLK_STS_NOSPC; ++ ++ /* Carve out a backup range. This may be smaller than the br given */ ++ backup_bi.bi_sector = backup_br->sector; ++ backup_bi.bi_size = min(range_size(backup_br), (u64) bi_iter->bi_size); ++ ret = split_range(bc, &backup_br, &backup_bi); ++ if (ret) ++ return ret; ++ ++ /* ++ * Carve out a changed range. This will not be smaller than the backup ++ * br since the backup br is smaller than the source range and iterator ++ */ ++ bi_iter->bi_size = backup_bi.bi_size; ++ ret = split_range(bc, &br, bi_iter); ++ if (ret) ++ return ret; ++ if (range_size(br) != range_size(backup_br)) { ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++ ++ ++ /* Copy data over */ ++ ret = copy_data(bc, br, backup_br, record_checksum ? &checksum : NULL); ++ if (ret) ++ return ret; ++ ++ /* Add an entry to the log */ ++ log_source = br->sector; ++ log_dest = backup_br->sector; ++ log_size = range_size(br); ++ ++ /* ++ * Set the types. Note that since set_type also amalgamates ranges ++ * we have to set both sectors to their final type before calling ++ * set_type on either ++ */ ++ original_type = br->type; ++ sector0 = backup_br->sector; ++ if (backup_br->type == TRIMMED) ++ list_del(&backup_br->trimmed_list); ++ backup_br->type = br->type == SECTOR0_CURRENT ? SECTOR0_CURRENT ++ : BACKUP; ++ br->type = CHANGED; ++ set_type(bc, &backup_br, backup_br->type); ++ ++ /* ++ * Add the log entry after marking the backup sector, since adding a log ++ * can cause another backup ++ */ ++ ret = add_log_entry(bc, log_source, log_dest, log_size, checksum); ++ if (ret) { ++ br->type = original_type; ++ return ret; ++ } ++ ++ /* Now it is safe to mark this backup successful */ ++ if (original_type == SECTOR0_CURRENT) ++ bc->log_sector->sector0 = sector0; ++ ++ set_type(bc, &br, br->type); ++ return ret; ++} ++ ++static int prepare_free_range(struct bow_context *bc, struct bow_range *br, ++ struct bvec_iter *bi_iter) ++{ ++ int ret; ++ ++ ret = split_range(bc, &br, bi_iter); ++ if (ret) ++ return ret; ++ set_type(bc, &br, CHANGED); ++ return BLK_STS_OK; ++} ++ ++static int prepare_changed_range(struct bow_context *bc, struct bow_range *br, ++ struct bvec_iter *bi_iter) ++{ ++ /* Nothing to do ... */ ++ return BLK_STS_OK; ++} ++ ++static int prepare_one_range(struct bow_context *bc, ++ struct bvec_iter *bi_iter) ++{ ++ struct bow_range *br = find_first_overlapping_range(&bc->ranges, ++ bi_iter); ++ switch (br->type) { ++ case CHANGED: ++ return prepare_changed_range(bc, br, bi_iter); ++ ++ case TRIMMED: ++ return prepare_free_range(bc, br, bi_iter); ++ ++ case UNCHANGED: ++ case BACKUP: ++ return prepare_unchanged_range(bc, br, bi_iter, true); ++ ++ /* ++ * We cannot track the checksum for the active sector0, since it ++ * may change at any point. ++ */ ++ case SECTOR0_CURRENT: ++ return prepare_unchanged_range(bc, br, bi_iter, false); ++ ++ case SECTOR0: /* Handled in the dm_bow_map */ ++ case TOP: /* Illegal - top is off the end of the device */ ++ default: ++ WARN_ON(1); ++ return BLK_STS_IOERR; ++ } ++} ++ ++struct write_work { ++ struct work_struct work; ++ struct bow_context *bc; ++ struct bio *bio; ++}; ++ ++static void bow_write(struct work_struct *work) ++{ ++ struct write_work *ww = container_of(work, struct write_work, work); ++ struct bow_context *bc = ww->bc; ++ struct bio *bio = ww->bio; ++ struct bvec_iter bi_iter = bio->bi_iter; ++ int ret = BLK_STS_OK; ++ ++ kfree(ww); ++ ++ mutex_lock(&bc->ranges_lock); ++ do { ++ ret = prepare_one_range(bc, &bi_iter); ++ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; ++ bi_iter.bi_size = bio->bi_iter.bi_size ++ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) ++ * SECTOR_SIZE; ++ } while (!ret && bi_iter.bi_size); ++ ++ mutex_unlock(&bc->ranges_lock); ++ ++ if (!ret) { ++ bio_set_dev(bio, bc->dev->bdev); ++ submit_bio(bio); ++ } else { ++ DMERR("Write failure with error %d", -ret); ++ bio->bi_status = ret; ++ bio_endio(bio); ++ } ++} ++ ++static int queue_write(struct bow_context *bc, struct bio *bio) ++{ ++ struct write_work *ww = kmalloc(sizeof(*ww), GFP_NOIO | __GFP_NORETRY ++ | __GFP_NOMEMALLOC | __GFP_NOWARN); ++ if (!ww) { ++ DMERR("Failed to allocate write_work"); ++ return -ENOMEM; ++ } ++ ++ INIT_WORK(&ww->work, bow_write); ++ ww->bc = bc; ++ ww->bio = bio; ++ queue_work(bc->workqueue, &ww->work); ++ return DM_MAPIO_SUBMITTED; ++} ++ ++static int handle_sector0(struct bow_context *bc, struct bio *bio) ++{ ++ int ret = DM_MAPIO_REMAPPED; ++ ++ if (bio->bi_iter.bi_size > bc->block_size) { ++ struct bio * split = bio_split(bio, ++ bc->block_size >> SECTOR_SHIFT, ++ GFP_NOIO, ++ &fs_bio_set); ++ if (!split) { ++ DMERR("Failed to split bio"); ++ bio->bi_status = BLK_STS_RESOURCE; ++ bio_endio(bio); ++ return DM_MAPIO_SUBMITTED; ++ } ++ ++ bio_chain(split, bio); ++ split->bi_iter.bi_sector = bc->log_sector->sector0; ++ bio_set_dev(split, bc->dev->bdev); ++ submit_bio(split); ++ ++ if (bio_data_dir(bio) == WRITE) ++ ret = queue_write(bc, bio); ++ } else { ++ bio->bi_iter.bi_sector = bc->log_sector->sector0; ++ } ++ ++ return ret; ++} ++ ++static int add_trim(struct bow_context *bc, struct bio *bio) ++{ ++ struct bow_range *br; ++ struct bvec_iter bi_iter = bio->bi_iter; ++ ++ DMDEBUG("add_trim: %lu, %u", ++ bio->bi_iter.bi_sector, bio->bi_iter.bi_size); ++ ++ do { ++ br = find_first_overlapping_range(&bc->ranges, &bi_iter); ++ ++ switch (br->type) { ++ case UNCHANGED: ++ if (!split_range(bc, &br, &bi_iter)) ++ set_type(bc, &br, TRIMMED); ++ break; ++ ++ case TRIMMED: ++ /* Nothing to do */ ++ break; ++ ++ default: ++ /* No other case is legal in TRIM state */ ++ WARN_ON(true); ++ break; ++ } ++ ++ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; ++ bi_iter.bi_size = bio->bi_iter.bi_size ++ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) ++ * SECTOR_SIZE; ++ ++ } while (bi_iter.bi_size); ++ ++ bio_endio(bio); ++ return DM_MAPIO_SUBMITTED; ++} ++ ++static int remove_trim(struct bow_context *bc, struct bio *bio) ++{ ++ struct bow_range *br; ++ struct bvec_iter bi_iter = bio->bi_iter; ++ ++ DMDEBUG("remove_trim: %lu, %u", ++ bio->bi_iter.bi_sector, bio->bi_iter.bi_size); ++ ++ do { ++ br = find_first_overlapping_range(&bc->ranges, &bi_iter); ++ ++ switch (br->type) { ++ case UNCHANGED: ++ /* Nothing to do */ ++ break; ++ ++ case TRIMMED: ++ if (!split_range(bc, &br, &bi_iter)) ++ set_type(bc, &br, UNCHANGED); ++ break; ++ ++ default: ++ /* No other case is legal in TRIM state */ ++ WARN_ON(true); ++ break; ++ } ++ ++ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; ++ bi_iter.bi_size = bio->bi_iter.bi_size ++ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) ++ * SECTOR_SIZE; ++ ++ } while (bi_iter.bi_size); ++ ++ return DM_MAPIO_REMAPPED; ++} ++ ++int remap_unless_illegal_trim(struct bow_context *bc, struct bio *bio) ++{ ++ if (!bc->forward_trims && bio_op(bio) == REQ_OP_DISCARD) { ++ bio->bi_status = BLK_STS_NOTSUPP; ++ bio_endio(bio); ++ return DM_MAPIO_SUBMITTED; ++ } else { ++ bio_set_dev(bio, bc->dev->bdev); ++ return DM_MAPIO_REMAPPED; ++ } ++} ++ ++/****** dm interface ******/ ++ ++static int dm_bow_map(struct dm_target *ti, struct bio *bio) ++{ ++ int ret = DM_MAPIO_REMAPPED; ++ struct bow_context *bc = ti->private; ++ ++ if (likely(bc->state.counter == COMMITTED)) ++ return remap_unless_illegal_trim(bc, bio); ++ ++ if (bio_data_dir(bio) == READ && bio->bi_iter.bi_sector != 0) ++ return remap_unless_illegal_trim(bc, bio); ++ ++ if (atomic_read(&bc->state) != COMMITTED) { ++ enum state state; ++ ++ mutex_lock(&bc->ranges_lock); ++ state = atomic_read(&bc->state); ++ if (state == TRIM) { ++ if (bio_op(bio) == REQ_OP_DISCARD) ++ ret = add_trim(bc, bio); ++ else if (bio_data_dir(bio) == WRITE) ++ ret = remove_trim(bc, bio); ++ else ++ /* pass-through */; ++ } else if (state == CHECKPOINT) { ++ if (bio->bi_iter.bi_sector == 0) ++ ret = handle_sector0(bc, bio); ++ else if (bio_data_dir(bio) == WRITE) ++ ret = queue_write(bc, bio); ++ else ++ /* pass-through */; ++ } else { ++ /* pass-through */ ++ } ++ mutex_unlock(&bc->ranges_lock); ++ } ++ ++ if (ret == DM_MAPIO_REMAPPED) ++ return remap_unless_illegal_trim(bc, bio); ++ ++ return ret; ++} ++ ++static void dm_bow_tablestatus(struct dm_target *ti, char *result, ++ unsigned int maxlen) ++{ ++ char *end = result + maxlen; ++ struct bow_context *bc = ti->private; ++ struct rb_node *i; ++ int trimmed_list_length = 0; ++ int trimmed_range_count = 0; ++ struct bow_range *br; ++ ++ if (maxlen == 0) ++ return; ++ result[0] = 0; ++ ++ list_for_each_entry(br, &bc->trimmed_list, trimmed_list) ++ if (br->type == TRIMMED) { ++ ++trimmed_list_length; ++ } else { ++ scnprintf(result, end - result, ++ "ERROR: non-trimmed entry in trimmed_list"); ++ return; ++ } ++ ++ if (!rb_first(&bc->ranges)) { ++ scnprintf(result, end - result, "ERROR: Empty ranges"); ++ return; ++ } ++ ++ if (container_of(rb_first(&bc->ranges), struct bow_range, node) ++ ->sector) { ++ scnprintf(result, end - result, ++ "ERROR: First range does not start at sector 0"); ++ return; ++ } ++ ++ for (i = rb_first(&bc->ranges); i; i = rb_next(i)) { ++ struct bow_range *br = container_of(i, struct bow_range, node); ++ ++ result += scnprintf(result, end - result, "%s: %lu", ++ readable_type[br->type], br->sector); ++ if (result >= end) ++ return; ++ ++ result += scnprintf(result, end - result, "\n"); ++ if (result >= end) ++ return; ++ ++ if (br->type == TRIMMED) ++ ++trimmed_range_count; ++ ++ if (br->type == TOP) { ++ if (br->sector != ti->len) { ++ scnprintf(result, end - result, ++ "\nERROR: Top sector is incorrect"); ++ } ++ ++ if (&br->node != rb_last(&bc->ranges)) { ++ scnprintf(result, end - result, ++ "\nERROR: Top sector is not last"); ++ } ++ ++ break; ++ } ++ ++ if (!rb_next(i)) { ++ scnprintf(result, end - result, ++ "\nERROR: Last range not of type TOP"); ++ return; ++ } ++ ++ if (br->sector > range_top(br)) { ++ scnprintf(result, end - result, ++ "\nERROR: sectors out of order"); ++ return; ++ } ++ } ++ ++ if (trimmed_range_count != trimmed_list_length) ++ scnprintf(result, end - result, ++ "\nERROR: not all trimmed ranges in trimmed list"); ++} ++ ++static void dm_bow_status(struct dm_target *ti, status_type_t type, ++ unsigned int status_flags, char *result, ++ unsigned int maxlen) ++{ ++ switch (type) { ++ case STATUSTYPE_INFO: ++ if (maxlen) ++ result[0] = 0; ++ break; ++ ++ case STATUSTYPE_TABLE: ++ dm_bow_tablestatus(ti, result, maxlen); ++ break; ++ } ++} ++ ++int dm_bow_prepare_ioctl(struct dm_target *ti, struct block_device **bdev) ++{ ++ struct bow_context *bc = ti->private; ++ struct dm_dev *dev = bc->dev; ++ ++ *bdev = dev->bdev; ++ /* Only pass ioctls through if the device sizes match exactly. */ ++ return ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT; ++} ++ ++static int dm_bow_iterate_devices(struct dm_target *ti, ++ iterate_devices_callout_fn fn, void *data) ++{ ++ struct bow_context *bc = ti->private; ++ ++ return fn(ti, bc->dev, 0, ti->len, data); ++} ++ ++static struct target_type bow_target = { ++ .name = "bow", ++ .version = {1, 1, 1}, ++ .module = THIS_MODULE, ++ .ctr = dm_bow_ctr, ++ .dtr = dm_bow_dtr, ++ .map = dm_bow_map, ++ .status = dm_bow_status, ++ .prepare_ioctl = dm_bow_prepare_ioctl, ++ .iterate_devices = dm_bow_iterate_devices, ++}; ++ ++int __init dm_bow_init(void) ++{ ++ int r = dm_register_target(&bow_target); ++ ++ if (r < 0) ++ DMERR("registering bow failed %d", r); ++ return r; ++} ++ ++void dm_bow_exit(void) ++{ ++ dm_unregister_target(&bow_target); ++} ++ ++MODULE_LICENSE("GPL"); ++ ++module_init(dm_bow_init); ++module_exit(dm_bow_exit); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch b/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch new file mode 100644 index 000000000000..a2f1464569f7 --- /dev/null +++ b/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch @@ -0,0 +1,79 @@ +From 8f9c80dc525828562ba9ec7c6a8fd17c11745cda Mon Sep 17 00:00:00 2001 +From: Paul Lawrence +Date: Tue, 26 Mar 2019 09:05:55 -0700 +Subject: ANDROID: dm-bow: Fix 32 bit compile errors + +See https://www.kernel.org/doc/html/v4.17/core-api/printk-formats.html + +Also 64-bit modulus not defined on 32-bit architectures + +Test: i386_defconfig and x86_64_cuttlefish_defconfig compile +Change-Id: I57b9372e12e97b9a18232191b525e7601bc57a24 +Signed-off-by: Paul Lawrence +--- + drivers/md/dm-bow.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c +index 0d176aa140dfb..9323c7c8580d4 100644 +--- a/drivers/md/dm-bow.c ++++ b/drivers/md/dm-bow.c +@@ -266,7 +266,8 @@ static struct bow_range *find_free_range(struct bow_context *bc) + + static sector_t sector_to_page(struct bow_context const *bc, sector_t sector) + { +- WARN_ON(sector % (bc->block_size / SECTOR_SIZE) != 0); ++ WARN_ON((sector & (((sector_t)1 << (bc->block_shift - SECTOR_SHIFT)) - 1)) ++ != 0); + return sector >> (bc->block_shift - SECTOR_SHIFT); + } + +@@ -291,7 +292,8 @@ static int copy_data(struct bow_context const *bc, + + read = dm_bufio_read(bc->bufio, page, &read_buffer); + if (IS_ERR(read)) { +- DMERR("Cannot read page %lu", page); ++ DMERR("Cannot read page %llu", ++ (unsigned long long)page); + return PTR_ERR(read); + } + +@@ -952,8 +954,9 @@ static int add_trim(struct bow_context *bc, struct bio *bio) + struct bow_range *br; + struct bvec_iter bi_iter = bio->bi_iter; + +- DMDEBUG("add_trim: %lu, %u", +- bio->bi_iter.bi_sector, bio->bi_iter.bi_size); ++ DMDEBUG("add_trim: %llu, %u", ++ (unsigned long long)bio->bi_iter.bi_sector, ++ bio->bi_iter.bi_size); + + do { + br = find_first_overlapping_range(&bc->ranges, &bi_iter); +@@ -990,8 +993,9 @@ static int remove_trim(struct bow_context *bc, struct bio *bio) + struct bow_range *br; + struct bvec_iter bi_iter = bio->bi_iter; + +- DMDEBUG("remove_trim: %lu, %u", +- bio->bi_iter.bi_sector, bio->bi_iter.bi_size); ++ DMDEBUG("remove_trim: %llu, %u", ++ (unsigned long long)bio->bi_iter.bi_sector, ++ bio->bi_iter.bi_size); + + do { + br = find_first_overlapping_range(&bc->ranges, &bi_iter); +@@ -1116,8 +1120,9 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result, + for (i = rb_first(&bc->ranges); i; i = rb_next(i)) { + struct bow_range *br = container_of(i, struct bow_range, node); + +- result += scnprintf(result, end - result, "%s: %lu", +- readable_type[br->type], br->sector); ++ result += scnprintf(result, end - result, "%s: %llu", ++ readable_type[br->type], ++ (unsigned long long)br->sector); + if (result >= end) + return; + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with.patch b/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with.patch new file mode 100644 index 000000000000..925dfbb546c1 --- /dev/null +++ b/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with.patch @@ -0,0 +1,46 @@ +From 2896f095a7d4d12ece9b30573340021bd710fbbf Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Wed, 19 Jun 2019 15:37:13 -0700 +Subject: ANDROID: dma-buf: Add support for mapping buffers + with DMA attributes + +When mapping the memory represented by a dma-buf into a device's +address space, it might be desireable to map the memory with +certain DMA attributes. Thus, introduce the dma_mapping_attrs +field in the dma_buf_attachment structure so that when +the memory is mapped with dma_buf_map_attachment, it is mapped +with the desired DMA attributes. + +Bug: 133508579 +Test: ion-unit-tests +Change-Id: Ib2e5bafdc02ae31a58ce96a82d77cc508dd71bd4 +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + include/linux/dma-buf.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h +index 432697b212c7e..5d3fe7ccc749d 100644 +--- a/include/linux/dma-buf.h ++++ b/include/linux/dma-buf.h +@@ -384,6 +384,8 @@ struct dma_buf { + * @sgt: cached mapping. + * @dir: direction of cached mapping. + * @priv: exporter specific attachment data. ++ * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer ++ * through dma_buf_map_attachment. + * + * This structure holds the attachment information between the dma_buf buffer + * and its user device(s). The list contains one attachment struct per device +@@ -401,6 +403,7 @@ struct dma_buf_attachment { + struct sg_table *sgt; + enum dma_data_direction dir; + void *priv; ++ unsigned long dma_map_attrs; + }; + + /** +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-dma-buf-Add-support-for-partial-cache-mainte.patch b/patches/ANDROID-dma-buf-Add-support-for-partial-cache-mainte.patch new file mode 100644 index 000000000000..54dbd2554827 --- /dev/null +++ b/patches/ANDROID-dma-buf-Add-support-for-partial-cache-mainte.patch @@ -0,0 +1,174 @@ +From b671f302714caee55532c225345f1269c0294582 Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Wed, 19 Jun 2019 15:37:11 -0700 +Subject: ANDROID: dma-buf: Add support for partial cache + maintenance + +In order to improve performance, allow dma-buf clients to +apply cache maintenance to only a subset of a dma-buf. + +Kernel clients will be able to use the dma_buf_begin_cpu_access_partial +and dma_buf_end_cpu_access_partial functions to only apply cache +maintenance to a range within the dma-buf. + +Bug: 133508579 +Test: ion-unit-tests +Change-Id: Icce61fc21b1542f5248daea34f713184449a62c3 +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/dma-buf/dma-buf.c | 40 +++++++++++++++++++++++++ + include/linux/dma-buf.h | 63 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 103 insertions(+) + +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index f45bfb29ef960..22d321b743f89 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -957,6 +957,30 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + } + EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); + ++int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, ++ enum dma_data_direction direction, ++ unsigned int offset, unsigned int len) ++{ ++ int ret = 0; ++ ++ if (WARN_ON(!dmabuf)) ++ return -EINVAL; ++ ++ if (dmabuf->ops->begin_cpu_access_partial) ++ ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction, ++ offset, len); ++ ++ /* Ensure that all fences are waited upon - but we first allow ++ * the native handler the chance to do so more efficiently if it ++ * chooses. A double invocation here will be reasonably cheap no-op. ++ */ ++ if (ret == 0) ++ ret = __dma_buf_begin_cpu_access(dmabuf, direction); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access_partial); ++ + /** + * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the + * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific +@@ -983,6 +1007,22 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf, + } + EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); + ++int dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, ++ enum dma_data_direction direction, ++ unsigned int offset, unsigned int len) ++{ ++ int ret = 0; ++ ++ WARN_ON(!dmabuf); ++ ++ if (dmabuf->ops->end_cpu_access_partial) ++ ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction, ++ offset, len); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial); ++ + /** + * dma_buf_kmap - Map a page of the buffer object into kernel address space. The + * same restrictions as for kmap and friends apply. +diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h +index bae060fae8629..432697b212c7e 100644 +--- a/include/linux/dma-buf.h ++++ b/include/linux/dma-buf.h +@@ -178,6 +178,41 @@ struct dma_buf_ops { + */ + int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); + ++ /** ++ * @begin_cpu_access_partial: ++ * ++ * This is called from dma_buf_begin_cpu_access_partial() and allows the ++ * exporter to ensure that the memory specified in the range is ++ * available for cpu access - the exporter might need to allocate or ++ * swap-in and pin the backing storage. ++ * The exporter also needs to ensure that cpu access is ++ * coherent for the access direction. The direction can be used by the ++ * exporter to optimize the cache flushing, i.e. access with a different ++ * direction (read instead of write) might return stale or even bogus ++ * data (e.g. when the exporter needs to copy the data to temporary ++ * storage). ++ * ++ * This callback is optional. ++ * ++ * FIXME: This is both called through the DMA_BUF_IOCTL_SYNC command ++ * from userspace (where storage shouldn't be pinned to avoid handing ++ * de-factor mlock rights to userspace) and for the kernel-internal ++ * users of the various kmap interfaces, where the backing storage must ++ * be pinned to guarantee that the atomic kmap calls can succeed. Since ++ * there's no in-kernel users of the kmap interfaces yet this isn't a ++ * real problem. ++ * ++ * Returns: ++ * ++ * 0 on success or a negative error code on failure. This can for ++ * example fail when the backing storage can't be allocated. Can also ++ * return -ERESTARTSYS or -EINTR when the call has been interrupted and ++ * needs to be restarted. ++ */ ++ int (*begin_cpu_access_partial)(struct dma_buf *dmabuf, ++ enum dma_data_direction, ++ unsigned int offset, unsigned int len); ++ + /** + * @end_cpu_access: + * +@@ -197,6 +232,28 @@ struct dma_buf_ops { + */ + int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); + ++ /** ++ * @end_cpu_access_partial: ++ * ++ * This is called from dma_buf_end_cpu_access_partial() when the ++ * importer is done accessing the CPU. The exporter can use to limit ++ * cache flushing to only the range specefied and to unpin any ++ * resources pinned in @begin_cpu_access_umapped. ++ * The result of any dma_buf kmap calls after end_cpu_access_partial is ++ * undefined. ++ * ++ * This callback is optional. ++ * ++ * Returns: ++ * ++ * 0 on success or a negative error code on failure. Can return ++ * -ERESTARTSYS or -EINTR when the call has been interrupted and needs ++ * to be restarted. ++ */ ++ int (*end_cpu_access_partial)(struct dma_buf *dmabuf, ++ enum dma_data_direction, ++ unsigned int offset, unsigned int len); ++ + /** + * @mmap: + * +@@ -411,8 +468,14 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, + enum dma_data_direction); + int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, + enum dma_data_direction dir); ++int dma_buf_begin_cpu_access_partial(struct dma_buf *dma_buf, ++ enum dma_data_direction dir, ++ unsigned int offset, unsigned int len); + int dma_buf_end_cpu_access(struct dma_buf *dma_buf, + enum dma_data_direction dir); ++int dma_buf_end_cpu_access_partial(struct dma_buf *dma_buf, ++ enum dma_data_direction dir, ++ unsigned int offset, unsigned int len); + void *dma_buf_kmap(struct dma_buf *, unsigned long); + void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-.patch b/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-.patch new file mode 100644 index 000000000000..90cef7f0c3eb --- /dev/null +++ b/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-.patch @@ -0,0 +1,80 @@ +From bd835cc2763e8551a92d8483b500544261e1be90 Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Wed, 19 Jun 2019 15:37:12 -0700 +Subject: ANDROID: dma-buf: Add support to get flags associated + with a buffer + +Allow kernel clients to get the flags associated with a buffer +that is wrapped by a dma-buf. This information can be used to +communicate the type of memory associated with the +buffer(e.g. uncached vs cached memory). + +Bug: 133508579 +Test: ion-unit-tests +Change-Id: I82eab8beb738b258616c22a01080615d7ffb6ad5 +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/dma-buf/dma-buf.c | 14 ++++++++++++++ + include/linux/dma-buf.h | 15 +++++++++++++++ + 2 files changed, 29 insertions(+) + +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index 22d321b743f89..d0f6e7290bcdb 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -1188,6 +1188,20 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) + } + EXPORT_SYMBOL_GPL(dma_buf_vunmap); + ++int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) ++{ ++ int ret = 0; ++ ++ if (WARN_ON(!dmabuf) || !flags) ++ return -EINVAL; ++ ++ if (dmabuf->ops->get_flags) ++ ret = dmabuf->ops->get_flags(dmabuf, flags); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(dma_buf_get_flags); ++ + #ifdef CONFIG_DEBUG_FS + static int dma_buf_debug_show(struct seq_file *s, void *unused) + { +diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h +index 5d3fe7ccc749d..1e148a48d7064 100644 +--- a/include/linux/dma-buf.h ++++ b/include/linux/dma-buf.h +@@ -318,6 +318,20 @@ struct dma_buf_ops { + + void *(*vmap)(struct dma_buf *); + void (*vunmap)(struct dma_buf *, void *vaddr); ++ ++ /** ++ * @get_flags: ++ * ++ * This is called by dma_buf_get_flags and is used to get the buffer's ++ * flags. ++ * This callback is optional. ++ * ++ * Returns: ++ * ++ * 0 on success or a negative error code on failure. On success flags ++ * will be populated with the buffer's flags. ++ */ ++ int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags); + }; + + /** +@@ -486,4 +500,5 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, + unsigned long); + void *dma_buf_vmap(struct dma_buf *); + void dma_buf_vunmap(struct dma_buf *, void *vaddr); ++int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags); + #endif /* __DMA_BUF_H__ */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch b/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch new file mode 100644 index 000000000000..2aeb1cc55331 --- /dev/null +++ b/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch @@ -0,0 +1,111 @@ +From a0d4dd90005235d67ef015eb402160d66c37a38f Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Thu, 29 Aug 2019 19:15:01 -0700 +Subject: ANDROID: first pass cuttlefish GKI modularization + +Bug: 132629930 +Signed-off-by: Ram Muthiah +Change-Id: Ie2a4d08596b0e2af7c868224bc18dcd6adae7ee0 +--- + arch/x86/configs/gki_defconfig | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 6b0ff4ca236ab..a37fa09bd107a 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -155,8 +155,12 @@ CONFIG_NET_CLS_BPF=y + CONFIG_NET_EMATCH=y + CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y +-CONFIG_VSOCKETS=y +-CONFIG_VIRTIO_VSOCKETS=y ++CONFIG_VSOCKETS=m ++CONFIG_VIRTIO_VSOCKETS=m ++CONFIG_CAN=m ++# CONFIG_CAN_BCM is not set ++# CONFIG_CAN_GW is not set ++CONFIG_CAN_VCAN=m + CONFIG_CFG80211=y + # CONFIG_CFG80211_DEFAULT_PS is not set + # CONFIG_CFG80211_CRDA_SUPPORT is not set +@@ -170,7 +174,7 @@ CONFIG_ZRAM=y + CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_SIZE=8192 +-CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_BLK=m + CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + # CONFIG_SCSI_PROC_FS is not set +@@ -185,7 +189,7 @@ CONFIG_DM_VERITY_FEC=y + CONFIG_DM_BOW=y + CONFIG_NETDEVICES=y + CONFIG_TUN=y +-CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_NET=m + # CONFIG_ETHERNET is not set + CONFIG_PHYLIB=y + CONFIG_PPP=y +@@ -219,7 +223,7 @@ CONFIG_USB_USBNET=y + # CONFIG_WLAN_VENDOR_TI is not set + # CONFIG_WLAN_VENDOR_ZYDAS is not set + # CONFIG_WLAN_VENDOR_QUANTENNA is not set +-CONFIG_VIRT_WIFI=y ++CONFIG_VIRT_WIFI=m + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set +@@ -236,9 +240,8 @@ CONFIG_SERIAL_8250_NR_UARTS=48 + CONFIG_SERIAL_8250_EXTENDED=y + CONFIG_SERIAL_8250_MANY_PORTS=y + CONFIG_SERIAL_8250_SHARE_IRQ=y +-CONFIG_VIRTIO_CONSOLE=y + CONFIG_HW_RANDOM=y +-CONFIG_HW_RANDOM_VIRTIO=y ++CONFIG_HW_RANDOM_VIRTIO=m + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set + CONFIG_SPI=y +@@ -250,7 +253,7 @@ CONFIG_MEDIA_SUPPORT=y + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set +-CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_DRM_VIRTIO_GPU=m + # CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y +@@ -260,6 +263,7 @@ CONFIG_SND_DYNAMIC_MINORS=y + # CONFIG_SND_SUPPORT_OLD_API is not set + # CONFIG_SND_VERBOSE_PROCFS is not set + # CONFIG_SND_DRIVERS is not set ++CONFIG_SND_INTEL8X0=m + # CONFIG_SND_USB is not set + CONFIG_HIDRAW=y + CONFIG_UHID=y +@@ -285,9 +289,10 @@ CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set +-CONFIG_VIRTIO_PCI=y +-CONFIG_VIRTIO_INPUT=y +-CONFIG_VIRTIO_MMIO=y ++CONFIG_RTC_DRV_TEST=m ++CONFIG_VIRTIO_PCI=m ++CONFIG_VIRTIO_INPUT=m ++CONFIG_VIRTIO_MMIO=m + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + CONFIG_STAGING=y + CONFIG_ASHMEM=y +@@ -325,7 +330,6 @@ CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_ANSI_CPRNG=y +-CONFIG_CRYPTO_DEV_VIRTIO=y + CONFIG_CRC8=y + CONFIG_XZ_DEC=y + CONFIG_DMA_CMA=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-fix-kernelci-build-break.patch b/patches/ANDROID-fix-kernelci-build-break.patch new file mode 100644 index 000000000000..0f57b493ecf8 --- /dev/null +++ b/patches/ANDROID-fix-kernelci-build-break.patch @@ -0,0 +1,42 @@ +From 4464b2a9ece12e18b118d7b1498021a30acd1f6e Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 20 Aug 2019 09:41:56 -0700 +Subject: ANDROID: fix kernelci build-break + +Added missing #includes to fix 'allmodconfig' builds + +Bug: 120445624 +Bug: 120445421 +Change-Id: Ia8823adf2b33aa31c6d3f9d50ca7679ef4a64eaa +Signed-off-by: Todd Kjos +--- + include/linux/netfilter/xt_quota2.h | 1 + + include/trace/events/android_fs.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/include/linux/netfilter/xt_quota2.h b/include/linux/netfilter/xt_quota2.h +index eadc6903314e7..a3918718cbf8d 100644 +--- a/include/linux/netfilter/xt_quota2.h ++++ b/include/linux/netfilter/xt_quota2.h +@@ -1,5 +1,6 @@ + #ifndef _XT_QUOTA_H + #define _XT_QUOTA_H ++#include + + enum xt_quota_flags { + XT_QUOTA_INVERT = 1 << 0, +diff --git a/include/trace/events/android_fs.h b/include/trace/events/android_fs.h +index 49509533d3faa..7edb6bcfe482f 100644 +--- a/include/trace/events/android_fs.h ++++ b/include/trace/events/android_fs.h +@@ -4,6 +4,7 @@ + #if !defined(_TRACE_ANDROID_FS_H) || defined(TRACE_HEADER_MULTI_READ) + #define _TRACE_ANDROID_FS_H + ++#include + #include + #include + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch b/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch new file mode 100644 index 000000000000..f040fb97e144 --- /dev/null +++ b/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch @@ -0,0 +1,632 @@ +From 5ecd1b81d6ad3e72af67249845129ffe681c5017 Mon Sep 17 00:00:00 2001 +From: Mohan Srinivasan +Date: Wed, 14 Dec 2016 16:39:51 -0800 +Subject: ANDROID: fs: FS tracepoints to track IO. + +Adds tracepoints in ext4/f2fs/mpage to track readpages/buffered +write()s. This allows us to track files that are being read/written +to PIDs. + +Bug: 120445624 +Change-Id: I44476230324e9397e292328463f846af4befbd6d +[joelaf: Needed for storaged fsync accounting ("storaged --uid" and + "storaged --task".)] +Signed-off-by: Mohan Srinivasan +[AmitP: Folded following android-4.9 commit changes into this patch + a5c4dbb05ab7 ("ANDROID: Replace spaces by '_' for some + android filesystem tracepoints.")] +Signed-off-by: Amit Pundir +[astrachan: Folded 63066f4acf92 ("ANDROID: fs: Refactor FS + readpage/write tracepoints.") into this patch +Signed-off-by: Alistair Strachan +--- + fs/ext4/inline.c | 14 +++++ + fs/ext4/inode.c | 55 ++++++++++++++++++ + fs/ext4/readpage.c | 47 ++++++++++++++-- + fs/f2fs/data.c | 42 ++++++++++++++ + fs/f2fs/inline.c | 18 ++++++ + fs/mpage.c | 36 ++++++++++++ + include/trace/events/android_fs.h | 65 ++++++++++++++++++++++ + include/trace/events/android_fs_template.h | 64 +++++++++++++++++++++ + 8 files changed, 337 insertions(+), 4 deletions(-) + create mode 100644 include/trace/events/android_fs.h + create mode 100644 include/trace/events/android_fs_template.h + +Index: common/fs/ext4/inline.c +=================================================================== +--- common.orig/fs/ext4/inline.c ++++ common/fs/ext4/inline.c +@@ -12,6 +12,7 @@ + #include "ext4.h" + #include "xattr.h" + #include "truncate.h" ++#include + + #define EXT4_XATTR_SYSTEM_DATA "data" + #define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) +@@ -505,6 +506,17 @@ int ext4_readpage_inline(struct inode *i + return -EAGAIN; + } + ++ if (trace_android_fs_dataread_start_enabled()) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_dataread_start(inode, page_offset(page), ++ PAGE_SIZE, current->pid, ++ path, current->comm); ++ } ++ + /* + * Current inline data can only exist in the 1st page, + * So for all the other pages, just set them uptodate. +@@ -516,6 +528,8 @@ int ext4_readpage_inline(struct inode *i + SetPageUptodate(page); + } + ++ trace_android_fs_dataread_end(inode, page_offset(page), PAGE_SIZE); ++ + up_read(&EXT4_I(inode)->xattr_sem); + + unlock_page(page); +Index: common/fs/ext4/inode.c +=================================================================== +--- common.orig/fs/ext4/inode.c ++++ common/fs/ext4/inode.c +@@ -47,6 +47,7 @@ + #include "truncate.h" + + #include ++#include + + #define MPAGE_DA_EXTENT_TAIL 0x01 + +@@ -1269,6 +1270,16 @@ static int ext4_write_begin(struct file + if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) + return -EIO; + ++ if (trace_android_fs_datawrite_start_enabled()) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_datawrite_start(inode, pos, len, ++ current->pid, path, ++ current->comm); ++ } + trace_ext4_write_begin(inode, pos, len, flags); + /* + * Reserve one block more for addition to orphan list in case +@@ -1411,6 +1422,7 @@ static int ext4_write_end(struct file *f + int inline_data = ext4_has_inline_data(inode); + bool verity = ext4_verity_in_progress(inode); + ++ trace_android_fs_datawrite_end(inode, pos, len); + trace_ext4_write_end(inode, pos, len, copied); + if (inline_data) { + ret = ext4_write_inline_data_end(inode, pos, len, +@@ -1521,6 +1533,7 @@ static int ext4_journalled_write_end(str + int inline_data = ext4_has_inline_data(inode); + bool verity = ext4_verity_in_progress(inode); + ++ trace_android_fs_datawrite_end(inode, pos, len); + trace_ext4_journalled_write_end(inode, pos, len, copied); + from = pos & (PAGE_SIZE - 1); + to = from + len; +@@ -3040,6 +3053,16 @@ static int ext4_da_write_begin(struct fi + len, flags, pagep, fsdata); + } + *fsdata = (void *)0; ++ if (trace_android_fs_datawrite_start_enabled()) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_datawrite_start(inode, pos, len, ++ current->pid, ++ path, current->comm); ++ } + trace_ext4_da_write_begin(inode, pos, len, flags); + + if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { +@@ -3158,6 +3181,7 @@ static int ext4_da_write_end(struct file + return ext4_write_end(file, mapping, pos, + len, copied, page, fsdata); + ++ trace_android_fs_datawrite_end(inode, pos, len); + trace_ext4_da_write_end(inode, pos, len, copied); + start = pos & (PAGE_SIZE - 1); + end = start + copied - 1; +@@ -3846,6 +3870,7 @@ static ssize_t ext4_direct_IO(struct kio + size_t count = iov_iter_count(iter); + loff_t offset = iocb->ki_pos; + ssize_t ret; ++ int rw = iov_iter_rw(iter); + + #ifdef CONFIG_FS_ENCRYPTION + if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) +@@ -3864,12 +3889,42 @@ static ssize_t ext4_direct_IO(struct kio + if (ext4_has_inline_data(inode)) + return 0; + ++ if (trace_android_fs_dataread_start_enabled() && ++ (rw == READ)) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_dataread_start(inode, offset, count, ++ current->pid, path, ++ current->comm); ++ } ++ if (trace_android_fs_datawrite_start_enabled() && ++ (rw == WRITE)) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_datawrite_start(inode, offset, count, ++ current->pid, path, ++ current->comm); ++ } + trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); + if (iov_iter_rw(iter) == READ) + ret = ext4_direct_IO_read(iocb, iter); + else + ret = ext4_direct_IO_write(iocb, iter); + trace_ext4_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), ret); ++ ++ if (trace_android_fs_dataread_start_enabled() && ++ (rw == READ)) ++ trace_android_fs_dataread_end(inode, offset, count); ++ if (trace_android_fs_datawrite_start_enabled() && ++ (rw == WRITE)) ++ trace_android_fs_datawrite_end(inode, offset, count); ++ + return ret; + } + +Index: common/fs/ext4/readpage.c +=================================================================== +--- common.orig/fs/ext4/readpage.c ++++ common/fs/ext4/readpage.c +@@ -46,6 +46,7 @@ + #include + + #include "ext4.h" ++#include + + #define NUM_PREALLOC_POST_READ_CTXS 128 + +@@ -146,6 +147,17 @@ static bool bio_post_read_required(struc + return bio->bi_private && !bio->bi_status; + } + ++static void ++ext4_trace_read_completion(struct bio *bio) ++{ ++ struct page *first_page = bio->bi_io_vec[0].bv_page; ++ ++ if (first_page != NULL) ++ trace_android_fs_dataread_end(first_page->mapping->host, ++ page_offset(first_page), ++ bio->bi_iter.bi_size); ++} ++ + /* + * I/O completion handler for multipage BIOs. + * +@@ -160,6 +172,9 @@ static bool bio_post_read_required(struc + */ + static void mpage_end_io(struct bio *bio) + { ++ if (trace_android_fs_dataread_start_enabled()) ++ ext4_trace_read_completion(bio); ++ + if (bio_post_read_required(bio)) { + struct bio_post_read_ctx *ctx = bio->bi_private; + +@@ -209,6 +224,30 @@ static inline loff_t ext4_readpage_limit + return i_size_read(inode); + } + ++static void ++ext4_submit_bio_read(struct bio *bio) ++{ ++ if (trace_android_fs_dataread_start_enabled()) { ++ struct page *first_page = bio->bi_io_vec[0].bv_page; ++ ++ if (first_page != NULL) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ first_page->mapping->host); ++ trace_android_fs_dataread_start( ++ first_page->mapping->host, ++ page_offset(first_page), ++ bio->bi_iter.bi_size, ++ current->pid, ++ path, ++ current->comm); ++ } ++ } ++ submit_bio(bio); ++} ++ + int ext4_mpage_readpages(struct address_space *mapping, + struct list_head *pages, struct page *page, + unsigned nr_pages, bool is_readahead) +@@ -354,7 +393,7 @@ int ext4_mpage_readpages(struct address_ + */ + if (bio && (last_block_in_bio != blocks[0] - 1)) { + submit_and_realloc: +- submit_bio(bio); ++ ext4_submit_bio_read(bio); + bio = NULL; + } + if (bio == NULL) { +@@ -385,14 +424,14 @@ int ext4_mpage_readpages(struct address_ + if (((map.m_flags & EXT4_MAP_BOUNDARY) && + (relative_block == map.m_len)) || + (first_hole != blocks_per_page)) { +- submit_bio(bio); ++ ext4_submit_bio_read(bio); + bio = NULL; + } else + last_block_in_bio = blocks[blocks_per_page - 1]; + goto next_page; + confused: + if (bio) { +- submit_bio(bio); ++ ext4_submit_bio_read(bio); + bio = NULL; + } + if (!PageUptodate(page)) +@@ -405,7 +444,7 @@ int ext4_mpage_readpages(struct address_ + } + BUG_ON(pages && !list_empty(pages)); + if (bio) +- submit_bio(bio); ++ ext4_submit_bio_read(bio); + return 0; + } + +Index: common/fs/f2fs/data.c +=================================================================== +--- common.orig/fs/f2fs/data.c ++++ common/fs/f2fs/data.c +@@ -25,6 +25,7 @@ + #include "segment.h" + #include "trace.h" + #include ++#include + + #define NUM_PREALLOC_POST_READ_CTXS 128 + +@@ -2623,6 +2624,16 @@ static int f2fs_write_begin(struct file + block_t blkaddr = NULL_ADDR; + int err = 0; + ++ if (trace_android_fs_datawrite_start_enabled()) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_datawrite_start(inode, pos, len, ++ current->pid, path, ++ current->comm); ++ } + trace_f2fs_write_begin(inode, pos, len, flags); + + if (!f2fs_is_checkpoint_ready(sbi)) { +@@ -2730,6 +2741,7 @@ static int f2fs_write_end(struct file *f + { + struct inode *inode = page->mapping->host; + ++ trace_android_fs_datawrite_end(inode, pos, len); + trace_f2fs_write_end(inode, pos, len, copied); + + /* +@@ -2846,6 +2858,29 @@ static ssize_t f2fs_direct_IO(struct kio + + trace_f2fs_direct_IO_enter(inode, offset, count, rw); + ++ if (trace_android_fs_dataread_start_enabled() && ++ (rw == READ)) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_dataread_start(inode, offset, ++ count, current->pid, path, ++ current->comm); ++ } ++ if (trace_android_fs_datawrite_start_enabled() && ++ (rw == WRITE)) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_datawrite_start(inode, offset, count, ++ current->pid, path, ++ current->comm); ++ } ++ + if (rw == WRITE && whint_mode == WHINT_MODE_OFF) + iocb->ki_hint = WRITE_LIFE_NOT_SET; + +@@ -2891,6 +2926,13 @@ static ssize_t f2fs_direct_IO(struct kio + } + + out: ++ if (trace_android_fs_dataread_start_enabled() && ++ (rw == READ)) ++ trace_android_fs_dataread_end(inode, offset, count); ++ if (trace_android_fs_datawrite_start_enabled() && ++ (rw == WRITE)) ++ trace_android_fs_datawrite_end(inode, offset, count); ++ + trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); + + return err; +Index: common/fs/f2fs/inline.c +=================================================================== +--- common.orig/fs/f2fs/inline.c ++++ common/fs/f2fs/inline.c +@@ -11,6 +11,7 @@ + + #include "f2fs.h" + #include "node.h" ++#include + + bool f2fs_may_inline_data(struct inode *inode) + { +@@ -84,14 +85,29 @@ int f2fs_read_inline_data(struct inode * + { + struct page *ipage; + ++ if (trace_android_fs_dataread_start_enabled()) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ inode); ++ trace_android_fs_dataread_start(inode, page_offset(page), ++ PAGE_SIZE, current->pid, ++ path, current->comm); ++ } ++ + ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino); + if (IS_ERR(ipage)) { ++ trace_android_fs_dataread_end(inode, page_offset(page), ++ PAGE_SIZE); + unlock_page(page); + return PTR_ERR(ipage); + } + + if (!f2fs_has_inline_data(inode)) { + f2fs_put_page(ipage, 1); ++ trace_android_fs_dataread_end(inode, page_offset(page), ++ PAGE_SIZE); + return -EAGAIN; + } + +@@ -103,6 +119,8 @@ int f2fs_read_inline_data(struct inode * + if (!PageUptodate(page)) + SetPageUptodate(page); + f2fs_put_page(ipage, 1); ++ trace_android_fs_dataread_end(inode, page_offset(page), ++ PAGE_SIZE); + unlock_page(page); + return 0; + } +Index: common/fs/mpage.c +=================================================================== +--- common.orig/fs/mpage.c ++++ common/fs/mpage.c +@@ -32,6 +32,14 @@ + #include + #include "internal.h" + ++#define CREATE_TRACE_POINTS ++#include ++ ++EXPORT_TRACEPOINT_SYMBOL(android_fs_datawrite_start); ++EXPORT_TRACEPOINT_SYMBOL(android_fs_datawrite_end); ++EXPORT_TRACEPOINT_SYMBOL(android_fs_dataread_start); ++EXPORT_TRACEPOINT_SYMBOL(android_fs_dataread_end); ++ + /* + * I/O completion handler for multipage BIOs. + * +@@ -49,6 +57,16 @@ static void mpage_end_io(struct bio *bio + struct bio_vec *bv; + struct bvec_iter_all iter_all; + ++ if (trace_android_fs_dataread_end_enabled() && ++ (bio_data_dir(bio) == READ)) { ++ struct page *first_page = bio->bi_io_vec[0].bv_page; ++ ++ if (first_page != NULL) ++ trace_android_fs_dataread_end(first_page->mapping->host, ++ page_offset(first_page), ++ bio->bi_iter.bi_size); ++ } ++ + bio_for_each_segment_all(bv, bio, iter_all) { + struct page *page = bv->bv_page; + page_endio(page, bio_op(bio), +@@ -60,6 +78,24 @@ static void mpage_end_io(struct bio *bio + + static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) + { ++ if (trace_android_fs_dataread_start_enabled() && (op == REQ_OP_READ)) { ++ struct page *first_page = bio->bi_io_vec[0].bv_page; ++ ++ if (first_page != NULL) { ++ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; ++ ++ path = android_fstrace_get_pathname(pathbuf, ++ MAX_TRACE_PATHBUF_LEN, ++ first_page->mapping->host); ++ trace_android_fs_dataread_start( ++ first_page->mapping->host, ++ page_offset(first_page), ++ bio->bi_iter.bi_size, ++ current->pid, ++ path, ++ current->comm); ++ } ++ } + bio->bi_end_io = mpage_end_io; + bio_set_op_attrs(bio, op, op_flags); + guard_bio_eod(op, bio); +Index: common/include/trace/events/android_fs.h +=================================================================== +--- /dev/null ++++ common/include/trace/events/android_fs.h +@@ -0,0 +1,65 @@ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM android_fs ++ ++#if !defined(_TRACE_ANDROID_FS_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_ANDROID_FS_H ++ ++#include ++#include ++ ++DEFINE_EVENT(android_fs_data_start_template, android_fs_dataread_start, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes, ++ pid_t pid, char *pathname, char *command), ++ TP_ARGS(inode, offset, bytes, pid, pathname, command)); ++ ++DEFINE_EVENT(android_fs_data_end_template, android_fs_dataread_end, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes), ++ TP_ARGS(inode, offset, bytes)); ++ ++DEFINE_EVENT(android_fs_data_start_template, android_fs_datawrite_start, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes, ++ pid_t pid, char *pathname, char *command), ++ TP_ARGS(inode, offset, bytes, pid, pathname, command)); ++ ++DEFINE_EVENT(android_fs_data_end_template, android_fs_datawrite_end, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes), ++ TP_ARGS(inode, offset, bytes)); ++ ++#endif /* _TRACE_ANDROID_FS_H */ ++ ++/* This part must be outside protection */ ++#include ++ ++#ifndef ANDROID_FSTRACE_GET_PATHNAME ++#define ANDROID_FSTRACE_GET_PATHNAME ++ ++/* Sizes an on-stack array, so careful if sizing this up ! */ ++#define MAX_TRACE_PATHBUF_LEN 256 ++ ++static inline char * ++android_fstrace_get_pathname(char *buf, int buflen, struct inode *inode) ++{ ++ char *path; ++ struct dentry *d; ++ ++ /* ++ * d_obtain_alias() will either iput() if it locates an existing ++ * dentry or transfer the reference to the new dentry created. ++ * So get an extra reference here. ++ */ ++ ihold(inode); ++ d = d_obtain_alias(inode); ++ if (likely(!IS_ERR(d))) { ++ path = dentry_path_raw(d, buf, buflen); ++ if (unlikely(IS_ERR(path))) { ++ strcpy(buf, "ERROR"); ++ path = buf; ++ } ++ dput(d); ++ } else { ++ strcpy(buf, "ERROR"); ++ path = buf; ++ } ++ return path; ++} ++#endif +Index: common/include/trace/events/android_fs_template.h +=================================================================== +--- /dev/null ++++ common/include/trace/events/android_fs_template.h +@@ -0,0 +1,64 @@ ++#if !defined(_TRACE_ANDROID_FS_TEMPLATE_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_ANDROID_FS_TEMPLATE_H ++ ++#include ++ ++DECLARE_EVENT_CLASS(android_fs_data_start_template, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes, ++ pid_t pid, char *pathname, char *command), ++ TP_ARGS(inode, offset, bytes, pid, pathname, command), ++ TP_STRUCT__entry( ++ __string(pathbuf, pathname); ++ __field(loff_t, offset); ++ __field(int, bytes); ++ __field(loff_t, i_size); ++ __string(cmdline, command); ++ __field(pid_t, pid); ++ __field(ino_t, ino); ++ ), ++ TP_fast_assign( ++ { ++ /* ++ * Replace the spaces in filenames and cmdlines ++ * because this screws up the tooling that parses ++ * the traces. ++ */ ++ __assign_str(pathbuf, pathname); ++ (void)strreplace(__get_str(pathbuf), ' ', '_'); ++ __entry->offset = offset; ++ __entry->bytes = bytes; ++ __entry->i_size = i_size_read(inode); ++ __assign_str(cmdline, command); ++ (void)strreplace(__get_str(cmdline), ' ', '_'); ++ __entry->pid = pid; ++ __entry->ino = inode->i_ino; ++ } ++ ), ++ TP_printk("entry_name %s, offset %llu, bytes %d, cmdline %s," ++ " pid %d, i_size %llu, ino %lu", ++ __get_str(pathbuf), __entry->offset, __entry->bytes, ++ __get_str(cmdline), __entry->pid, __entry->i_size, ++ (unsigned long) __entry->ino) ++); ++ ++DECLARE_EVENT_CLASS(android_fs_data_end_template, ++ TP_PROTO(struct inode *inode, loff_t offset, int bytes), ++ TP_ARGS(inode, offset, bytes), ++ TP_STRUCT__entry( ++ __field(ino_t, ino); ++ __field(loff_t, offset); ++ __field(int, bytes); ++ ), ++ TP_fast_assign( ++ { ++ __entry->ino = inode->i_ino; ++ __entry->offset = offset; ++ __entry->bytes = bytes; ++ } ++ ), ++ TP_printk("ino %lu, offset %llu, bytes %d", ++ (unsigned long) __entry->ino, ++ __entry->offset, __entry->bytes) ++); ++ ++#endif /* _TRACE_ANDROID_FS_TEMPLATE_H */ diff --git a/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch b/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch new file mode 100644 index 000000000000..f8345a6ea3a9 --- /dev/null +++ b/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch @@ -0,0 +1,52 @@ +From 25c49c8d48cfe199197009eb2793b3710afa5039 Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 19 Nov 2018 22:38:23 -0800 +Subject: ANDROID: fs: Restore vfs_path_lookup() export + +Partial revert of 197df04c749a ("rename user_path_umountat() to +user_path_mountpoint_at()"), to restore access to vfs_path_lookup() +without including fs/internal.h, as needed by sdcardfs. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Change-Id: I757f2df9f4dcc66f633939e7833e6fa2ac0ff4f8 +Signed-off-by: Alistair Strachan +Signed-off-by: Yongqin Liu +--- + fs/internal.h | 2 -- + include/linux/namei.h | 2 ++ + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/internal.h b/fs/internal.h +index 315fcd8d237cc..df6e4c4584f32 100644 +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -62,8 +62,6 @@ extern int finish_clean_context(struct fs_context *fc); + extern int filename_lookup(int dfd, struct filename *name, unsigned flags, + struct path *path, struct path *root); + extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); +-extern int vfs_path_lookup(struct dentry *, struct vfsmount *, +- const char *, unsigned int, struct path *); + long do_mknodat(int dfd, const char __user *filename, umode_t mode, + unsigned int dev); + long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); +diff --git a/include/linux/namei.h b/include/linux/namei.h +index 474b3c2de0898..ff686a3989e96 100644 +--- a/include/linux/namei.h ++++ b/include/linux/namei.h +@@ -82,6 +82,8 @@ extern struct dentry *kern_path_create(int, const char *, struct path *, unsigne + extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); + extern void done_path_create(struct path *, struct dentry *); + extern struct dentry *kern_path_locked(const char *, struct path *); ++extern int vfs_path_lookup(struct dentry *, struct vfsmount *, ++ const char *, unsigned int, struct path *); + extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); + + extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch b/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch new file mode 100644 index 000000000000..8fb2a3fd2dad --- /dev/null +++ b/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch @@ -0,0 +1,54 @@ +From 680078c26c5aaa6321e37c7f24243fbadf91b6f4 Mon Sep 17 00:00:00 2001 +From: Colin Cross +Date: Mon, 6 May 2013 23:50:16 +0000 +Subject: ANDROID: fs: epoll: use freezable blocking call + +Avoid waking up every thread sleeping in an epoll_wait call during +suspend and resume by calling a freezable blocking call. Previous +patches modified the freezer to avoid sending wakeups to threads +that are blocked in freezable blocking calls. + +This call was selected to be converted to a freezable call because +it doesn't hold any locks or release any resources when interrupted +that might be needed by another freezing task or a kernel driver +during suspend, and is a common site where idle userspace tasks are +blocked. + +Bug: 77139736 +Bug: 120440023 +Change-Id: I848d08d28c89302fd42bbbdfa76489a474ab27bf +[ccross: This was upstream (https://lkml.org/lkml/2013/5/6/823), but + reverted because it reportedly caused memory corruption on + 32-bit x86 (https://patchwork.kernel.org/patch/3162301/).] +Acked-by: Tejun Heo +Signed-off-by: Colin Cross +Signed-off-by: Rafael J. Wysocki +--- + fs/eventpoll.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/eventpoll.c b/fs/eventpoll.c +index d7f1f5011fac3..f58f3943b07ae 100644 +--- a/fs/eventpoll.c ++++ b/fs/eventpoll.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1912,7 +1913,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, + break; + } + +- if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) { ++ if (!freezable_schedule_hrtimeout_range(to, slack, ++ HRTIMER_MODE_ABS)) { + timed_out = 1; + break; + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build.patch b/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build.patch new file mode 100644 index 000000000000..4eabcff0ab51 --- /dev/null +++ b/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build.patch @@ -0,0 +1,71 @@ +From 339bf978309591fa61211691f97139e5932f06f4 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Mon, 24 Jun 2019 18:10:19 +0100 +Subject: ANDROID: gki/cuttlefish defconfigs: use prebuilt + build-tools + +Rather than relying on the hosts build tools, use a set of prebuilt +build-tools. These are tools like awk, cat, cp, hostname, python, rm, +sed, etc. + +Bug: 135922132 +Change-Id: Ie6b0bd208c684c9f153eb2f0bfac4712e02e8e05 +Signed-off-by: Matthias Maennich +--- + build.config.cuttlefish.aarch64 | 1 + + build.config.cuttlefish.x86_64 | 1 + + build.config.gki.aarch64 | 1 + + build.config.gki.x86_64 | 1 + + 4 files changed, 4 insertions(+) + +diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 +index bec1288d65e13..40c8d7a5219cc 100644 +--- a/build.config.cuttlefish.aarch64 ++++ b/build.config.cuttlefish.aarch64 +@@ -8,6 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 +index 33063abed0edb..c9496b0d2ce6a 100644 +--- a/build.config.cuttlefish.x86_64 ++++ b/build.config.cuttlefish.x86_64 +@@ -8,6 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 +index 408a2d1877e15..fce42ab0daa34 100644 +--- a/build.config.gki.aarch64 ++++ b/build.config.gki.aarch64 +@@ -8,6 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin + FILES=" + arch/arm64/boot/Image.gz +diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 +index 69d339dce4a0f..3ce45e962732b 100644 +--- a/build.config.gki.x86_64 ++++ b/build.config.gki.x86_64 +@@ -8,6 +8,7 @@ EXTRA_CMDS='' + KERNEL_DIR=common + POST_DEFCONFIG_CMDS="check_defconfig" + CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 + LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin + FILES=" + arch/x86/boot/bzImage +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch b/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch new file mode 100644 index 000000000000..e26f3e4a22c3 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch @@ -0,0 +1,44 @@ +From 266742e1fc09a223aebe10491aca7831b443ad40 Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 16:22:18 -0700 +Subject: ANDROID: gki_defconfig: Add GKI_HACKS_to_FIX config + +Enable config which selects a number of non-module +options which are usually selected by drivers built +as modules + +Bug: 141266428 +Change-Id: I8d95c96b74b2cfd861d68573135455a3392ff522 +Signed-off-by: Todd Kjos +--- + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index f65b544d17a41..8edcded9ab1fd 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -72,6 +72,7 @@ CONFIG_KPROBES=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y ++CONFIG_GKI_HACKS_TO_FIX=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + CONFIG_MEMORY_HOTPLUG=y + CONFIG_TRANSPARENT_HUGEPAGE=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 88f715d3df352..4b0393ba4da41 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -47,6 +47,7 @@ CONFIG_KPROBES=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y ++CONFIG_GKI_HACKS_TO_FIX=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + CONFIG_TRANSPARENT_HUGEPAGE=y + CONFIG_CMA=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDO.patch b/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDO.patch new file mode 100644 index 000000000000..1f1892f7756c --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDO.patch @@ -0,0 +1,40 @@ +From b2c6a200c8227027bedb6322a83fc0b295e5df3b Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Mon, 3 Jun 2019 13:53:01 -0700 +Subject: ANDROID: gki_defconfig: Enable CMA, SLAB_FREELIST + (RANDOM and HARDENED) on x86 + +Fixes: 134087016 +Fixes: 134378085 +Test: Boot x86 cuttlefish +Change-Id: I64f9714bbda558056c47f09a5e768d7eb83e2640 +Signed-off-by: Ram Muthiah +--- + arch/x86/configs/gki_defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index cdaba53b7bb04..864595c719e76 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -30,6 +30,8 @@ CONFIG_EMBEDDED=y + # CONFIG_VM_EVENT_COUNTERS is not set + # CONFIG_COMPAT_BRK is not set + # CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_SLAB_FREELIST_RANDOM=y ++CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 +@@ -46,6 +48,8 @@ CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + # CONFIG_SPARSEMEM_VMEMMAP is not set + CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_CMA=y ++CONFIG_CMA_AREAS=16 + CONFIG_ZSMALLOC=y + CONFIG_NET=y + CONFIG_PACKET=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch b/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch new file mode 100644 index 000000000000..03937a204007 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch @@ -0,0 +1,45 @@ +From ad5139fd550dfc4cd26ed62f88b2a063b8f8553d Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Wed, 18 Sep 2019 10:49:45 -0700 +Subject: ANDROID: gki_defconfig: Enable HiSilicon SoCs + +Enable configs required for HiSilicon SoCs. + +Bug: 141265942 +Change-Id: Iedb2b795bda690bdec4db3265dc391f7837208e0 +Signed-off-by: Todd Kjos +--- + arch/arm64/configs/gki_defconfig | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 1263dc50f970e..f964b81a1e4be 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -36,6 +36,7 @@ CONFIG_EMBEDDED=y + CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y ++CONFIG_ARCH_HISI=y + CONFIG_ARCH_QCOM=y + CONFIG_SCHED_MC=y + CONFIG_NR_CPUS=32 +@@ -195,6 +196,7 @@ CONFIG_MAC80211=y + CONFIG_RFKILL=y + CONFIG_PCI=y + CONFIG_PCI_HOST_GENERIC=y ++CONFIG_PCIE_KIRIN=y + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y + CONFIG_ZRAM=y +@@ -280,6 +282,7 @@ CONFIG_SPI=y + CONFIG_SPMI=y + CONFIG_PINCTRL_AMD=y + CONFIG_POWER_AVS=y ++CONFIG_POWER_RESET_HISI=y + # CONFIG_HWMON is not set + CONFIG_THERMAL=y + CONFIG_THERMAL_GOV_USER_SPACE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch b/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch new file mode 100644 index 000000000000..adf450f1b76d --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch @@ -0,0 +1,42 @@ +From 91911b91ad44466e1cbc3c8e377e51f487b1dde5 Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 16:25:46 -0700 +Subject: ANDROID: gki_defconfig: Enable SERIAL_DEV_BUS + +Enable CONFIG_SERIAL_DEV_BUS for hikey/db845c + +Bug: 141265942 +Change-Id: Iedc0d96ed10011ca0b5bedd7384f5158f32c6c76 +Signed-off-by: Todd Kjos +--- + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 8edcded9ab1fd..1263dc50f970e 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -268,6 +268,7 @@ CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_OF_PLATFORM=m + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_DEV_BUS=y + CONFIG_VIRTIO_CONSOLE=y + CONFIG_HW_RANDOM=y + CONFIG_HW_RANDOM_VIRTIO=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 4b0393ba4da41..b69cccca0df13 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -239,6 +239,7 @@ CONFIG_SERIAL_8250=y + # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set + CONFIG_SERIAL_8250_CONSOLE=y + CONFIG_SERIAL_OF_PLATFORM=m ++CONFIG_SERIAL_DEV_BUS=y + CONFIG_HW_RANDOM=y + CONFIG_HW_RANDOM_VIRTIO=m + # CONFIG_I2C_COMPAT is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch b/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch new file mode 100644 index 000000000000..a4f3e6d51b45 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch @@ -0,0 +1,68 @@ +From 06e0256c5c890918ae24431384c602126192e271 Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Fri, 16 Aug 2019 22:33:20 +0000 +Subject: ANDROID: gki_defconfig: Minimally enable EFI + +HiKey/HiKey960 need UEFI support to boot but don't need much of +the other options that default on when enabling EFI. + +Bug: 140204135 +Signed-off-by: John Stultz +Change-Id: I5c2e63701ae93277fcc3ddb36a39637237c65194 +--- + arch/arm64/configs/gki_defconfig | 4 +++- + arch/x86/configs/gki_defconfig | 2 ++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 2773a84fd9390..006692f065d4e 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -46,7 +46,7 @@ CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y + CONFIG_RANDOMIZE_BASE=y +-# CONFIG_EFI is not set ++# CONFIG_DMI is not set + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +@@ -64,6 +64,7 @@ CONFIG_ARM_SCMI_PROTOCOL=y + # CONFIG_ARM_SCMI_POWER_DOMAIN is not set + CONFIG_ARM_SCPI_PROTOCOL=y + # CONFIG_ARM_SCPI_POWER_DOMAIN is not set ++# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set + CONFIG_ARM64_CRYPTO=y + CONFIG_CRYPTO_AES_ARM64=y + CONFIG_KPROBES=y +@@ -382,6 +383,7 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y ++# CONFIG_EFIVAR_FS is not set + CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index a1b2121bde8b6..ed8296e953ed3 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -36,6 +36,7 @@ CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_SMP=y + CONFIG_NR_CPUS=32 ++CONFIG_EFI=y + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +@@ -308,6 +309,7 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y ++# CONFIG_EFIVAR_FS is not set + CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-con.patch b/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-con.patch new file mode 100644 index 000000000000..ac247f2bdd18 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-con.patch @@ -0,0 +1,97 @@ +From 01a9fc33b29bb6c713efe1f56c401c2eeab03448 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Fri, 10 May 2019 14:33:29 -0700 +Subject: ANDROID: gki_defconfig: Remove cuttlefish-specific + configs + +Left enabled: +- configs for virtualization CONFIG_PARAVIRT, CONFIG_VIRTIO_*, etc. +- cuttlefish doesn't boot without CONFIG_KSM, CONFIG_SGETMASK_SYSCALL, + CONFIG_SCHED_AUTOGROUP + +A number of config should be modules, but due to lack of module support +in userspace are left built in: +- CONFIG_PCI_HOST_GENERIC +- CONFIG_SERIAL_* +- CONFIG_MAC80211 +- CONFIG_SND_INTEL8X0 +- CONFIG_RTC_DRV_PL030 +- CONFIG_RTC_DRV_PL031 +- CONFIG_CRYPTO_ADIANTUM +- CONFIG_CRYPTO_ZSTD + +Test: boot cuttlefish on arm64 +Signed-off-by: Tri Vo +(partially cherry picked from commit a651d6eccc912ea60d8b79ddeec23ffb1f85b65f) +--- + arch/arm64/configs/gki_defconfig | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index a747e222db8e1..41a892ca324d9 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -34,7 +34,6 @@ CONFIG_EMBEDDED=y + # CONFIG_SLAB_MERGE_DEFAULT is not set + CONFIG_PROFILING=y + CONFIG_SCHED_MC=y +-CONFIG_HZ_100=y + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y + CONFIG_ARMV8_DEPRECATED=y +@@ -56,7 +55,6 @@ CONFIG_CPU_FREQ_TIMES=y + CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=y + CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +-CONFIG_CPUFREQ_DT=y + CONFIG_ARM_SCPI_CPUFREQ=y + CONFIG_ARM_SCMI_CPUFREQ=y + CONFIG_ARM_SCMI_PROTOCOL=y +@@ -90,10 +88,6 @@ CONFIG_INET_ESP=y + # CONFIG_INET_XFRM_MODE_BEET is not set + CONFIG_INET_UDP_DIAG=y + CONFIG_INET_DIAG_DESTROY=y +-CONFIG_TCP_CONG_ADVANCED=y +-# CONFIG_TCP_CONG_BIC is not set +-# CONFIG_TCP_CONG_WESTWOOD is not set +-# CONFIG_TCP_CONG_HTCP is not set + CONFIG_IPV6_ROUTER_PREF=y + CONFIG_IPV6_ROUTE_INFO=y + CONFIG_IPV6_OPTIMISTIC_DAD=y +@@ -191,10 +185,8 @@ CONFIG_RFKILL=y + CONFIG_PCI=y + CONFIG_PCI_HOST_GENERIC=y + # CONFIG_UEVENT_HELPER is not set +-CONFIG_DEVTMPFS=y + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y +-CONFIG_OF_UNITTEST=y + CONFIG_ZRAM=y + CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y +@@ -214,8 +206,6 @@ CONFIG_DM_VERITY_AVB=y + CONFIG_DM_VERITY_FEC=y + CONFIG_DM_BOW=y + CONFIG_NETDEVICES=y +-CONFIG_NETCONSOLE=y +-CONFIG_NETCONSOLE_DYNAMIC=y + CONFIG_TUN=y + CONFIG_VIRTIO_NET=y + # CONFIG_ETHERNET is not set +@@ -366,7 +356,6 @@ CONFIG_XZ_DEC=y + CONFIG_PRINTK_TIME=y + CONFIG_DEBUG_INFO=y + # CONFIG_ENABLE_MUST_CHECK is not set +-CONFIG_FRAME_WARN=1024 + # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set + CONFIG_MAGIC_SYSRQ=y + CONFIG_DEBUG_STACK_USAGE=y +@@ -375,5 +364,4 @@ CONFIG_SOFTLOCKUP_DETECTOR=y + # CONFIG_DETECT_HUNG_TASK is not set + CONFIG_PANIC_TIMEOUT=5 + CONFIG_SCHEDSTATS=y +-CONFIG_RCU_CPU_STALL_TIMEOUT=60 + # CONFIG_RUNTIME_TESTING_MENU is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not.patch b/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not.patch new file mode 100644 index 000000000000..2713c128ceb1 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not.patch @@ -0,0 +1,153 @@ +From aba7e7f7b3f9e42875fa98bb778ce2cfe9631b29 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Sat, 4 May 2019 17:45:04 -0700 +Subject: ANDROID: gki_defconfig: Remove recommended configs + not present on b1c1 + +Enable: +CONFIG_USB because it's required. +CONFIG_OVERLAY_FS, CONFIG_ARM64_SW_TTBR0_PAN because cuttlefish doesn't +boot without these. + +CONFIG_PSI, CONFIG_DM_BOW, CONFIG_HIDRAW, CONFIG_USB_HIDDEV, +CONFIG_MSDOS_FS, CONFIG_PANIC_TIMEOUT=5 are not strictly required, but +seem appropriate for a "generic" kernel. + +Note that cuttlefish-specific modules, that are neither required nor +recommended, are still enabled. + +Test: boot cuttlefish on a arm64 machine +Signed-off-by: Tri Vo +(partially cherry picked from commit 37381a5b77c8496a5bc5827ddbaf106e51d2c0c0) +--- + arch/arm64/configs/gki_defconfig | 68 +------------------------------- + 1 file changed, 1 insertion(+), 67 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index a87cf1871f129..a747e222db8e1 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -3,7 +3,6 @@ CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_PREEMPT=y + CONFIG_TASKSTATS=y +-CONFIG_TASK_DELAY_ACCT=y + CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_PSI=y +@@ -49,7 +48,6 @@ CONFIG_COMPAT=y + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +-CONFIG_PM_DEBUG=y + CONFIG_ENERGY_MODEL=y + CONFIG_CPU_IDLE=y + CONFIG_ARM_CPUIDLE=y +@@ -176,7 +174,6 @@ CONFIG_IP6_NF_RAW=y + CONFIG_L2TP=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y +-CONFIG_NET_SCH_NETEM=y + CONFIG_NET_SCH_INGRESS=y + CONFIG_NET_CLS_U32=y + CONFIG_NET_CLS_BPF=y +@@ -259,15 +256,6 @@ CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set + CONFIG_INPUT_JOYSTICK=y +-CONFIG_JOYSTICK_XPAD=y +-CONFIG_JOYSTICK_XPAD_FF=y +-CONFIG_JOYSTICK_XPAD_LEDS=y +-CONFIG_INPUT_TABLET=y +-CONFIG_TABLET_USB_ACECAD=y +-CONFIG_TABLET_USB_AIPTEK=y +-CONFIG_TABLET_USB_GTCO=y +-CONFIG_TABLET_USB_HANWANG=y +-CONFIG_TABLET_USB_KBTAB=y + CONFIG_INPUT_MISC=y + CONFIG_INPUT_UINPUT=y + # CONFIG_VT is not set +@@ -309,65 +297,13 @@ CONFIG_SND_INTEL8X0=y + # CONFIG_SND_USB is not set + CONFIG_HIDRAW=y + CONFIG_UHID=y +-CONFIG_HID_A4TECH=y +-CONFIG_HID_ACRUX=y +-CONFIG_HID_ACRUX_FF=y + CONFIG_HID_APPLE=y +-CONFIG_HID_BELKIN=y +-CONFIG_HID_CHERRY=y +-CONFIG_HID_CHICONY=y +-CONFIG_HID_PRODIKEYS=y +-CONFIG_HID_CYPRESS=y +-CONFIG_HID_DRAGONRISE=y +-CONFIG_DRAGONRISE_FF=y +-CONFIG_HID_EMS_FF=y + CONFIG_HID_ELECOM=y +-CONFIG_HID_EZKEY=y +-CONFIG_HID_HOLTEK=y +-CONFIG_HID_KEYTOUCH=y +-CONFIG_HID_KYE=y +-CONFIG_HID_UCLOGIC=y +-CONFIG_HID_WALTOP=y +-CONFIG_HID_GYRATION=y +-CONFIG_HID_TWINHAN=y +-CONFIG_HID_KENSINGTON=y +-CONFIG_HID_LCPOWER=y +-CONFIG_HID_LOGITECH=y +-CONFIG_HID_LOGITECH_DJ=y +-CONFIG_LOGITECH_FF=y +-CONFIG_LOGIRUMBLEPAD2_FF=y +-CONFIG_LOGIG940_FF=y + CONFIG_HID_MAGICMOUSE=y + CONFIG_HID_MICROSOFT=y +-CONFIG_HID_MONTEREY=y + CONFIG_HID_MULTITOUCH=y +-CONFIG_HID_NTRIG=y +-CONFIG_HID_ORTEK=y +-CONFIG_HID_PANTHERLORD=y +-CONFIG_PANTHERLORD_FF=y +-CONFIG_HID_PETALYNX=y +-CONFIG_HID_PICOLCD=y +-CONFIG_HID_PRIMAX=y +-CONFIG_HID_ROCCAT=y +-CONFIG_HID_SAITEK=y +-CONFIG_HID_SAMSUNG=y +-CONFIG_HID_SONY=y +-CONFIG_HID_SPEEDLINK=y +-CONFIG_HID_SUNPLUS=y +-CONFIG_HID_GREENASIA=y +-CONFIG_GREENASIA_FF=y +-CONFIG_HID_SMARTJOYPLUS=y +-CONFIG_SMARTJOYPLUS_FF=y +-CONFIG_HID_TIVO=y +-CONFIG_HID_TOPSEED=y +-CONFIG_HID_THRUSTMASTER=y +-CONFIG_HID_WACOM=y +-CONFIG_HID_WIIMOTE=y +-CONFIG_HID_ZEROPLUS=y +-CONFIG_HID_ZYDACRON=y + CONFIG_USB_HIDDEV=y +-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +-CONFIG_USB_EHCI_HCD=y ++CONFIG_USB=y + CONFIG_USB_GADGET=y + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y +@@ -418,7 +354,6 @@ CONFIG_PSTORE_RAM=y + CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y + CONFIG_SECURITY=y + CONFIG_SECURITY_NETWORK=y +-CONFIG_LSM_MMAP_MIN_ADDR=65536 + CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y + CONFIG_CRYPTO_ADIANTUM=y +@@ -441,5 +376,4 @@ CONFIG_SOFTLOCKUP_DETECTOR=y + CONFIG_PANIC_TIMEOUT=5 + CONFIG_SCHEDSTATS=y + CONFIG_RCU_CPU_STALL_TIMEOUT=60 +-CONFIG_ENABLE_DEFAULT_TRACERS=y + # CONFIG_RUNTIME_TESTING_MENU is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKM.patch b/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKM.patch new file mode 100644 index 000000000000..ee3c93a0051e --- /dev/null +++ b/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKM.patch @@ -0,0 +1,81 @@ +From 14a0f7ada52f543394530cbedcb24c6f54daf8cd Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Sat, 11 May 2019 16:48:08 -0700 +Subject: ANDROID: gki_defconfig: common configs for device + DLKMs + +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +(partially cherry picked from commit 6742f3f75046867373ac782e709681c98f72a744) +--- + arch/arm64/configs/gki_defconfig | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 41a892ca324d9..cc9ecd83a69c5 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -269,22 +269,30 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_DEVPORT is not set + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPMI=y ++CONFIG_GPIOLIB=y + # CONFIG_HWMON is not set + CONFIG_THERMAL=y ++CONFIG_THERMAL_GOV_USER_SPACE=y + CONFIG_CPU_THERMAL=y ++CONFIG_DEVFREQ_THERMAL=y ++CONFIG_REGULATOR=y + CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_CAMERA_SUPPORT=y + # CONFIG_VGA_ARB is not set + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_BACKLIGHT_LCD_SUPPORT=y ++CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y + CONFIG_SND=y + CONFIG_SND_HRTIMER=y ++CONFIG_SND_DYNAMIC_MINORS=y + # CONFIG_SND_SUPPORT_OLD_API is not set + # CONFIG_SND_VERBOSE_PROCFS is not set + # CONFIG_SND_DRIVERS is not set + CONFIG_SND_INTEL8X0=y +-# CONFIG_SND_USB is not set + CONFIG_HIDRAW=y + CONFIG_UHID=y + CONFIG_HID_APPLE=y +@@ -305,6 +313,9 @@ CONFIG_MMC=y + # CONFIG_PWRSEQ_EMMC is not set + # CONFIG_PWRSEQ_SIMPLE is not set + # CONFIG_MMC_BLOCK is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_TRIGGERS=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set + CONFIG_RTC_DRV_PL030=y +@@ -321,7 +332,9 @@ CONFIG_ANDROID_VSOC=y + CONFIG_ION=y + CONFIG_COMMON_CLK_SCPI=y + CONFIG_MAILBOX=y +-# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_PM_DEVFREQ=y ++CONFIG_PWM=y ++CONFIG_GENERIC_PHY=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y + CONFIG_EXT4_FS=y +@@ -352,6 +365,7 @@ CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_ANSI_CPRNG=y + CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_CRC8=y + CONFIG_XZ_DEC=y + CONFIG_PRINTK_TIME=y + CONFIG_DEBUG_INFO=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch b/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch new file mode 100644 index 000000000000..6dfdd9493371 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch @@ -0,0 +1,26 @@ +From 9c1e79aef63fc344f83656f4183264bb3db23f87 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Wed, 17 Jul 2019 15:25:54 -0700 +Subject: ANDROID: gki_defconfig: disable BRIDGE_NETFILTER + +This config is explicitly disabled on Pixel 3. + +Change-Id: I126e5222180e3880a71c0f78b99276b0157ef4c8 +Signed-off-by: Tri Vo +--- + abi_gki_aarch64.xml | 132495 +++++++++++++++------------- + arch/arm64/configs/gki_defconfig | 1 + + 2 files changed, 70038 insertions(+), 62458 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -101,6 +101,7 @@ CONFIG_IPV6_MIP6=y + CONFIG_IPV6_VTI=y + CONFIG_IPV6_MULTIPLE_TABLES=y + CONFIG_NETFILTER=y ++# CONFIG_BRIDGE_NETFILTER is not set + CONFIG_NF_CONNTRACK=y + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y diff --git a/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVIC.patch b/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVIC.patch new file mode 100644 index 000000000000..71aafeb0507b --- /dev/null +++ b/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVIC.patch @@ -0,0 +1,27 @@ +From 20395ab49599be230676e03bbc977206f16c18f4 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Tue, 14 May 2019 17:32:43 -0700 +Subject: ANDROID: gki_defconfig: disable + CONFIG_LCD_CLASS_DEVICE module + +CONFIG_LCD_CLASS_DEVICE is set to "m" by default when +CONFIG_BACKLIGHT_LCD_SUPPORT is set. We don't need lcd.ko though. +--- + arch/arm64/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index cc9ecd83a69c5..4b17f0f9d0ae8 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -284,6 +284,7 @@ CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=y + CONFIG_BACKLIGHT_LCD_SUPPORT=y ++# CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y + CONFIG_SND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch b/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch new file mode 100644 index 000000000000..5ead17c03628 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch @@ -0,0 +1,36 @@ +From aeba9a624e4903c9b3e97c6ef89caee80620edb3 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 8 Aug 2019 17:06:26 -0700 +Subject: ANDROID: gki_defconfig: disable IP_PNP, ECRYPT_FS + +Neither are necessary on android devices. + +Change-Id: I61008f47c53fb88fcdbdcd889346a214b23246ad +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 43a1fea94c6a5..539f42574383e 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -87,7 +87,6 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IP_PNP=y + CONFIG_NET_IPGRE_DEMUX=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +@@ -379,7 +378,6 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y +-CONFIG_ECRYPT_FS=y + CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AR.patch b/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AR.patch new file mode 100644 index 000000000000..124a3fdcced3 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AR.patch @@ -0,0 +1,29 @@ +From bd6786952038afa50723a79647e9b824dde9667e Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Mon, 3 Jun 2019 11:50:28 -0700 +Subject: ANDROID: gki_defconfig: enable CMA and increase + CMA_AREAS + +Fixes: 134378085 +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index c9720858fd9a1..bf15919ba7e79 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -66,6 +66,8 @@ CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + # CONFIG_SPARSEMEM_VMEMMAP is not set + CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_CMA=y ++CONFIG_CMA_AREAS=16 + CONFIG_ZSMALLOC=y + CONFIG_NET=y + CONFIG_PACKET=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB.patch new file mode 100644 index 000000000000..7a2fa6b1ecc2 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB.patch @@ -0,0 +1,70 @@ +From b82028105d31e9da504fe7fd507da1aff9eac95f Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 29 Aug 2019 14:04:15 -0700 +Subject: ANDROID: gki_defconfig: enable + CONFIG_QCOM_{COMMAND_DB,RPMH,PDC} + +CONFIG_ARCH_QCOM is a dependency of the above and selects +CONFIG_{PINCTRL, REGULATOR, TMPFS}. + +Bug: 133441279 +Bug: 133441092 +Bug: 133440650 +Change-Id: I22c37946ec3a62ccbd3fa65bbc09076964d86475 +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -36,6 +36,7 @@ CONFIG_EMBEDDED=y + CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y ++CONFIG_ARCH_QCOM=y + CONFIG_SCHED_MC=y + CONFIG_NR_CPUS=32 + CONFIG_SECCOMP=y +@@ -279,7 +280,6 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_I2C_HELPER_AUTO is not set + CONFIG_SPI=y + CONFIG_SPMI=y +-CONFIG_PINCTRL=y + CONFIG_PINCTRL_AMD=y + CONFIG_POWER_AVS=y + # CONFIG_HWMON is not set +@@ -290,7 +290,6 @@ CONFIG_DEVFREQ_THERMAL=y + CONFIG_WATCHDOG=y + CONFIG_MFD_ACT8945A=y + CONFIG_MFD_SYSCON=y +-CONFIG_REGULATOR=y + CONFIG_MEDIA_SUPPORT=y + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_MEDIA_CONTROLLER=y +@@ -357,12 +356,15 @@ CONFIG_COMMON_CLK_SCPI=y + CONFIG_HWSPINLOCK=y + CONFIG_MAILBOX=y + CONFIG_ARM_SMMU=y ++CONFIG_QCOM_COMMAND_DB=y ++CONFIG_QCOM_RPMH=y + CONFIG_DEVFREQ_GOV_PERFORMANCE=y + CONFIG_DEVFREQ_GOV_POWERSAVE=y + CONFIG_DEVFREQ_GOV_USERSPACE=y + CONFIG_DEVFREQ_GOV_PASSIVE=y + CONFIG_EXTCON=y + CONFIG_PWM=y ++CONFIG_QCOM_PDC=y + CONFIG_GENERIC_PHY=y + CONFIG_RAS=y + CONFIG_ANDROID=y +@@ -380,7 +382,6 @@ CONFIG_FUSE_FS=y + CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +-CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y + # CONFIG_EFIVAR_FS is not set + CONFIG_SDCARD_FS=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch new file mode 100644 index 000000000000..e26ddad5171e --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch @@ -0,0 +1,54 @@ +From e8e6122e2d36b0467d9465c292875d577e446d2d Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Thu, 29 Aug 2019 08:00:26 -0700 +Subject: ANDROID: gki_defconfig enable + CONFIG_SPARSEMEM_VMEMMAP + +Legacy Ion driver and SPARSEMEM for carveout regions results +in invalid page structures breaking page_to_pfn(). This can +be temporarily resolved with SPARSEMEM_VMEMMAP until the Ion +driver is refactored and can be reinvestigated. + +At that time if it can be solved, or maybe correct this issue +utilizing less resources than SPARSEMEM_VMEMMAP requires. The +ABI does not change so we have the flexibility to adjust this +configuration. + +Signed-off-by: Mark Salyzyn +Bug: 138851285 +Bug: 138149732 +Test: ABI_DEFINITION=common/abi_gki_aarch64.xml \ + BUILD_CONFIG=common/build.config.gki.aarch64 ./build/build_abi.sh +Change-Id: I25cc8ebe9e25260b9869c5e8d8667b280f83ca51 +--- + arch/arm64/configs/gki_defconfig | 1 - + arch/x86/configs/gki_defconfig | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 006692f065d4e..604b97841737e 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -72,7 +72,6 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_SPARSEMEM_VMEMMAP is not set + CONFIG_MEMORY_HOTPLUG=y + CONFIG_TRANSPARENT_HUGEPAGE=y + CONFIG_CMA=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index ed8296e953ed3..e86cd1009a67c 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -48,7 +48,6 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_SPARSEMEM_VMEMMAP is not set + CONFIG_TRANSPARENT_HUGEPAGE=y + CONFIG_CMA=y + CONFIG_CMA_AREAS=16 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch new file mode 100644 index 000000000000..c145826de521 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch @@ -0,0 +1,27 @@ +From 6746891e99fc3eda1bbbd999a8a08b3128c3f458 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Fri, 23 Aug 2019 10:57:25 -0700 +Subject: ANDROID: gki_defconfig: enable CONFIG_TIPC + +Test: n/a +Change-Id: If068edf432bd2574a9ca8257e5a4f43731328317 +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 73acbe383203d..b70d608b1ee69 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -170,6 +170,7 @@ CONFIG_IP6_NF_FILTER=y + CONFIG_IP6_NF_TARGET_REJECT=y + CONFIG_IP6_NF_MANGLE=y + CONFIG_IP6_NF_RAW=y ++CONFIG_TIPC=y + CONFIG_L2TP=y + CONFIG_BRIDGE=y + CONFIG_NET_SCHED=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch new file mode 100644 index 000000000000..7bb74aefd71b --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch @@ -0,0 +1,40 @@ +From 4d7838f044cdca6d05d8126b6884e0c46540d342 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Wed, 18 Sep 2019 14:07:28 -0700 +Subject: ANDROID: gki_defconfig: enable CONFIG_UIO + +Bug: 135666008 +Change-Id: I1fac71548c2f442d3622ff068928662d1ba6e3dd +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 440173b3c3013..f65b544d17a41 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -337,6 +337,7 @@ CONFIG_RTC_CLASS=y + CONFIG_RTC_DRV_PL030=y + CONFIG_RTC_DRV_PL031=y + CONFIG_DMADEVICES=y ++CONFIG_UIO=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set + CONFIG_VIRTIO_INPUT=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 929be246c6b1e..88f715d3df352 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -288,6 +288,7 @@ CONFIG_LEDS_TRIGGERS=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set + CONFIG_RTC_DRV_TEST=m ++CONFIG_UIO=y + CONFIG_VIRTIO_PCI=m + CONFIG_VIRTIO_INPUT=m + CONFIG_VIRTIO_MMIO=m +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch b/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch new file mode 100644 index 000000000000..0e8968d961b4 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch @@ -0,0 +1,28 @@ +From a36995c4265f4336e17b67930d13f44b2bef8df2 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Wed, 12 Jun 2019 15:26:49 -0700 +Subject: ANDROID: gki_defconfig: enable DMA_CMA + +And update ABI representation. + +Fixes: 134916881 +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +Change-Id: Id0d270f510aa0a06dc5a082ef35c3d969b72cc35 +--- + abi_gki_aarch64.xml | 115880 ++++++++++++++-------------- + arch/arm64/configs/gki_defconfig | 1 + + 2 files changed, 57878 insertions(+), 58003 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -373,6 +373,7 @@ CONFIG_CRYPTO_ANSI_CPRNG=y + CONFIG_CRYPTO_DEV_VIRTIO=y + CONFIG_CRC8=y + CONFIG_XZ_DEC=y ++CONFIG_DMA_CMA=y + CONFIG_PRINTK_TIME=y + CONFIG_DEBUG_INFO=y + # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SL.patch b/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SL.patch new file mode 100644 index 000000000000..b99c210ed36d --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SL.patch @@ -0,0 +1,31 @@ +From c270a5e76cb5480889f9add5af42ddcf53640471 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Mon, 3 Jun 2019 12:54:46 -0700 +Subject: ANDROID: gki_defconfig: enable SLAB_FREELIST_RANDOM, + SLAB_FREELIST_HARDENED + +Security hardening + +Fixes: 134087016 +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index bf15919ba7e79..ef79e45cae164 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -31,6 +31,8 @@ CONFIG_EMBEDDED=y + # CONFIG_VM_EVENT_COUNTERS is not set + # CONFIG_COMPAT_BRK is not set + # CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_SLAB_FREELIST_RANDOM=y ++CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_SCHED_MC=y + CONFIG_SECCOMP=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-enable-more-configs.patch b/patches/ANDROID-gki_defconfig-enable-more-configs.patch new file mode 100644 index 000000000000..d7e670efa5f1 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-enable-more-configs.patch @@ -0,0 +1,88 @@ +From a202788f0afad1fe1f69007fda37b5baf317553e Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Tue, 16 Jul 2019 16:27:17 -0700 +Subject: ANDROID: gki_defconfig: enable more configs + +Enable following configs: +CONFIG_RAS +CONFIG_EDAC +CONFIG_SPI +CONFIG_DMADEVICES +CONFIG_POWER_AVS +CONFIG_WATCHDOG +CONFIG_USB_OTG +CONFIG_MMC_BLOCK + +Fixes: 137124260 +Fixes: 136278478 +Fixes: 136279343 +Fixes: 136279418 +Fixes: 136279652 +Fixes: 136279658 +Fixes: 136281307 +Change-Id: I630dd2ffd4f6694b497cbb273830d643878694f6 +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 7c66f40c97398..45644397a2d7a 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -274,14 +274,17 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_DEVPORT is not set + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y + CONFIG_SPMI=y + CONFIG_PINCTRL=y + CONFIG_PINCTRL_AMD=y ++CONFIG_POWER_AVS=y + # CONFIG_HWMON is not set + CONFIG_THERMAL=y + CONFIG_THERMAL_GOV_USER_SPACE=y + CONFIG_CPU_THERMAL=y + CONFIG_DEVFREQ_THERMAL=y ++CONFIG_WATCHDOG=y + CONFIG_MFD_ACT8945A=y + CONFIG_MFD_SYSCON=y + CONFIG_REGULATOR=y +@@ -313,6 +316,7 @@ CONFIG_HID_MICROSOFT=y + CONFIG_HID_MULTITOUCH=y + CONFIG_USB_HIDDEV=y + CONFIG_USB=y ++CONFIG_USB_OTG=y + CONFIG_USB_GADGET=y + CONFIG_USB_DUMMY_HCD=y + CONFIG_USB_CONFIGFS=y +@@ -324,16 +328,17 @@ CONFIG_USB_CONFIGFS_F_MIDI=y + CONFIG_MMC=y + # CONFIG_PWRSEQ_EMMC is not set + # CONFIG_PWRSEQ_SIMPLE is not set +-# CONFIG_MMC_BLOCK is not set + CONFIG_MMC_SDHCI=y + CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y ++CONFIG_EDAC=y + CONFIG_RTC_CLASS=y + # CONFIG_RTC_SYSTOHC is not set + CONFIG_RTC_DRV_PL030=y + CONFIG_RTC_DRV_PL031=y ++CONFIG_DMADEVICES=y + CONFIG_VIRTIO_PCI=y + # CONFIG_VIRTIO_PCI_LEGACY is not set + CONFIG_VIRTIO_INPUT=y +@@ -354,6 +359,7 @@ CONFIG_DEVFREQ_GOV_PASSIVE=y + CONFIG_EXTCON=y + CONFIG_PWM=y + CONFIG_GENERIC_PHY=y ++CONFIG_RAS=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y + CONFIG_INTERCONNECT=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttle.patch b/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttle.patch new file mode 100644 index 000000000000..24952a31334d --- /dev/null +++ b/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttle.patch @@ -0,0 +1,467 @@ +From b9bf826665b9db01d3f1a1e0acdc06d7facea405 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Mon, 13 May 2019 16:00:04 -0700 +Subject: ANDROID: gki_defconfig: initial config based on + cuttlefish_defconfig + +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 445 +++++++++++++++++++++++++++++++ + 1 file changed, 445 insertions(+) + create mode 100644 arch/arm64/configs/gki_defconfig + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +new file mode 100644 +index 0000000000000..a87cf1871f129 +--- /dev/null ++++ b/arch/arm64/configs/gki_defconfig +@@ -0,0 +1,445 @@ ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_PSI=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_BPF=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++# CONFIG_RD_LZ4 is not set ++CONFIG_SGETMASK_SYSCALL=y ++# CONFIG_SYSFS_SYSCALL is not set ++# CONFIG_FHANDLE is not set ++CONFIG_KALLSYMS_ALL=y ++CONFIG_BPF_SYSCALL=y ++# CONFIG_RSEQ is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB_MERGE_DEFAULT is not set ++CONFIG_PROFILING=y ++CONFIG_SCHED_MC=y ++CONFIG_HZ_100=y ++CONFIG_SECCOMP=y ++CONFIG_PARAVIRT=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++CONFIG_ARM64_SW_TTBR0_PAN=y ++CONFIG_RANDOMIZE_BASE=y ++# CONFIG_EFI is not set ++CONFIG_COMPAT=y ++CONFIG_PM_WAKELOCKS=y ++CONFIG_PM_WAKELOCKS_LIMIT=0 ++# CONFIG_PM_WAKELOCKS_GC is not set ++CONFIG_PM_DEBUG=y ++CONFIG_ENERGY_MODEL=y ++CONFIG_CPU_IDLE=y ++CONFIG_ARM_CPUIDLE=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_TIMES=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPUFREQ_DT=y ++CONFIG_ARM_SCPI_CPUFREQ=y ++CONFIG_ARM_SCMI_CPUFREQ=y ++CONFIG_ARM_SCMI_PROTOCOL=y ++# CONFIG_ARM_SCMI_POWER_DOMAIN is not set ++CONFIG_ARM_SCPI_PROTOCOL=y ++# CONFIG_ARM_SCPI_POWER_DOMAIN is not set ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++# CONFIG_SPARSEMEM_VMEMMAP is not set ++CONFIG_KSM=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_ZSMALLOC=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_XFRM_INTERFACE=y ++CONFIG_XFRM_STATISTICS=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_NET_IPGRE_DEMUX=y ++CONFIG_NET_IPVTI=y ++CONFIG_INET_ESP=y ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_UDP_DIAG=y ++CONFIG_INET_DIAG_DESTROY=y ++CONFIG_TCP_CONG_ADVANCED=y ++# CONFIG_TCP_CONG_BIC is not set ++# CONFIG_TCP_CONG_WESTWOOD is not set ++# CONFIG_TCP_CONG_HTCP is not set ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_ESP=y ++CONFIG_INET6_IPCOMP=y ++CONFIG_IPV6_MIP6=y ++CONFIG_IPV6_VTI=y ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_AMANDA=y ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_H323=y ++CONFIG_NF_CONNTRACK_IRC=y ++CONFIG_NF_CONNTRACK_NETBIOS_NS=y ++CONFIG_NF_CONNTRACK_PPTP=y ++CONFIG_NF_CONNTRACK_SANE=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NF_CT_NETLINK=y ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NETFILTER_XT_TARGET_NFLOG=y ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y ++CONFIG_NETFILTER_XT_TARGET_TPROXY=y ++CONFIG_NETFILTER_XT_TARGET_TRACE=y ++CONFIG_NETFILTER_XT_TARGET_SECMARK=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_MATCH_COMMENT=y ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y ++CONFIG_NETFILTER_XT_MATCH_LENGTH=y ++CONFIG_NETFILTER_XT_MATCH_LIMIT=y ++CONFIG_NETFILTER_XT_MATCH_MAC=y ++CONFIG_NETFILTER_XT_MATCH_MARK=y ++CONFIG_NETFILTER_XT_MATCH_OWNER=y ++CONFIG_NETFILTER_XT_MATCH_POLICY=y ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA=y ++CONFIG_NETFILTER_XT_MATCH_QUOTA2=y ++CONFIG_NETFILTER_XT_MATCH_SOCKET=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y ++CONFIG_NETFILTER_XT_MATCH_STRING=y ++CONFIG_NETFILTER_XT_MATCH_TIME=y ++CONFIG_NETFILTER_XT_MATCH_U32=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_NETMAP=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_SECURITY=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_L2TP=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_HTB=y ++CONFIG_NET_SCH_NETEM=y ++CONFIG_NET_SCH_INGRESS=y ++CONFIG_NET_CLS_U32=y ++CONFIG_NET_CLS_BPF=y ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_U32=y ++CONFIG_NET_CLS_ACT=y ++CONFIG_VSOCKETS=y ++CONFIG_VIRTIO_VSOCKETS=y ++CONFIG_CFG80211=y ++# CONFIG_CFG80211_DEFAULT_PS is not set ++# CONFIG_CFG80211_CRDA_SUPPORT is not set ++CONFIG_MAC80211=y ++# CONFIG_MAC80211_RC_MINSTREL is not set ++CONFIG_RFKILL=y ++CONFIG_PCI=y ++CONFIG_PCI_HOST_GENERIC=y ++# CONFIG_UEVENT_HELPER is not set ++CONFIG_DEVTMPFS=y ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++CONFIG_DEBUG_DEVRES=y ++CONFIG_OF_UNITTEST=y ++CONFIG_ZRAM=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_VIRTIO_BLK=y ++CONFIG_UID_SYS_STATS=y ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_VIRTIO=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_UEVENT=y ++CONFIG_DM_VERITY=y ++CONFIG_DM_VERITY_AVB=y ++CONFIG_DM_VERITY_FEC=y ++CONFIG_DM_BOW=y ++CONFIG_NETDEVICES=y ++CONFIG_NETCONSOLE=y ++CONFIG_NETCONSOLE_DYNAMIC=y ++CONFIG_TUN=y ++CONFIG_VIRTIO_NET=y ++# CONFIG_ETHERNET is not set ++CONFIG_PHYLIB=y ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_MPPE=y ++CONFIG_PPTP=y ++CONFIG_PPPOL2TP=y ++CONFIG_USB_RTL8152=y ++CONFIG_USB_USBNET=y ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++CONFIG_VIRT_WIFI=y ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_XPAD=y ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_XPAD_LEDS=y ++CONFIG_INPUT_TABLET=y ++CONFIG_TABLET_USB_ACECAD=y ++CONFIG_TABLET_USB_AIPTEK=y ++CONFIG_TABLET_USB_GTCO=y ++CONFIG_TABLET_USB_HANWANG=y ++CONFIG_TABLET_USB_KBTAB=y ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_UINPUT=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_EXAR is not set ++CONFIG_SERIAL_8250_NR_UARTS=48 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_MANY_PORTS=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_VIRTIO=y ++# CONFIG_HW_RANDOM_CAVIUM is not set ++# CONFIG_DEVPORT is not set ++# CONFIG_I2C_COMPAT is not set ++# CONFIG_I2C_HELPER_AUTO is not set ++# CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_CPU_THERMAL=y ++CONFIG_MEDIA_SUPPORT=y ++# CONFIG_VGA_ARB is not set ++CONFIG_DRM=y ++# CONFIG_DRM_FBDEV_EMULATION is not set ++CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_HRTIMER=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_DRIVERS is not set ++CONFIG_SND_INTEL8X0=y ++# CONFIG_SND_USB is not set ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_A4TECH=y ++CONFIG_HID_ACRUX=y ++CONFIG_HID_ACRUX_FF=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_BELKIN=y ++CONFIG_HID_CHERRY=y ++CONFIG_HID_CHICONY=y ++CONFIG_HID_PRODIKEYS=y ++CONFIG_HID_CYPRESS=y ++CONFIG_HID_DRAGONRISE=y ++CONFIG_DRAGONRISE_FF=y ++CONFIG_HID_EMS_FF=y ++CONFIG_HID_ELECOM=y ++CONFIG_HID_EZKEY=y ++CONFIG_HID_HOLTEK=y ++CONFIG_HID_KEYTOUCH=y ++CONFIG_HID_KYE=y ++CONFIG_HID_UCLOGIC=y ++CONFIG_HID_WALTOP=y ++CONFIG_HID_GYRATION=y ++CONFIG_HID_TWINHAN=y ++CONFIG_HID_KENSINGTON=y ++CONFIG_HID_LCPOWER=y ++CONFIG_HID_LOGITECH=y ++CONFIG_HID_LOGITECH_DJ=y ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_HID_MAGICMOUSE=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MONTEREY=y ++CONFIG_HID_MULTITOUCH=y ++CONFIG_HID_NTRIG=y ++CONFIG_HID_ORTEK=y ++CONFIG_HID_PANTHERLORD=y ++CONFIG_PANTHERLORD_FF=y ++CONFIG_HID_PETALYNX=y ++CONFIG_HID_PICOLCD=y ++CONFIG_HID_PRIMAX=y ++CONFIG_HID_ROCCAT=y ++CONFIG_HID_SAITEK=y ++CONFIG_HID_SAMSUNG=y ++CONFIG_HID_SONY=y ++CONFIG_HID_SPEEDLINK=y ++CONFIG_HID_SUNPLUS=y ++CONFIG_HID_GREENASIA=y ++CONFIG_GREENASIA_FF=y ++CONFIG_HID_SMARTJOYPLUS=y ++CONFIG_SMARTJOYPLUS_FF=y ++CONFIG_HID_TIVO=y ++CONFIG_HID_TOPSEED=y ++CONFIG_HID_THRUSTMASTER=y ++CONFIG_HID_WACOM=y ++CONFIG_HID_WIIMOTE=y ++CONFIG_HID_ZEROPLUS=y ++CONFIG_HID_ZYDACRON=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_UEVENT=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_ACC=y ++CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_MMC=y ++# CONFIG_PWRSEQ_EMMC is not set ++# CONFIG_PWRSEQ_SIMPLE is not set ++# CONFIG_MMC_BLOCK is not set ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_SYSTOHC is not set ++CONFIG_RTC_DRV_PL030=y ++CONFIG_RTC_DRV_PL031=y ++CONFIG_VIRTIO_PCI=y ++# CONFIG_VIRTIO_PCI_LEGACY is not set ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_STAGING=y ++CONFIG_ASHMEM=y ++CONFIG_ANDROID_VSOC=y ++CONFIG_ION=y ++CONFIG_COMMON_CLK_SCPI=y ++CONFIG_MAILBOX=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_ANDROID=y ++CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_F2FS_FS=y ++CONFIG_F2FS_FS_SECURITY=y ++CONFIG_FS_ENCRYPTION=y ++# CONFIG_DNOTIFY is not set ++CONFIG_QUOTA=y ++CONFIG_QFMT_V2=y ++CONFIG_FUSE_FS=y ++CONFIG_OVERLAY_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y ++CONFIG_SECURITY=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_LSM_MMAP_MIN_ADDR=65536 ++CONFIG_HARDENED_USERCOPY=y ++CONFIG_SECURITY_SELINUX=y ++CONFIG_CRYPTO_ADIANTUM=y ++CONFIG_CRYPTO_SHA512=y ++CONFIG_CRYPTO_LZ4=y ++CONFIG_CRYPTO_ZSTD=y ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_XZ_DEC=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_SOFTLOCKUP_DETECTOR=y ++# CONFIG_DETECT_HUNG_TASK is not set ++CONFIG_PANIC_TIMEOUT=5 ++CONFIG_SCHEDSTATS=y ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++CONFIG_ENABLE_DEFAULT_TRACERS=y ++# CONFIG_RUNTIME_TESTING_MENU is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch b/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch new file mode 100644 index 000000000000..78e5193e444d --- /dev/null +++ b/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch @@ -0,0 +1,128 @@ +From 0ad8fba0d7c02b5d2495829dd001b118809a83ee Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 20 Jun 2019 14:30:05 -0700 +Subject: ANDROID: gki_defconfig: more configs for partners + +Bug: 135666008 +Signed-off-by: Tri Vo +Change-Id: I5e13f602bcacb416cace48f92f40689ebd3bb12e +--- + abi_gki_aarch64.xml | 415449 +++++++++++++++------------- + arch/arm64/configs/gki_defconfig | 21 +- + 2 files changed, 222337 insertions(+), 193133 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -10,6 +10,7 @@ CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_MEMCG=y + CONFIG_MEMCG_SWAP=y ++CONFIG_BLK_CGROUP=y + CONFIG_RT_GROUP_SCHED=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y +@@ -61,12 +62,15 @@ CONFIG_ARM_SCMI_PROTOCOL=y + # CONFIG_ARM_SCMI_POWER_DOMAIN is not set + CONFIG_ARM_SCPI_PROTOCOL=y + # CONFIG_ARM_SCPI_POWER_DOMAIN is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_AES_ARM64=y + CONFIG_KPROBES=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + # CONFIG_SPARSEMEM_VMEMMAP is not set ++CONFIG_MEMORY_HOTPLUG=y + CONFIG_TRANSPARENT_HUGEPAGE=y + CONFIG_CMA=y + CONFIG_CMA_AREAS=16 +@@ -82,6 +86,7 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y + CONFIG_NET_IPGRE_DEMUX=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +@@ -165,6 +170,7 @@ CONFIG_IP6_NF_TARGET_REJECT=y + CONFIG_IP6_NF_MANGLE=y + CONFIG_IP6_NF_RAW=y + CONFIG_L2TP=y ++CONFIG_BRIDGE=y + CONFIG_NET_SCHED=y + CONFIG_NET_SCH_HTB=y + CONFIG_NET_SCH_INGRESS=y +@@ -175,6 +181,7 @@ CONFIG_NET_EMATCH_U32=y + CONFIG_NET_CLS_ACT=y + CONFIG_VSOCKETS=y + CONFIG_VIRTIO_VSOCKETS=y ++CONFIG_BT=y + CONFIG_CFG80211=y + # CONFIG_CFG80211_DEFAULT_PS is not set + # CONFIG_CFG80211_CRDA_SUPPORT is not set +@@ -242,7 +249,6 @@ CONFIG_USB_USBNET=y + # CONFIG_WLAN_VENDOR_QUANTENNA is not set + CONFIG_VIRT_WIFI=y + CONFIG_INPUT_EVDEV=y +-# CONFIG_INPUT_KEYBOARD is not set + # CONFIG_INPUT_MOUSE is not set + CONFIG_INPUT_JOYSTICK=y + CONFIG_INPUT_MISC=y +@@ -276,9 +282,11 @@ CONFIG_THERMAL=y + CONFIG_THERMAL_GOV_USER_SPACE=y + CONFIG_CPU_THERMAL=y + CONFIG_DEVFREQ_THERMAL=y ++CONFIG_MFD_SYSCON=y + CONFIG_REGULATOR=y + CONFIG_MEDIA_SUPPORT=y + CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y + # CONFIG_VGA_ARB is not set + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set +@@ -334,8 +342,14 @@ CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y + CONFIG_COMMON_CLK_SCPI=y ++CONFIG_HWSPINLOCK=y + CONFIG_MAILBOX=y + CONFIG_ARM_SMMU=y ++CONFIG_DEVFREQ_GOV_PERFORMANCE=y ++CONFIG_DEVFREQ_GOV_POWERSAVE=y ++CONFIG_DEVFREQ_GOV_USERSPACE=y ++CONFIG_DEVFREQ_GOV_PASSIVE=y ++CONFIG_EXTCON=y + CONFIG_PWM=y + CONFIG_GENERIC_PHY=y + CONFIG_ANDROID=y +@@ -355,6 +369,7 @@ CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=y + CONFIG_PSTORE=y + CONFIG_PSTORE_CONSOLE=y + CONFIG_PSTORE_RAM=y +@@ -364,11 +379,13 @@ CONFIG_SECURITY_NETWORK=y + CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y + CONFIG_CRYPTO_ADIANTUM=y ++CONFIG_CRYPTO_MD4=y + CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_ANSI_CPRNG=y + CONFIG_CRYPTO_DEV_VIRTIO=y ++CONFIG_CRC_CCITT=y + CONFIG_CRC8=y + CONFIG_XZ_DEC=y + CONFIG_DMA_CMA=y +@@ -384,3 +401,5 @@ CONFIG_SOFTLOCKUP_DETECTOR=y + CONFIG_PANIC_TIMEOUT=5 + CONFIG_SCHEDSTATS=y + # CONFIG_RUNTIME_TESTING_MENU is not set ++CONFIG_CORESIGHT=y ++CONFIG_CORESIGHT_STM=y diff --git a/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch b/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch new file mode 100644 index 000000000000..6b5cc6016e79 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch @@ -0,0 +1,69 @@ +From 4f8e773bb4a8fc494e0d786c6466bcd76ab0a693 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Sun, 19 May 2019 14:37:03 -0700 +Subject: ANDROID: gki_defconfig: more generic configs for + DLKMs + +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +Change-Id: I9f6380927f348d0a5e20d1acff2bef4331c3f591 +--- + arch/arm64/configs/gki_defconfig | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index b7ae05eb896e7..04f531ef25117 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -192,6 +192,8 @@ CONFIG_UID_SYS_STATS=y + CONFIG_SCSI=y + # CONFIG_SCSI_PROC_FS is not set + CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_UFSHCD=y ++CONFIG_SCSI_UFSHCD_PLATFORM=y + CONFIG_SCSI_VIRTIO=y + CONFIG_MD=y + CONFIG_BLK_DEV_DM=y +@@ -266,6 +268,7 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_I2C_COMPAT is not set + # CONFIG_I2C_HELPER_AUTO is not set + CONFIG_SPMI=y ++CONFIG_PINCTRL=y + CONFIG_GPIOLIB=y + # CONFIG_HWMON is not set + CONFIG_THERMAL=y +@@ -290,6 +293,8 @@ CONFIG_SND_DYNAMIC_MINORS=y + # CONFIG_SND_VERBOSE_PROCFS is not set + # CONFIG_SND_DRIVERS is not set + CONFIG_SND_INTEL8X0=y ++CONFIG_SND_USB_AUDIO=y ++CONFIG_SND_SOC=y + CONFIG_HIDRAW=y + CONFIG_UHID=y + CONFIG_HID_APPLE=y +@@ -310,6 +315,8 @@ CONFIG_MMC=y + # CONFIG_PWRSEQ_EMMC is not set + # CONFIG_PWRSEQ_SIMPLE is not set + # CONFIG_MMC_BLOCK is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y +@@ -329,11 +336,12 @@ CONFIG_ANDROID_VSOC=y + CONFIG_ION=y + CONFIG_COMMON_CLK_SCPI=y + CONFIG_MAILBOX=y +-CONFIG_PM_DEVFREQ=y ++CONFIG_ARM_SMMU=y + CONFIG_PWM=y + CONFIG_GENERIC_PHY=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y ++CONFIG_INTERCONNECT=y + CONFIG_EXT4_FS=y + CONFIG_EXT4_FS_SECURITY=y + CONFIG_F2FS_FS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-remove-more-recommended-config.patch b/patches/ANDROID-gki_defconfig-remove-more-recommended-config.patch new file mode 100644 index 000000000000..233281f1216c --- /dev/null +++ b/patches/ANDROID-gki_defconfig-remove-more-recommended-config.patch @@ -0,0 +1,50 @@ +From 9ecaedfaac196278ba1ea1ce4c8283cbb7820cb9 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 16 May 2019 09:57:57 -0700 +Subject: ANDROID: gki_defconfig: remove more recommended + configs + +Disable following configs: +CONFIG_KSM +CONFIG_SGETMASK_SYSCALL +CONFIG_ARM64_SW_TTBR0_PAN + +Bug: 132717553 +Test: boot arm64 cuttlefish +Signed-off-by: Tri Vo +Change-Id: I2689515f3ddff10d6ad09c41ac5f4a0415922357 +--- + arch/arm64/configs/gki_defconfig | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 9c1086a740cf7..b7ae05eb896e7 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -22,7 +22,6 @@ CONFIG_BLK_DEV_INITRD=y + # CONFIG_RD_XZ is not set + # CONFIG_RD_LZO is not set + # CONFIG_RD_LZ4 is not set +-CONFIG_SGETMASK_SYSCALL=y + # CONFIG_SYSFS_SYSCALL is not set + # CONFIG_FHANDLE is not set + CONFIG_KALLSYMS_ALL=y +@@ -40,7 +39,6 @@ CONFIG_ARMV8_DEPRECATED=y + CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y +-CONFIG_ARM64_SW_TTBR0_PAN=y + CONFIG_RANDOMIZE_BASE=y + # CONFIG_EFI is not set + CONFIG_COMPAT=y +@@ -67,7 +65,6 @@ CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + # CONFIG_SPARSEMEM_VMEMMAP is not set +-CONFIG_KSM=y + CONFIG_TRANSPARENT_HUGEPAGE=y + CONFIG_ZSMALLOC=y + CONFIG_NET=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch b/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch new file mode 100644 index 000000000000..2553a277d776 --- /dev/null +++ b/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch @@ -0,0 +1,46 @@ +From ee9fd08b5e142f62bc5b751ddeb6418cfe8c119a Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Mon, 26 Aug 2019 07:56:13 -0700 +Subject: ANDROID: gki_defconfig: set CONFIG_NR_CPUS=32 + +Consensus is that CONFIG_NR_CPUS of 32 will deal with the future +products with a moderate engineering margin. + +Signed-off-by: Mark Salyzyn +Test: confirm value propagates to .config +Bug: 139693734 +Bug: 139406736 +Bug: 139692860 +Change-Id: I9687d37da254a612947398a45ae56ab01e676562 +--- + arch/arm64/configs/gki_defconfig | 1 + + arch/x86/configs/gki_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index b70d608b1ee69..2773a84fd9390 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -37,6 +37,7 @@ CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_SCHED_MC=y ++CONFIG_NR_CPUS=32 + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y + CONFIG_COMPAT=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index ae3d165a79c3a..a1b2121bde8b6 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -35,6 +35,7 @@ CONFIG_SLAB_FREELIST_RANDOM=y + CONFIG_SLAB_FREELIST_HARDENED=y + CONFIG_PROFILING=y + CONFIG_SMP=y ++CONFIG_NR_CPUS=32 + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch b/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch new file mode 100644 index 000000000000..f55030e95f1d --- /dev/null +++ b/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch @@ -0,0 +1,27 @@ +From 125079727a716b483b018d40c164c1e7013cea2f Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Wed, 15 May 2019 15:47:18 -0700 +Subject: ANDROID: gki_defconfig: sync with savedefconfig + +Otherwise, build/build.sh will complain. + +Signed-off-by: Tri Vo +--- + arch/arm64/configs/gki_defconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 4b17f0f9d0ae8..9c1086a740cf7 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -62,7 +62,6 @@ CONFIG_ARM_SCMI_PROTOCOL=y + CONFIG_ARM_SCPI_PROTOCOL=y + # CONFIG_ARM_SCPI_POWER_DOMAIN is not set + CONFIG_KPROBES=y +-CONFIG_JUMP_LABEL=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch b/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch new file mode 100644 index 000000000000..54bc5527284b --- /dev/null +++ b/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch @@ -0,0 +1,55 @@ +From 33a5e52fa9dec25bc57a99883d6a675f36cc0543 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 20 Jun 2019 18:04:53 -0700 +Subject: ANDROID: gki_defconfig: workaround to enable configs + +We're interested in following configs, which can't be selected by +themselves: +CONFIG_GPIOLIB_IRQCHIP +CONFIG_GENERIC_PINCONF +CONFIG_PINCONF +CONFIG_PINMUX +CONFIG_GENERIC_TRACER +CONFIG_MFD_CORE + +As a workaround, enable configs that select the above: +CONFIG_PINCTRL_AMD +CONFIG_MFD_ACT8945A +CONFIG_FUNCTION_TRACER + +Bug: 135666008 +Bug: 135247530 +Change-Id: If348f54fc11ab2c35ed2241d50327d8ce3b0b72e +Signed-off-by: Tri Vo +--- + abi_gki_aarch64.xml | 221872 ++++++++++++++-------------- + arch/arm64/configs/gki_defconfig | 4 +- + 2 files changed, 110333 insertions(+), 111543 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -276,12 +276,13 @@ CONFIG_HW_RANDOM_VIRTIO=y + # CONFIG_I2C_HELPER_AUTO is not set + CONFIG_SPMI=y + CONFIG_PINCTRL=y +-CONFIG_GPIOLIB=y ++CONFIG_PINCTRL_AMD=y + # CONFIG_HWMON is not set + CONFIG_THERMAL=y + CONFIG_THERMAL_GOV_USER_SPACE=y + CONFIG_CPU_THERMAL=y + CONFIG_DEVFREQ_THERMAL=y ++CONFIG_MFD_ACT8945A=y + CONFIG_MFD_SYSCON=y + CONFIG_REGULATOR=y + CONFIG_MEDIA_SUPPORT=y +@@ -400,6 +401,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y + # CONFIG_DETECT_HUNG_TASK is not set + CONFIG_PANIC_TIMEOUT=5 + CONFIG_SCHEDSTATS=y ++CONFIG_FUNCTION_TRACER=y + # CONFIG_RUNTIME_TESTING_MENU is not set + CONFIG_CORESIGHT=y + CONFIG_CORESIGHT_STM=y diff --git a/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch b/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch new file mode 100644 index 000000000000..3f682e383116 --- /dev/null +++ b/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch @@ -0,0 +1,56 @@ +From 76c1e17520ad3f2e68fded7ea6f7e7612fec2f5f Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Wed, 28 Aug 2019 15:52:02 -0700 +Subject: ANDROID: init: GKI: add GKI_HACKS_TO_FIX + +Add CONFIG_GKI_HACKS_TO_FIX as a mechanism to force +hidden configs to be selected for modules that will be built +separately. Also used to select drivers that need to be +modularized. + +As these issues are resolved upstream, the configs should +be removed from GKI_HACKS_TO_FIX + +Bug: 141266428 +Change-Id: Ic8b2a17cd3a389ac5ef999c8c79b5b5dfee73c8a +Signed-off-by: Todd Kjos +--- + init/Kconfig | 2 ++ + init/Kconfig.gki | 15 +++++++++++++++ + 2 files changed, 17 insertions(+) + create mode 100644 init/Kconfig.gki + +diff --git a/init/Kconfig b/init/Kconfig +index bd7d650d4a996..3ff5a3ec7b559 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -2181,3 +2181,5 @@ config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE + # . + config ARCH_HAS_SYSCALL_WRAPPER + def_bool n ++ ++source "init/Kconfig.gki" +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +new file mode 100644 +index 0000000000000..fafcd618037de +--- /dev/null ++++ b/init/Kconfig.gki +@@ -0,0 +1,15 @@ ++# Atrocities needed for ++# a) building GKI modules in separate tree, or ++# b) building drivers that are not modularizable ++# ++# All of these should be reworked into an upstream solution ++# if possible. ++# ++config GKI_HACKS_TO_FIX ++ bool "GKI Dummy config options" ++ help ++ Dummy config option used to enable core functionality used by ++ modules that may not be selectable in this config. ++ ++ Unless you are building a GKI kernel to be used with modules ++ built from a different config, say N here. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch new file mode 100644 index 000000000000..77744aa3c7cc --- /dev/null +++ b/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch @@ -0,0 +1,46 @@ +From 0e99f5a95ab59f973a1a1d7cd51a3edef46747b5 Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 14:36:04 -0700 +Subject: ANDROID: init: GKI: enable hidden configs for DRM + +Add hidden configs to GKI_HACKS_TO_FIX so they +are enabled for loadable DRM modules built +out-of-tree. + +Bug: 141266428 +Change-Id: Ibeda203afa54edc4f9a1daec9b4e8a928eb934fb +Signed-off-by: Todd Kjos +--- + init/Kconfig.gki | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +index fafcd618037de..6c3f89bd8e25e 100644 +--- a/init/Kconfig.gki ++++ b/init/Kconfig.gki +@@ -1,3 +1,14 @@ ++config GKI_HIDDEN_DRM_CONFIGS ++ bool "Hidden DRM configs needed for GKI" ++ select DRM_KMS_HELPER if (HAS_IOMEM && DRM) ++ select DRM_GEM_CMA_HELPER ++ select DRM_KMS_CMA_HELPER ++ select DRM_MIPI_DSI ++ help ++ Dummy config option used to enable hidden DRM configs. ++ These are normally selected implicitely when including a ++ DRM module, but for GKI, the modules are built out-of-tree. ++ + # Atrocities needed for + # a) building GKI modules in separate tree, or + # b) building drivers that are not modularizable +@@ -7,6 +18,7 @@ + # + config GKI_HACKS_TO_FIX + bool "GKI Dummy config options" ++ select GKI_HIDDEN_DRM_CONFIGS + help + Dummy config option used to enable core functionality used by + modules that may not be selectable in this config. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch new file mode 100644 index 000000000000..8d60bd9d806e --- /dev/null +++ b/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch @@ -0,0 +1,46 @@ +From 9432ab303c8f7f7b632d0eac23e77b6915c18d0d Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 16:19:15 -0700 +Subject: ANDROID: init: GKI: enable hidden configs for GPIO + +Add hidden configs to GKI_HACKS_TO_FIX so they are +enabled for loadable GPIO modules built out-of-tree + +Bug: 141266428 +Change-Id: Ie6e79921df67e86783f04cb869604c988656a034 +Signed-off-by: Todd Kjos +--- + init/Kconfig.gki | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +index bbd5fac693550..5df8c67123ef4 100644 +--- a/init/Kconfig.gki ++++ b/init/Kconfig.gki +@@ -25,6 +25,15 @@ config GKI_HIDDEN_SND_SOC_CONFIGS + These are normally selected implicitely when a module + that relies on it is configured. + ++config GKI_HIDDEN_GPIO_CONFIGS ++ bool "Hidden GPIO configs needed for GKI" ++ select PINCTRL_SINGLE if (PINCTRL && OF && HAS_IOMEM) ++ select GPIO_PL061 if (HAS_IOMEM && ARM_AMBA && GPIOLIB) ++ help ++ Dummy config option used to enable hidden GPIO configs. ++ These are normally selected implicitely when a module ++ that relies on it is configured. ++ + # Atrocities needed for + # a) building GKI modules in separate tree, or + # b) building drivers that are not modularizable +@@ -37,6 +46,7 @@ config GKI_HACKS_TO_FIX + select GKI_HIDDEN_DRM_CONFIGS + select GKI_HIDDEN_REGMAP_CONFIGS + select GKI_HIDDEN_SND_SOC_CONFIGS ++ select GKI_HIDDEN_GPIO_CONFIGS + help + Dummy config option used to enable core functionality used by + modules that may not be selectable in this config. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch new file mode 100644 index 000000000000..15e628f6259a --- /dev/null +++ b/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch @@ -0,0 +1,45 @@ +From edc80363a1f2a16604a1d5bffc93e6311f224ff1 Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 15:57:02 -0700 +Subject: ANDROID: init: GKI: enable hidden configs for SND_SOC + +Add hidden configs to GKI_HACKS_TO_FIX so they are +enabled for loadable SND_SOC modules built out-of-tree + +Bug: 141266428 +Change-Id: I4782b5bb401a76c647bac41258c1371762dace1c +Signed-off-by: Todd Kjos +--- + init/Kconfig.gki | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +index 45966f3325b9a..bbd5fac693550 100644 +--- a/init/Kconfig.gki ++++ b/init/Kconfig.gki +@@ -17,6 +17,14 @@ config GKI_HIDDEN_REGMAP_CONFIGS + These are normally selected implicitely when a module + that relies on it is configured. + ++config GKI_HIDDEN_SND_SOC_CONFIGS ++ bool "Hidden SND_SOC configs needed for GKI" ++ select SND_SOC_GENERIC_DMAENGINE_PCM if (SND_SOC && SND) ++ help ++ Dummy config option used to enable hidden SND_SOC configs. ++ These are normally selected implicitely when a module ++ that relies on it is configured. ++ + # Atrocities needed for + # a) building GKI modules in separate tree, or + # b) building drivers that are not modularizable +@@ -28,6 +36,7 @@ config GKI_HACKS_TO_FIX + bool "GKI Dummy config options" + select GKI_HIDDEN_DRM_CONFIGS + select GKI_HIDDEN_REGMAP_CONFIGS ++ select GKI_HIDDEN_SND_SOC_CONFIGS + help + Dummy config option used to enable core functionality used by + modules that may not be selectable in this config. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch new file mode 100644 index 000000000000..4db3915dc234 --- /dev/null +++ b/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch @@ -0,0 +1,45 @@ +From 2ac00e9f01fc629c665fdc495beec17b019ddcf9 Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Tue, 17 Sep 2019 15:38:05 -0700 +Subject: ANDROID: init: GKI: enable hidden configs for regmap + +Add hidden configs to GKI_HACKS_TO_FIX so they are +enabled for loadable regmap modules built out-of-tree. + +Bug: 141266428 +Change-Id: I1dedb1fd6e26e36c12b28fcbbf0302f074547101 +Signed-off-by: Todd Kjos +--- + init/Kconfig.gki | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +index 6c3f89bd8e25e..45966f3325b9a 100644 +--- a/init/Kconfig.gki ++++ b/init/Kconfig.gki +@@ -9,6 +9,14 @@ config GKI_HIDDEN_DRM_CONFIGS + These are normally selected implicitely when including a + DRM module, but for GKI, the modules are built out-of-tree. + ++config GKI_HIDDEN_REGMAP_CONFIGS ++ bool "Hidden Regmap configs needed for GKI" ++ select REGMAP_IRQ ++ help ++ Dummy config option used to enable hidden regmap configs. ++ These are normally selected implicitely when a module ++ that relies on it is configured. ++ + # Atrocities needed for + # a) building GKI modules in separate tree, or + # b) building drivers that are not modularizable +@@ -19,6 +27,7 @@ config GKI_HIDDEN_DRM_CONFIGS + config GKI_HACKS_TO_FIX + bool "GKI Dummy config options" + select GKI_HIDDEN_DRM_CONFIGS ++ select GKI_HIDDEN_REGMAP_CONFIGS + help + Dummy config option used to enable core functionality used by + modules that may not be selectable in this config. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-label-cuttlefish-modules-for-gki.patch b/patches/ANDROID-label-cuttlefish-modules-for-gki.patch new file mode 100644 index 000000000000..eb3d0cbb81d9 --- /dev/null +++ b/patches/ANDROID-label-cuttlefish-modules-for-gki.patch @@ -0,0 +1,53 @@ +From cfb26413f900bc6e31d278a4ecf5f5a2e7ac2bbc Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 23 Jul 2019 15:19:58 -0700 +Subject: ANDROID: label cuttlefish modules for gki + +Bug: 138227143 +Test: Boot x86 cuttlefish and gki locally and via forrest +Change-Id: Iff0ea7f31f53897e16d753491e41c5f087abf77c +Signed-off-by: Ram Muthiah +--- + arch/arm64/configs/gki_defconfig | 3 ++- + arch/x86/configs/gki_defconfig | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 18e8f81cc0fb9..43a1fea94c6a5 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -1,3 +1,4 @@ ++CONFIG_LOCALVERSION="-mainline" + CONFIG_AUDIT=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y +@@ -319,7 +320,7 @@ CONFIG_USB_HIDDEV=y + CONFIG_USB=y + CONFIG_USB_OTG=y + CONFIG_USB_GADGET=y +-CONFIG_USB_DUMMY_HCD=y ++CONFIG_USB_DUMMY_HCD=m + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index eacebe96e4224..4016f8be75c52 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -1,3 +1,4 @@ ++CONFIG_LOCALVERSION="-mainline" + CONFIG_AUDIT=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y +@@ -267,7 +268,7 @@ CONFIG_HID_MULTITOUCH=y + CONFIG_USB_HIDDEV=y + CONFIG_USB=y + CONFIG_USB_GADGET=y +-CONFIG_USB_DUMMY_HCD=y ++CONFIG_USB_DUMMY_HCD=m + CONFIG_USB_CONFIGFS=y + CONFIG_USB_CONFIGFS_UEVENT=y + CONFIG_USB_CONFIGFS_F_FS=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-mm-add-a-field-to-store-names-for-private-an.patch b/patches/ANDROID-mm-add-a-field-to-store-names-for-private-an.patch new file mode 100644 index 000000000000..7216f700aa00 --- /dev/null +++ b/patches/ANDROID-mm-add-a-field-to-store-names-for-private-an.patch @@ -0,0 +1,648 @@ +From 462eb2c1881a6525613c558d04cdceda1bacce39 Mon Sep 17 00:00:00 2001 +From: Colin Cross +Date: Tue, 27 Oct 2015 16:42:08 -0700 +Subject: ANDROID: mm: add a field to store names for private + anonymous memory + +Userspace processes often have multiple allocators that each do +anonymous mmaps to get memory. When examining memory usage of +individual processes or systems as a whole, it is useful to be +able to break down the various heaps that were allocated by +each layer and examine their size, RSS, and physical memory +usage. + +This patch adds a user pointer to the shared union in +vm_area_struct that points to a null terminated string inside +the user process containing a name for the vma. vmas that +point to the same address will be merged, but vmas that +point to equivalent strings at different addresses will +not be merged. + +Userspace can set the name for a region of memory by calling +prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, (unsigned long)name); +Setting the name to NULL clears it. + +The names of named anonymous vmas are shown in /proc/pid/maps +as [anon:] and in /proc/pid/smaps in a new "Name" field +that is only present for named vmas. If the userspace pointer +is no longer valid all or part of the name will be replaced +with "". + +The idea to store a userspace pointer to reduce the complexity +within mm (at the expense of the complexity of reading +/proc/pid/mem) came from Dave Hansen. This results in no +runtime overhead in the mm subsystem other than comparing +the anon_name pointers when considering vma merging. The pointer +is stored in a union with fieds that are only used on file-backed +mappings, so it does not increase memory usage. + +Includes fix from Jed Davis for typo in +prctl_set_vma_anon_name, which could attempt to set the name +across two vmas at the same time due to a typo, which might +corrupt the vma list. Fix it to use tmp instead of end to limit +the name setting to a single vma at a time. + +Bug: 120441514 +Change-Id: I9aa7b6b5ef536cd780599ba4e2fba8ceebe8b59f +Signed-off-by: Dmitry Shmidt +[AmitP: Fix get_user_pages_remote() call to align with upstream commit + 5b56d49fc31d ("mm: add locked parameter to get_user_pages_remote()")] +Signed-off-by: Amit Pundir +--- + Documentation/filesystems/proc.txt | 6 ++ + fs/proc/task_mmu.c | 64 +++++++++++- + fs/userfaultfd.c | 9 +- + include/linux/mm.h | 2 +- + include/linux/mm_types.h | 24 ++++- + include/uapi/linux/prctl.h | 3 + + kernel/sys.c | 152 +++++++++++++++++++++++++++++ + mm/madvise.c | 2 +- + mm/mempolicy.c | 3 +- + mm/mlock.c | 2 +- + mm/mmap.c | 39 +++++--- + mm/mprotect.c | 2 +- + 12 files changed, 280 insertions(+), 28 deletions(-) + +diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt +index 99ca040e3f900..4579d1452f898 100644 +--- a/Documentation/filesystems/proc.txt ++++ b/Documentation/filesystems/proc.txt +@@ -415,6 +415,8 @@ is not associated with a file: + [stack] = the stack of the main process + [vdso] = the "virtual dynamic shared object", + the kernel system call handler ++ [anon:] = an anonymous mapping that has been ++ named by userspace + + or if empty, the mapping is anonymous. + +@@ -447,6 +449,7 @@ MMUPageSize: 4 kB + Locked: 0 kB + THPeligible: 0 + VmFlags: rd ex mr mw me dw ++Name: name from userspace + + The first of these lines shows the same information as is displayed for the + mapping in /proc/PID/maps. Following lines show the size of the mapping +@@ -526,6 +529,9 @@ be vanished or the reverse -- new added. Interpretation of their meaning + might change in future as well. So each consumer of these flags has to + follow each specific kernel version for the exact semantic. + ++The "Name" field will only be present on a mapping that has been named by ++userspace, and will show the name passed in by userspace. ++ + This file is only present if the CONFIG_MMU kernel configuration option is + enabled. + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 731642e0f5a0f..3275002c23fc6 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -123,6 +123,56 @@ static void release_task_mempolicy(struct proc_maps_private *priv) + } + #endif + ++static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma) ++{ ++ const char __user *name = vma_get_anon_name(vma); ++ struct mm_struct *mm = vma->vm_mm; ++ ++ unsigned long page_start_vaddr; ++ unsigned long page_offset; ++ unsigned long num_pages; ++ unsigned long max_len = NAME_MAX; ++ int i; ++ ++ page_start_vaddr = (unsigned long)name & PAGE_MASK; ++ page_offset = (unsigned long)name - page_start_vaddr; ++ num_pages = DIV_ROUND_UP(page_offset + max_len, PAGE_SIZE); ++ ++ seq_puts(m, "[anon:"); ++ ++ for (i = 0; i < num_pages; i++) { ++ int len; ++ int write_len; ++ const char *kaddr; ++ long pages_pinned; ++ struct page *page; ++ ++ pages_pinned = get_user_pages_remote(current, mm, ++ page_start_vaddr, 1, 0, &page, NULL, NULL); ++ if (pages_pinned < 1) { ++ seq_puts(m, "]"); ++ return; ++ } ++ ++ kaddr = (const char *)kmap(page); ++ len = min(max_len, PAGE_SIZE - page_offset); ++ write_len = strnlen(kaddr + page_offset, len); ++ seq_write(m, kaddr + page_offset, write_len); ++ kunmap(page); ++ put_page(page); ++ ++ /* if strnlen hit a null terminator then we're done */ ++ if (write_len != len) ++ break; ++ ++ max_len -= len; ++ page_offset = 0; ++ page_start_vaddr += PAGE_SIZE; ++ } ++ ++ seq_putc(m, ']'); ++} ++ + static void vma_stop(struct proc_maps_private *priv) + { + struct mm_struct *mm = priv->mm; +@@ -348,8 +398,15 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) + goto done; + } + +- if (is_stack(vma)) ++ if (is_stack(vma)) { + name = "[stack]"; ++ goto done; ++ } ++ ++ if (vma_get_anon_name(vma)) { ++ seq_pad(m, ' '); ++ seq_print_vma_name(m, vma); ++ } + } + + done: +@@ -824,6 +881,11 @@ static int show_smap(struct seq_file *m, void *v) + smap_gather_stats(vma, &mss); + + show_map_vma(m, vma); ++ if (vma_get_anon_name(vma)) { ++ seq_puts(m, "Name: "); ++ seq_print_vma_name(m, vma); ++ seq_putc(m, '\n'); ++ } + + SEQ_PUT_DEC("Size: ", vma->vm_end - vma->vm_start); + SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma)); +diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c +index fe6d804a38dc2..33f2614210e0d 100644 +--- a/fs/userfaultfd.c ++++ b/fs/userfaultfd.c +@@ -912,7 +912,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file) + new_flags, vma->anon_vma, + vma->vm_file, vma->vm_pgoff, + vma_policy(vma), +- NULL_VM_UFFD_CTX); ++ NULL_VM_UFFD_CTX, ++ vma_get_anon_name(vma)); + if (prev) + vma = prev; + else +@@ -1462,7 +1463,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, + prev = vma_merge(mm, prev, start, vma_end, new_flags, + vma->anon_vma, vma->vm_file, vma->vm_pgoff, + vma_policy(vma), +- ((struct vm_userfaultfd_ctx){ ctx })); ++ ((struct vm_userfaultfd_ctx){ ctx }), ++ vma_get_anon_name(vma)); + if (prev) { + vma = prev; + goto next; +@@ -1624,7 +1626,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, + prev = vma_merge(mm, prev, start, vma_end, new_flags, + vma->anon_vma, vma->vm_file, vma->vm_pgoff, + vma_policy(vma), +- NULL_VM_UFFD_CTX); ++ NULL_VM_UFFD_CTX, ++ vma_get_anon_name(vma)); + if (prev) { + vma = prev; + goto next; +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 0334ca97c584d..9fd371a63cab5 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -2301,7 +2301,7 @@ static inline int vma_adjust(struct vm_area_struct *vma, unsigned long start, + extern struct vm_area_struct *vma_merge(struct mm_struct *, + struct vm_area_struct *prev, unsigned long addr, unsigned long end, + unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t, +- struct mempolicy *, struct vm_userfaultfd_ctx); ++ struct mempolicy *, struct vm_userfaultfd_ctx, const char __user *); + extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *); + extern int __split_vma(struct mm_struct *, struct vm_area_struct *, + unsigned long addr, int new_below); +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 6a7a1083b6fb7..2b09663f0db62 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -313,11 +313,18 @@ struct vm_area_struct { + /* + * For areas with an address space and backing store, + * linkage into the address_space->i_mmap interval tree. ++ * ++ * For private anonymous mappings, a pointer to a null terminated string ++ * in the user process containing the name given to the vma, or NULL ++ * if unnamed. + */ +- struct { +- struct rb_node rb; +- unsigned long rb_subtree_last; +- } shared; ++ union { ++ struct { ++ struct rb_node rb; ++ unsigned long rb_subtree_last; ++ } shared; ++ const char __user *anon_name; ++ }; + + /* + * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma +@@ -746,4 +753,13 @@ typedef struct { + unsigned long val; + } swp_entry_t; + ++/* Return the name for an anonymous mapping or NULL for a file-backed mapping */ ++static inline const char __user *vma_get_anon_name(struct vm_area_struct *vma) ++{ ++ if (vma->vm_file) ++ return NULL; ++ ++ return vma->anon_name; ++} ++ + #endif /* _LINUX_MM_TYPES_H */ +diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h +index 094bb03b9cc28..e057eddb572f3 100644 +--- a/include/uapi/linux/prctl.h ++++ b/include/uapi/linux/prctl.h +@@ -229,4 +229,7 @@ struct prctl_mm_map { + # define PR_PAC_APDBKEY (1UL << 3) + # define PR_PAC_APGAKEY (1UL << 4) + ++#define PR_SET_VMA 0x53564d41 ++# define PR_SET_VMA_ANON_NAME 0 ++ + #endif /* _LINUX_PRCTL_H */ +diff --git a/kernel/sys.c b/kernel/sys.c +index 2969304c29fe3..54f8fabc58e4f 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -42,6 +42,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -2269,6 +2271,153 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, + return -EINVAL; + } + ++#ifdef CONFIG_MMU ++static int prctl_update_vma_anon_name(struct vm_area_struct *vma, ++ struct vm_area_struct **prev, ++ unsigned long start, unsigned long end, ++ const char __user *name_addr) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ int error = 0; ++ pgoff_t pgoff; ++ ++ if (name_addr == vma_get_anon_name(vma)) { ++ *prev = vma; ++ goto out; ++ } ++ ++ pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); ++ *prev = vma_merge(mm, *prev, start, end, vma->vm_flags, vma->anon_vma, ++ vma->vm_file, pgoff, vma_policy(vma), ++ vma->vm_userfaultfd_ctx, name_addr); ++ if (*prev) { ++ vma = *prev; ++ goto success; ++ } ++ ++ *prev = vma; ++ ++ if (start != vma->vm_start) { ++ error = split_vma(mm, vma, start, 1); ++ if (error) ++ goto out; ++ } ++ ++ if (end != vma->vm_end) { ++ error = split_vma(mm, vma, end, 0); ++ if (error) ++ goto out; ++ } ++ ++success: ++ if (!vma->vm_file) ++ vma->anon_name = name_addr; ++ ++out: ++ if (error == -ENOMEM) ++ error = -EAGAIN; ++ return error; ++} ++ ++static int prctl_set_vma_anon_name(unsigned long start, unsigned long end, ++ unsigned long arg) ++{ ++ unsigned long tmp; ++ struct vm_area_struct *vma, *prev; ++ int unmapped_error = 0; ++ int error = -EINVAL; ++ ++ /* ++ * If the interval [start,end) covers some unmapped address ++ * ranges, just ignore them, but return -ENOMEM at the end. ++ * - this matches the handling in madvise. ++ */ ++ vma = find_vma_prev(current->mm, start, &prev); ++ if (vma && start > vma->vm_start) ++ prev = vma; ++ ++ for (;;) { ++ /* Still start < end. */ ++ error = -ENOMEM; ++ if (!vma) ++ return error; ++ ++ /* Here start < (end|vma->vm_end). */ ++ if (start < vma->vm_start) { ++ unmapped_error = -ENOMEM; ++ start = vma->vm_start; ++ if (start >= end) ++ return error; ++ } ++ ++ /* Here vma->vm_start <= start < (end|vma->vm_end) */ ++ tmp = vma->vm_end; ++ if (end < tmp) ++ tmp = end; ++ ++ /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */ ++ error = prctl_update_vma_anon_name(vma, &prev, start, tmp, ++ (const char __user *)arg); ++ if (error) ++ return error; ++ start = tmp; ++ if (prev && start < prev->vm_end) ++ start = prev->vm_end; ++ error = unmapped_error; ++ if (start >= end) ++ return error; ++ if (prev) ++ vma = prev->vm_next; ++ else /* madvise_remove dropped mmap_sem */ ++ vma = find_vma(current->mm, start); ++ } ++} ++ ++static int prctl_set_vma(unsigned long opt, unsigned long start, ++ unsigned long len_in, unsigned long arg) ++{ ++ struct mm_struct *mm = current->mm; ++ int error; ++ unsigned long len; ++ unsigned long end; ++ ++ if (start & ~PAGE_MASK) ++ return -EINVAL; ++ len = (len_in + ~PAGE_MASK) & PAGE_MASK; ++ ++ /* Check to see whether len was rounded up from small -ve to zero */ ++ if (len_in && !len) ++ return -EINVAL; ++ ++ end = start + len; ++ if (end < start) ++ return -EINVAL; ++ ++ if (end == start) ++ return 0; ++ ++ down_write(&mm->mmap_sem); ++ ++ switch (opt) { ++ case PR_SET_VMA_ANON_NAME: ++ error = prctl_set_vma_anon_name(start, end, arg); ++ break; ++ default: ++ error = -EINVAL; ++ } ++ ++ up_write(&mm->mmap_sem); ++ ++ return error; ++} ++#else /* CONFIG_MMU */ ++static int prctl_set_vma(unsigned long opt, unsigned long start, ++ unsigned long len_in, unsigned long arg) ++{ ++ return -EINVAL; ++} ++#endif ++ + SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + unsigned long, arg4, unsigned long, arg5) + { +@@ -2487,6 +2636,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + return -EINVAL; + error = arch_prctl_spec_ctrl_set(me, arg2, arg3); + break; ++ case PR_SET_VMA: ++ error = prctl_set_vma(arg2, arg3, arg4, arg5); ++ break; + case PR_PAC_RESET_KEYS: + if (arg3 || arg4 || arg5) + return -EINVAL; +diff --git a/mm/madvise.c b/mm/madvise.c +index 968df3aa069fd..b733c33c975af 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -138,7 +138,7 @@ static long madvise_behavior(struct vm_area_struct *vma, + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); + *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma, + vma->vm_file, pgoff, vma_policy(vma), +- vma->vm_userfaultfd_ctx); ++ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); + if (*prev) { + vma = *prev; + goto success; +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 65e0874fce173..460282a8e4fe7 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -758,7 +758,8 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, + ((vmstart - vma->vm_start) >> PAGE_SHIFT); + prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, + vma->anon_vma, vma->vm_file, pgoff, +- new_pol, vma->vm_userfaultfd_ctx); ++ new_pol, vma->vm_userfaultfd_ctx, ++ vma_get_anon_name(vma)); + if (prev) { + vma = prev; + next = vma->vm_next; +diff --git a/mm/mlock.c b/mm/mlock.c +index a90099da4fb41..25d326f1009d6 100644 +--- a/mm/mlock.c ++++ b/mm/mlock.c +@@ -535,7 +535,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); + *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma, + vma->vm_file, pgoff, vma_policy(vma), +- vma->vm_userfaultfd_ctx); ++ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); + if (*prev) { + vma = *prev; + goto success; +diff --git a/mm/mmap.c b/mm/mmap.c +index 7e8c3e8ae75f1..51cd78b7c53b4 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1008,7 +1008,8 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, + */ + static inline int is_mergeable_vma(struct vm_area_struct *vma, + struct file *file, unsigned long vm_flags, +- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) ++ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, ++ const char __user *anon_name) + { + /* + * VM_SOFTDIRTY should not prevent from VMA merging, if we +@@ -1026,6 +1027,8 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma, + return 0; + if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx)) + return 0; ++ if (vma_get_anon_name(vma) != anon_name) ++ return 0; + return 1; + } + +@@ -1058,9 +1061,10 @@ static int + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, + struct anon_vma *anon_vma, struct file *file, + pgoff_t vm_pgoff, +- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) ++ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, ++ const char __user *anon_name) + { +- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) && ++ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) && + is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { + if (vma->vm_pgoff == vm_pgoff) + return 1; +@@ -1079,9 +1083,10 @@ static int + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + struct anon_vma *anon_vma, struct file *file, + pgoff_t vm_pgoff, +- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) ++ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, ++ const char __user *anon_name) + { +- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) && ++ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) && + is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { + pgoff_t vm_pglen; + vm_pglen = vma_pages(vma); +@@ -1092,9 +1097,9 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + } + + /* +- * Given a mapping request (addr,end,vm_flags,file,pgoff), figure out +- * whether that can be merged with its predecessor or its successor. +- * Or both (it neatly fills a hole). ++ * Given a mapping request (addr,end,vm_flags,file,pgoff,anon_name), ++ * figure out whether that can be merged with its predecessor or its ++ * successor. Or both (it neatly fills a hole). + * + * In most cases - when called for mmap, brk or mremap - [addr,end) is + * certain not to be mapped by the time vma_merge is called; but when +@@ -1136,7 +1141,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, + unsigned long end, unsigned long vm_flags, + struct anon_vma *anon_vma, struct file *file, + pgoff_t pgoff, struct mempolicy *policy, +- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) ++ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, ++ const char __user *anon_name) + { + pgoff_t pglen = (end - addr) >> PAGE_SHIFT; + struct vm_area_struct *area, *next; +@@ -1169,7 +1175,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, + mpol_equal(vma_policy(prev), policy) && + can_vma_merge_after(prev, vm_flags, + anon_vma, file, pgoff, +- vm_userfaultfd_ctx)) { ++ vm_userfaultfd_ctx, ++ anon_name)) { + /* + * OK, it can. Can we now merge in the successor as well? + */ +@@ -1178,7 +1185,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, + can_vma_merge_before(next, vm_flags, + anon_vma, file, + pgoff+pglen, +- vm_userfaultfd_ctx) && ++ vm_userfaultfd_ctx, ++ anon_name) && + is_mergeable_anon_vma(prev->anon_vma, + next->anon_vma, NULL)) { + /* cases 1, 6 */ +@@ -1201,7 +1209,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, + mpol_equal(policy, vma_policy(next)) && + can_vma_merge_before(next, vm_flags, + anon_vma, file, pgoff+pglen, +- vm_userfaultfd_ctx)) { ++ vm_userfaultfd_ctx, ++ anon_name)) { + if (prev && addr < prev->vm_end) /* case 4 */ + err = __vma_adjust(prev, prev->vm_start, + addr, prev->vm_pgoff, NULL, next); +@@ -1746,7 +1755,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, + * Can we just expand an old mapping? + */ + vma = vma_merge(mm, prev, addr, addr + len, vm_flags, +- NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX); ++ NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX, NULL); + if (vma) + goto out; + +@@ -3025,7 +3034,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla + + /* Can we just expand an old private anonymous mapping? */ + vma = vma_merge(mm, prev, addr, addr + len, flags, +- NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX); ++ NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX, NULL); + if (vma) + goto out; + +@@ -3223,7 +3232,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, + return NULL; /* should never get here */ + new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags, + vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma), +- vma->vm_userfaultfd_ctx); ++ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); + if (new_vma) { + /* + * Source vma may have been merged into new_vma +diff --git a/mm/mprotect.c b/mm/mprotect.c +index bf38dfbbb4b47..9b19034440bbd 100644 +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -400,7 +400,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); + *pprev = vma_merge(mm, *pprev, start, end, newflags, + vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma), +- vma->vm_userfaultfd_ctx); ++ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); + if (*pprev) { + vma = *pprev; + VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functional.patch b/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functional.patch new file mode 100644 index 000000000000..94b377ba6363 --- /dev/null +++ b/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functional.patch @@ -0,0 +1,54 @@ +From 7abf32b804fd1f264261186672e46ec49611c88c Mon Sep 17 00:00:00 2001 +From: Dmitry Shmidt +Date: Thu, 7 Oct 2010 14:39:16 -0700 +Subject: ANDROID: mmc: core: Add "ignore mmc pm notify" + functionality + +Used to prevent remounting MMC on suspend/resume. + +Bug: 120441127 +Change-Id: I20821a82831b07ca037973d5d92e832372c6b583 +Signed-off-by: Dmitry Shmidt +--- + drivers/mmc/core/host.c | 6 ++++-- + include/linux/mmc/pm.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c +index 105b7a7c02513..faa6975d436c8 100644 +--- a/drivers/mmc/core/host.c ++++ b/drivers/mmc/core/host.c +@@ -480,7 +480,8 @@ int mmc_add_host(struct mmc_host *host) + #endif + + mmc_start_host(host); +- mmc_register_pm_notifier(host); ++ if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) ++ mmc_register_pm_notifier(host); + + return 0; + } +@@ -497,7 +498,8 @@ EXPORT_SYMBOL(mmc_add_host); + */ + void mmc_remove_host(struct mmc_host *host) + { +- mmc_unregister_pm_notifier(host); ++ if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) ++ mmc_unregister_pm_notifier(host); + mmc_stop_host(host); + + #ifdef CONFIG_DEBUG_FS +diff --git a/include/linux/mmc/pm.h b/include/linux/mmc/pm.h +index 3549f80457846..1d554b858086b 100644 +--- a/include/linux/mmc/pm.h ++++ b/include/linux/mmc/pm.h +@@ -23,5 +23,6 @@ typedef unsigned int mmc_pm_flag_t; + + #define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */ + #define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */ ++#define MMC_PM_IGNORE_PM_NOTIFY (1 << 2) /* ignore mmc pm notify */ + + #endif /* LINUX_MMC_PM_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-poi.patch b/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-poi.patch new file mode 100644 index 000000000000..0c0dd6090ec8 --- /dev/null +++ b/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-poi.patch @@ -0,0 +1,172 @@ +From 4a3ab8dab982f61a525fb666b003de1e071c5ef6 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Wed, 26 Oct 2016 15:29:51 -0700 +Subject: ANDROID: mnt: Add filesystem private data to mount + points + +This starts to add private data associated directly +to mount points. The intent is to give filesystems +a sense of where they have come from, as a means of +letting a filesystem take different actions based on +this information. + +Bug: 62094374 +Bug: 120446149 +Bug: 122428178 +Change-Id: Ie769d7b3bb2f5972afe05c1bf16cf88c91647ab2 +Signed-off-by: Daniel Rosenberg +[astrachan: Folded 89a54ed3bf68 ("ANDROID: mnt: Fix next_descendent") + into this patch] +[drosen: Folded 138993ea820 ("Android: mnt: Propagate remount + correctly") into this patch, integrated fs_context things + Now has update_mnt_data instead of needing remount2 +Signed-off-by: Alistair Strachan +--- + fs/namespace.c | 28 +++++++++++++++++++++++++++- + fs/pnode.c | 16 ++++++++++++++++ + fs/pnode.h | 1 + + include/linux/fs.h | 4 ++++ + include/linux/mount.h | 1 + + 5 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index d28d30b130439..2f5aad606ff92 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -198,6 +198,7 @@ static struct mount *alloc_vfsmnt(const char *name) + mnt->mnt_count = 1; + mnt->mnt_writers = 0; + #endif ++ mnt->mnt.data = NULL; + + INIT_HLIST_NODE(&mnt->mnt_hash); + INIT_LIST_HEAD(&mnt->mnt_child); +@@ -547,6 +548,7 @@ int sb_prepare_remount_readonly(struct super_block *sb) + + static void free_vfsmnt(struct mount *mnt) + { ++ kfree(mnt->mnt.data); + kfree_const(mnt->mnt_devname); + #ifdef CONFIG_SMP + free_percpu(mnt->mnt_pcp); +@@ -941,6 +943,15 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc) + if (!mnt) + return ERR_PTR(-ENOMEM); + ++ if (fc->fs_type->alloc_mnt_data) { ++ mnt->mnt.data = fc->fs_type->alloc_mnt_data(); ++ if (!mnt->mnt.data) { ++ mnt_free_id(mnt); ++ free_vfsmnt(mnt); ++ return ERR_PTR(-ENOMEM); ++ } ++ fc->root->d_sb->s_op->update_mnt_data(mnt->mnt.data, fc); ++ } + if (fc->sb_flags & SB_KERNMOUNT) + mnt->mnt.mnt_flags = MNT_INTERNAL; + +@@ -1024,6 +1035,14 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, + if (!mnt) + return ERR_PTR(-ENOMEM); + ++ if (sb->s_op->clone_mnt_data) { ++ mnt->mnt.data = sb->s_op->clone_mnt_data(old->mnt.data); ++ if (!mnt->mnt.data) { ++ err = -ENOMEM; ++ goto out_free; ++ } ++ } ++ + if (flag & (CL_SLAVE | CL_PRIVATE | CL_SHARED_TO_SLAVE)) + mnt->mnt_group_id = 0; /* not a peer of original */ + else +@@ -2523,8 +2542,15 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, + err = -EPERM; + if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { + err = reconfigure_super(fc); +- if (!err) ++ if (!err) { ++ sb->s_op->update_mnt_data(mnt->mnt.data, fc); + set_mount_attributes(mnt, mnt_flags); ++ namespace_lock(); ++ lock_mount_hash(); ++ propagate_remount(mnt); ++ unlock_mount_hash(); ++ namespace_unlock(); ++ } + } + up_write(&sb->s_umount); + } +diff --git a/fs/pnode.c b/fs/pnode.c +index 49f6d7ff21394..16b2d165b5e9c 100644 +--- a/fs/pnode.c ++++ b/fs/pnode.c +@@ -601,3 +601,19 @@ int propagate_umount(struct list_head *list) + + return 0; + } ++ ++void propagate_remount(struct mount *mnt) ++{ ++ struct mount *parent = mnt->mnt_parent; ++ struct mount *p = mnt, *m; ++ struct super_block *sb = mnt->mnt.mnt_sb; ++ ++ if (!sb->s_op->copy_mnt_data) ++ return; ++ for (p = propagation_next(parent, parent); p; ++ p = propagation_next(p, parent)) { ++ m = __lookup_mnt(&p->mnt, mnt->mnt_mountpoint); ++ if (m) ++ sb->s_op->copy_mnt_data(m->mnt.data, mnt->mnt.data); ++ } ++} +diff --git a/fs/pnode.h b/fs/pnode.h +index 49a058c73e4c7..a95e519b77bf3 100644 +--- a/fs/pnode.h ++++ b/fs/pnode.h +@@ -42,6 +42,7 @@ int propagate_mnt(struct mount *, struct mountpoint *, struct mount *, + int propagate_umount(struct list_head *); + int propagate_mount_busy(struct mount *, int); + void propagate_mount_unlock(struct mount *); ++void propagate_remount(struct mount *); + void mnt_release_group_id(struct mount *); + int get_dominating_id(struct mount *mnt, const struct path *root); + unsigned int mnt_get_count(struct mount *mnt); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 045bd6ff12ae1..42eb38778351c 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1937,6 +1937,9 @@ struct super_operations { + int (*unfreeze_fs) (struct super_block *); + int (*statfs) (struct dentry *, struct kstatfs *); + int (*remount_fs) (struct super_block *, int *, char *); ++ void *(*clone_mnt_data) (void *); ++ void (*copy_mnt_data) (void *, void *); ++ void (*update_mnt_data) (void *, struct fs_context *); + void (*umount_begin) (struct super_block *); + + int (*show_options)(struct seq_file *, struct dentry *); +@@ -2207,6 +2210,7 @@ struct file_system_type { + const struct fs_parameter_description *parameters; + struct dentry *(*mount) (struct file_system_type *, int, + const char *, void *); ++ void *(*alloc_mnt_data) (void); + void (*kill_sb) (struct super_block *); + struct module *owner; + struct file_system_type * next; +diff --git a/include/linux/mount.h b/include/linux/mount.h +index bf8cc4108b8f9..20541916e3605 100644 +--- a/include/linux/mount.h ++++ b/include/linux/mount.h +@@ -69,6 +69,7 @@ struct vfsmount { + struct dentry *mnt_root; /* root of the mounted tree */ + struct super_block *mnt_sb; /* pointer to superblock */ + int mnt_flags; ++ void *data; + } __randomize_layout; + + struct file; /* forward dec */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch b/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch new file mode 100644 index 000000000000..81aa260ac5c3 --- /dev/null +++ b/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch @@ -0,0 +1,65 @@ +From 7920564b989448af92f3a0e5c64c6269565aa005 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Mon, 22 Jul 2019 14:29:35 -0700 +Subject: ANDROID: mnt: Fix null pointer dereference + +Fix "ANDROID: mnt: Add filesystem private data to mount points" to only +call update_mnt_data() if the filesystem provides the function. This +avoids a null pointer dereference in do_mount(). + +Reported-by: youling 257 +Signed-off-by: Alistair Delva +Signed-off-by: Daniel Rosenberg +Change-Id: I6aedaa89536ae85e6bc29093f38934c672c8fe42 +--- + fs/namespace.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 2f5aad606ff92..2d600caf9fd8b 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -935,9 +935,11 @@ static struct mount *skip_mnt_tree(struct mount *p) + struct vfsmount *vfs_create_mount(struct fs_context *fc) + { + struct mount *mnt; ++ struct super_block *sb; + + if (!fc->root) + return ERR_PTR(-EINVAL); ++ sb = fc->root->d_sb; + + mnt = alloc_vfsmnt(fc->source ?: "none"); + if (!mnt) +@@ -950,7 +952,8 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc) + free_vfsmnt(mnt); + return ERR_PTR(-ENOMEM); + } +- fc->root->d_sb->s_op->update_mnt_data(mnt->mnt.data, fc); ++ if (sb->s_op->update_mnt_data) ++ sb->s_op->update_mnt_data(mnt->mnt.data, fc); + } + if (fc->sb_flags & SB_KERNMOUNT) + mnt->mnt.mnt_flags = MNT_INTERNAL; +@@ -2542,7 +2545,7 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, + err = -EPERM; + if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { + err = reconfigure_super(fc); +- if (!err) { ++ if (!err && sb->s_op->update_mnt_data) { + sb->s_op->update_mnt_data(mnt->mnt.data, fc); + set_mount_attributes(mnt, mnt_flags); + namespace_lock(); +@@ -2550,7 +2553,8 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, + propagate_remount(mnt); + unlock_mount_hash(); + namespace_unlock(); +- } ++ } else if (!err) ++ set_mount_attributes(mnt, mnt_flags); + } + up_write(&sb->s_umount); + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-net-enable-wireless-core-features-with-GKI_.patch b/patches/ANDROID-net-enable-wireless-core-features-with-GKI_.patch new file mode 100644 index 000000000000..ee539b45cf5c --- /dev/null +++ b/patches/ANDROID-net-enable-wireless-core-features-with-GKI_.patch @@ -0,0 +1,67 @@ +From 8a167346a33aa28c6e422739e69abc87f57f81bc Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Fri, 30 Aug 2019 08:23:25 -0700 +Subject: ANDROID: net: enable wireless core features with + GKI_LEGACY_WEXT_ALLCONFIG + +In embedded environments the requirements are to be able to pick and +chose which features one requires built into the kernel. If an +embedded environment wants to supports loading modules that have been +kbuilt out of tree, there is a need to enable hidden configurations +for legacy wireless core features to provide the API surface for +them to load. + +Introduce CONFIG_GKI_LEGACY_WEXT_ALLCONFIG to select all legacy wireless +extension core features by activating in turn all the associated +hidden configuration options, without having to specifically select +any wireless module(s). + +(rejected upstream commit url https://lkml.org/lkml/2019/9/6/878) +Signed-off-by: Mark Salyzyn +Bug: 140250271 +Change-Id: Ie40e656d87ce21ae82f04ffe8dae2f0efab88a2e +--- + init/Kconfig.gki | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/init/Kconfig.gki b/init/Kconfig.gki +index 5df8c67123ef..b2f3ecefd782 100644 +--- a/init/Kconfig.gki ++++ b/init/Kconfig.gki +@@ -34,6 +34,25 @@ config GKI_HIDDEN_GPIO_CONFIGS + These are normally selected implicitely when a module + that relies on it is configured. + ++# LEGACY_WEXT_ALLCONFIG Discussed upstream, soundly rejected as a unique ++# problem for GKI to solve. It should be noted that these extensions are ++# in-effect deprecated and generally unsupported and we should pressure ++# the SOC vendors to drop any modules that require these extensions. ++config GKI_LEGACY_WEXT_ALLCONFIG ++ bool "Hidden wireless extension configs needed for GKI" ++ select WIRELESS_EXT ++ select WEXT_CORE ++ select WEXT_PROC ++ select WEXT_SPY ++ select WEXT_PRIV ++ help ++ Dummy config option used to enable all the hidden legacy wireless ++ extensions to the core wireless network functionality used by ++ add-in modules. ++ ++ If you are not building a kernel to be used for a variety of ++ out-of-kernel built wireless modules, say N here. ++ + # Atrocities needed for + # a) building GKI modules in separate tree, or + # b) building drivers that are not modularizable +@@ -47,6 +66,7 @@ config GKI_HACKS_TO_FIX + select GKI_HIDDEN_REGMAP_CONFIGS + select GKI_HIDDEN_SND_SOC_CONFIGS + select GKI_HIDDEN_GPIO_CONFIGS ++ select GKI_LEGACY_WEXT_ALLCONFIG + help + Dummy config option used to enable core functionality used by + modules that may not be selectable in this config. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tab.patch b/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tab.patch new file mode 100644 index 000000000000..b3900a1ca9c1 --- /dev/null +++ b/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tab.patch @@ -0,0 +1,270 @@ +From 2b8c793a1eda6622bc4a56016e53d1cf9f28da94 Mon Sep 17 00:00:00 2001 +From: Lorenzo Colitti +Date: Wed, 26 Mar 2014 19:35:41 +0900 +Subject: ANDROID: net: ipv6: autoconf routes into per-device + tables + +Currently, IPv6 router discovery always puts routes into +RT6_TABLE_MAIN. This causes problems for connection managers +that want to support multiple simultaneous network connections +and want control over which one is used by default (e.g., wifi +and wired). + +To work around this connection managers typically take the routes +they prefer and copy them to static routes with low metrics in +the main table. This puts the burden on the connection manager +to watch netlink to see if the routes have changed, delete the +routes when their lifetime expires, etc. + +Instead, this patch adds a per-interface sysctl to have the +kernel put autoconf routes into different tables. This allows +each interface to have its own autoconf table, and choosing the +default interface (or using different interfaces at the same +time for different types of traffic) can be done using +appropriate ip rules. + +The sysctl behaves as follows: + +- = 0: default. Put routes into RT6_TABLE_MAIN as before. +- > 0: manual. Put routes into the specified table. +- < 0: automatic. Add the absolute value of the sysctl to the + device's ifindex, and use that table. + +The automatic mode is most useful in conjunction with +net.ipv6.conf.default.accept_ra_rt_table. A connection manager +or distribution could set it to, say, -100 on boot, and +thereafter just use IP rules. + +Signed-off-by: Lorenzo Colitti +[AmitP: Refactored original changes to align with + the changes introduced by upstream commits + 830218c1add1 ("net: ipv6: Fix processing of RAs in presence of VRF"), + 8d1c802b2815 ("net/ipv6: Flip FIB entries to fib6_info"). + + Also folded following android-4.9 commit changes into this patch + be65fb01da4d ("ANDROID: net: ipv6: remove unused variable ifindex in")] +Bug: 120445791 +Change-Id: I82d16e3737d9cdfa6489e649e247894d0d60cbb1 +Signed-off-by: Amit Pundir +--- + include/linux/ipv6.h | 1 + + include/net/addrconf.h | 12 ++++++++++ + net/ipv6/addrconf.c | 33 +++++++++++++++++++++++++-- + net/ipv6/route.c | 51 ++++++++++++------------------------------ + 4 files changed, 58 insertions(+), 39 deletions(-) + +diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h +index ea7c7906591eb..76cfef3d43f30 100644 +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -42,6 +42,7 @@ struct ipv6_devconf { + __s32 accept_ra_rt_info_max_plen; + #endif + #endif ++ __s32 accept_ra_rt_table; + __s32 proxy_ndp; + __s32 accept_source_route; + __s32 accept_ra_from_local; +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index 3f62b347b04a7..2306098a7f2d9 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -266,6 +266,18 @@ static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset) + void addrconf_prefix_rcv(struct net_device *dev, + u8 *opt, int len, bool sllao); + ++/* Determines into what table to put autoconf PIO/RIO/default routes ++ * learned on this device. ++ * ++ * - If 0, use the same table for every device. This puts routes into ++ * one of RT_TABLE_{PREFIX,INFO,DFLT} depending on the type of route ++ * (but note that these three are currently all equal to ++ * RT6_TABLE_MAIN). ++ * - If > 0, use the specified table. ++ * - If < 0, put routes into table dev->ifindex + (-rt_table). ++ */ ++u32 addrconf_rt_table(const struct net_device *dev, u32 default_table); ++ + /* + * anycast prototypes (anycast.c) + */ +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 6a576ff92c399..89c828c4d0279 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -217,6 +217,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { + .accept_ra_rt_info_max_plen = 0, + #endif + #endif ++ .accept_ra_rt_table = 0, + .proxy_ndp = 0, + .accept_source_route = 0, /* we do not accept RH0 by default. */ + .disable_ipv6 = 0, +@@ -271,6 +272,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { + .accept_ra_rt_info_max_plen = 0, + #endif + #endif ++ .accept_ra_rt_table = 0, + .proxy_ndp = 0, + .accept_source_route = 0, /* we do not accept RH0 by default. */ + .disable_ipv6 = 0, +@@ -2361,6 +2363,26 @@ static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpad + ipv6_regen_rndid(idev); + } + ++u32 addrconf_rt_table(const struct net_device *dev, u32 default_table) ++{ ++ struct inet6_dev *idev = in6_dev_get(dev); ++ int sysctl; ++ u32 table; ++ ++ if (!idev) ++ return default_table; ++ sysctl = idev->cnf.accept_ra_rt_table; ++ if (sysctl == 0) { ++ table = default_table; ++ } else if (sysctl > 0) { ++ table = (u32) sysctl; ++ } else { ++ table = (unsigned) dev->ifindex + (-sysctl); ++ } ++ in6_dev_put(idev); ++ return table; ++} ++ + /* + * Add prefix route. + */ +@@ -2371,7 +2393,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, u32 metric, + u32 flags, gfp_t gfp_flags) + { + struct fib6_config cfg = { +- .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX, ++ .fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_PREFIX), + .fc_metric = metric ? : IP6_RT_PRIO_ADDRCONF, + .fc_ifindex = dev->ifindex, + .fc_expires = expires, +@@ -2406,7 +2428,7 @@ static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, + struct fib6_node *fn; + struct fib6_info *rt = NULL; + struct fib6_table *table; +- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX; ++ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_PREFIX); + + table = fib6_get_table(dev_net(dev), tb_id); + if (!table) +@@ -6634,6 +6656,13 @@ static const struct ctl_table addrconf_sysctl[] = { + }, + #endif + #endif ++ { ++ .procname = "accept_ra_rt_table", ++ .data = &ipv6_devconf.accept_ra_rt_table, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, ++ }, + { + .procname = "proxy_ndp", + .data = &ipv6_devconf.proxy_ndp, +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 546088e508151..2fb2b913214ca 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -4081,7 +4081,7 @@ static struct fib6_info *rt6_get_route_info(struct net *net, + const struct in6_addr *gwaddr, + struct net_device *dev) + { +- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO; ++ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO); + int ifindex = dev->ifindex; + struct fib6_node *fn; + struct fib6_info *rt = NULL; +@@ -4135,7 +4135,7 @@ static struct fib6_info *rt6_add_route_info(struct net *net, + .fc_nlinfo.nl_net = net, + }; + +- cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO, ++ cfg.fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO), + cfg.fc_dst = *prefix; + cfg.fc_gateway = *gwaddr; + +@@ -4153,7 +4153,7 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, + const struct in6_addr *addr, + struct net_device *dev) + { +- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT; ++ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_DFLT); + struct fib6_info *rt; + struct fib6_table *table; + +@@ -4187,7 +4187,7 @@ struct fib6_info *rt6_add_dflt_router(struct net *net, + unsigned int pref) + { + struct fib6_config cfg = { +- .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT, ++ .fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_DFLT), + .fc_metric = IP6_RT_PRIO_USER, + .fc_ifindex = dev->ifindex, + .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | +@@ -4212,47 +4212,24 @@ struct fib6_info *rt6_add_dflt_router(struct net *net, + return rt6_get_dflt_router(net, gwaddr, dev); + } + +-static void __rt6_purge_dflt_routers(struct net *net, +- struct fib6_table *table) ++static int rt6_addrconf_purge(struct fib6_info *rt, void *arg) + { +- struct fib6_info *rt; +- +-restart: +- rcu_read_lock(); +- for_each_fib6_node_rt_rcu(&table->tb6_root) { +- struct net_device *dev = fib6_info_nh_dev(rt); +- struct inet6_dev *idev = dev ? __in6_dev_get(dev) : NULL; ++ struct net_device *dev = fib6_info_nh_dev(rt); ++ struct inet6_dev *idev = dev ? __in6_dev_get(dev) : NULL; + +- if (rt->fib6_flags & (RTF_DEFAULT | RTF_ADDRCONF) && +- (!idev || idev->cnf.accept_ra != 2) && +- fib6_info_hold_safe(rt)) { +- rcu_read_unlock(); +- ip6_del_rt(net, rt); +- goto restart; +- } ++ if (rt->fib6_flags & (RTF_DEFAULT | RTF_ADDRCONF) && ++ (!idev || idev->cnf.accept_ra != 2)) { ++ /* Delete this route. See fib6_clean_tree() */ ++ return -1; + } +- rcu_read_unlock(); + +- table->flags &= ~RT6_TABLE_HAS_DFLT_ROUTER; ++ /* Continue walking */ ++ return 0; + } + + void rt6_purge_dflt_routers(struct net *net) + { +- struct fib6_table *table; +- struct hlist_head *head; +- unsigned int h; +- +- rcu_read_lock(); +- +- for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { +- head = &net->ipv6.fib_table_hash[h]; +- hlist_for_each_entry_rcu(table, head, tb6_hlist) { +- if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER) +- __rt6_purge_dflt_routers(net, table); +- } +- } +- +- rcu_read_unlock(); ++ fib6_clean_all(net, rt6_addrconf_purge, NULL); + } + + static void rtmsg_to_fib6_config(struct net *net, +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-complian.patch b/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-complian.patch new file mode 100644 index 000000000000..9731a0c74551 --- /dev/null +++ b/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-complian.patch @@ -0,0 +1,41 @@ +From daa8921ccee73b35993b7cbc3a09d60878b49c1c Mon Sep 17 00:00:00 2001 +From: Lorenzo Colitti +Date: Wed, 10 May 2017 23:54:04 +0900 +Subject: ANDROID: net: xfrm: make PF_KEY SHA256 use + RFC-compliant truncation. + +When using the PF_KEY interface, SHA-256 hashes are hardcoded to +use 96-bit truncation. This is a violation of RFC4868, which +specifies 128-bit truncation, but will not be fixed upstream due +to backwards compatibility concerns and because the PF_KEY +interface is deprecated in favour of netlink XFRM (which allows +the app to specify an arbitrary truncation length). + +Change the hardcoded truncation length from 96 to 128 so that +PF_KEY apps such as racoon will work with standards-compliant VPN +servers. + +Bug: 34114242 +Bug: 120440497 +Change-Id: Ie46bff4b6358f18117d0be241171d677d31d33f7 +Signed-off-by: Lorenzo Colitti +--- + net/xfrm/xfrm_algo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c +index 32a378e7011ff..8b06ef53d7fcc 100644 +--- a/net/xfrm/xfrm_algo.c ++++ b/net/xfrm/xfrm_algo.c +@@ -237,7 +237,7 @@ static struct xfrm_algo_desc aalg_list[] = { + + .uinfo = { + .auth = { +- .icv_truncbits = 96, ++ .icv_truncbits = 128, + .icv_fullbits = 256, + } + }, +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-t.patch b/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-t.patch new file mode 100644 index 000000000000..25dbbcffcc13 --- /dev/null +++ b/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-t.patch @@ -0,0 +1,454 @@ +From 2d68a635f962a2de88a2d9584831489d61b64561 Mon Sep 17 00:00:00 2001 +From: JP Abgrall +Date: Thu, 26 Apr 2012 23:28:35 -0700 +Subject: ANDROID: netfilter: xt_IDLETIMER: Add new netlink msg + type + +Send notifications when the label becomes active after an idle period. +Send netlink message notifications in addition to sysfs notifications. +Using a uevent with + subsystem=xt_idletimer + INTERFACE=... + STATE={active,inactive} + +This is backport from common android-3.0 +commit: beb914e987cbbd368988d2b94a6661cb907c4d5a +with uevent support instead of a new netlink message type. + +Bug: 120445672 +Change-Id: I31677ef00c94b5f82c8457e5bf9e5e584c23c523 +Signed-off-by: Ashish Sharma +Signed-off-by: JP Abgrall +[astrachan: Folded the following changes into this patch: + ee0b238fada5 ("netfilter: xt_IDLETIMER: time-stamp and suspend/resume handling.") + 728c058a495e ("netfilter: xt_IDLETIMER: Adds the uid field in the msg") + 5ebea489d44c ("netfilter: xt_IDLETIMER: Fix use after free condition during work") + 5ab69d7ba2c5 ("netfilter: xt_IDLETIMER: Use fullsock when querying uid")] +Signed-off-by: Alistair Strachan +--- + include/uapi/linux/netfilter/xt_IDLETIMER.h | 8 + + net/netfilter/xt_IDLETIMER.c | 251 +++++++++++++++++++- + 2 files changed, 247 insertions(+), 12 deletions(-) + +diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h +index 3c586a19baeab..c82a1c1d53ec0 100644 +--- a/include/uapi/linux/netfilter/xt_IDLETIMER.h ++++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h +@@ -5,6 +5,7 @@ + * Header file for Xtables timer target module. + * + * Copyright (C) 2004, 2010 Nokia Corporation ++ * + * Written by Timo Teras + * + * Converted to x_tables and forward-ported to 2.6.34 +@@ -33,12 +34,19 @@ + #include + + #define MAX_IDLETIMER_LABEL_SIZE 28 ++#define NLMSG_MAX_SIZE 64 ++ ++#define NL_EVENT_TYPE_INACTIVE 0 ++#define NL_EVENT_TYPE_ACTIVE 1 + + struct idletimer_tg_info { + __u32 timeout; + + char label[MAX_IDLETIMER_LABEL_SIZE]; + ++ /* Use netlink messages for notification in addition to sysfs */ ++ __u8 send_nl_msg; ++ + /* for kernel module internal use only */ + struct idletimer_tg *timer __attribute__((aligned(8))); + }; +diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c +index 9cec9eae556a6..c25a2953c75cf 100644 +--- a/net/netfilter/xt_IDLETIMER.c ++++ b/net/netfilter/xt_IDLETIMER.c +@@ -6,6 +6,7 @@ + * After timer expires a kevent will be sent. + * + * Copyright (C) 2004, 2010 Nokia Corporation ++ * + * Written by Timo Teras + * + * Converted to x_tables and reworked for upstream inclusion +@@ -25,8 +26,17 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + struct idletimer_tg { + struct list_head entry; +@@ -36,14 +46,111 @@ struct idletimer_tg { + struct kobject *kobj; + struct device_attribute attr; + ++ struct timespec64 delayed_timer_trigger; ++ struct timespec64 last_modified_timer; ++ struct timespec64 last_suspend_time; ++ struct notifier_block pm_nb; ++ ++ int timeout; + unsigned int refcnt; ++ bool work_pending; ++ bool send_nl_msg; ++ bool active; ++ uid_t uid; + }; + + static LIST_HEAD(idletimer_tg_list); + static DEFINE_MUTEX(list_mutex); ++static DEFINE_SPINLOCK(timestamp_lock); + + static struct kobject *idletimer_tg_kobj; + ++static bool check_for_delayed_trigger(struct idletimer_tg *timer, ++ struct timespec64 *ts) ++{ ++ bool state; ++ struct timespec64 temp; ++ spin_lock_bh(×tamp_lock); ++ timer->work_pending = false; ++ if ((ts->tv_sec - timer->last_modified_timer.tv_sec) > timer->timeout || ++ timer->delayed_timer_trigger.tv_sec != 0) { ++ state = false; ++ temp.tv_sec = timer->timeout; ++ temp.tv_nsec = 0; ++ if (timer->delayed_timer_trigger.tv_sec != 0) { ++ temp = timespec64_add(timer->delayed_timer_trigger, ++ temp); ++ ts->tv_sec = temp.tv_sec; ++ ts->tv_nsec = temp.tv_nsec; ++ timer->delayed_timer_trigger.tv_sec = 0; ++ timer->work_pending = true; ++ schedule_work(&timer->work); ++ } else { ++ temp = timespec64_add(timer->last_modified_timer, temp); ++ ts->tv_sec = temp.tv_sec; ++ ts->tv_nsec = temp.tv_nsec; ++ } ++ } else { ++ state = timer->active; ++ } ++ spin_unlock_bh(×tamp_lock); ++ return state; ++} ++ ++static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer) ++{ ++ char iface_msg[NLMSG_MAX_SIZE]; ++ char state_msg[NLMSG_MAX_SIZE]; ++ char timestamp_msg[NLMSG_MAX_SIZE]; ++ char uid_msg[NLMSG_MAX_SIZE]; ++ char *envp[] = { iface_msg, state_msg, timestamp_msg, uid_msg, NULL }; ++ int res; ++ struct timespec64 ts; ++ uint64_t time_ns; ++ bool state; ++ ++ res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s", ++ iface); ++ if (NLMSG_MAX_SIZE <= res) { ++ pr_err("message too long (%d)", res); ++ return; ++ } ++ ++ ts = ktime_to_timespec64(ktime_get_boottime()); ++ state = check_for_delayed_trigger(timer, &ts); ++ res = snprintf(state_msg, NLMSG_MAX_SIZE, "STATE=%s", ++ state ? "active" : "inactive"); ++ ++ if (NLMSG_MAX_SIZE <= res) { ++ pr_err("message too long (%d)", res); ++ return; ++ } ++ ++ if (state) { ++ res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID=%u", timer->uid); ++ if (NLMSG_MAX_SIZE <= res) ++ pr_err("message too long (%d)", res); ++ } else { ++ res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID="); ++ if (NLMSG_MAX_SIZE <= res) ++ pr_err("message too long (%d)", res); ++ } ++ ++ time_ns = timespec64_to_ns(&ts); ++ res = snprintf(timestamp_msg, NLMSG_MAX_SIZE, "TIME_NS=%llu", time_ns); ++ if (NLMSG_MAX_SIZE <= res) { ++ timestamp_msg[0] = '\0'; ++ pr_err("message too long (%d)", res); ++ } ++ ++ pr_debug("putting nlmsg: <%s> <%s> <%s> <%s>\n", iface_msg, state_msg, ++ timestamp_msg, uid_msg); ++ kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp); ++ return; ++ ++ ++} ++ + static + struct idletimer_tg *__idletimer_tg_find_by_label(const char *label) + { +@@ -62,6 +169,7 @@ static ssize_t idletimer_tg_show(struct device *dev, + { + struct idletimer_tg *timer; + unsigned long expires = 0; ++ unsigned long now = jiffies; + + mutex_lock(&list_mutex); + +@@ -71,11 +179,15 @@ static ssize_t idletimer_tg_show(struct device *dev, + + mutex_unlock(&list_mutex); + +- if (time_after(expires, jiffies)) ++ if (time_after(expires, now)) + return sprintf(buf, "%u\n", +- jiffies_to_msecs(expires - jiffies) / 1000); ++ jiffies_to_msecs(expires - now) / 1000); + +- return sprintf(buf, "0\n"); ++ if (timer->send_nl_msg) ++ return sprintf(buf, "0 %d\n", ++ jiffies_to_msecs(now - expires) / 1000); ++ else ++ return sprintf(buf, "0\n"); + } + + static void idletimer_tg_work(struct work_struct *work) +@@ -84,6 +196,9 @@ static void idletimer_tg_work(struct work_struct *work) + work); + + sysfs_notify(idletimer_tg_kobj, NULL, timer->attr.attr.name); ++ ++ if (timer->send_nl_msg) ++ notify_netlink_uevent(timer->attr.attr.name, timer); + } + + static void idletimer_tg_expired(struct timer_list *t) +@@ -91,8 +206,56 @@ static void idletimer_tg_expired(struct timer_list *t) + struct idletimer_tg *timer = from_timer(timer, t, timer); + + pr_debug("timer %s expired\n", timer->attr.attr.name); +- ++ spin_lock_bh(×tamp_lock); ++ timer->active = false; ++ timer->work_pending = true; + schedule_work(&timer->work); ++ spin_unlock_bh(×tamp_lock); ++} ++ ++static int idletimer_resume(struct notifier_block *notifier, ++ unsigned long pm_event, void *unused) ++{ ++ struct timespec64 ts; ++ unsigned long time_diff, now = jiffies; ++ struct idletimer_tg *timer = container_of(notifier, ++ struct idletimer_tg, pm_nb); ++ if (!timer) ++ return NOTIFY_DONE; ++ switch (pm_event) { ++ case PM_SUSPEND_PREPARE: ++ timer->last_suspend_time = ++ ktime_to_timespec64(ktime_get_boottime()); ++ break; ++ case PM_POST_SUSPEND: ++ spin_lock_bh(×tamp_lock); ++ if (!timer->active) { ++ spin_unlock_bh(×tamp_lock); ++ break; ++ } ++ /* since jiffies are not updated when suspended now represents ++ * the time it would have suspended */ ++ if (time_after(timer->timer.expires, now)) { ++ ts = ktime_to_timespec64(ktime_get_boottime()); ++ ts = timespec64_sub(ts, timer->last_suspend_time); ++ time_diff = timespec64_to_jiffies(&ts); ++ if (timer->timer.expires > (time_diff + now)) { ++ mod_timer_pending(&timer->timer, ++ (timer->timer.expires - time_diff)); ++ } else { ++ del_timer(&timer->timer); ++ timer->timer.expires = 0; ++ timer->active = false; ++ timer->work_pending = true; ++ schedule_work(&timer->work); ++ } ++ } ++ spin_unlock_bh(×tamp_lock); ++ break; ++ default: ++ break; ++ } ++ return NOTIFY_DONE; + } + + static int idletimer_check_sysfs_name(const char *name, unsigned int size) +@@ -144,6 +307,22 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) + + timer_setup(&info->timer->timer, idletimer_tg_expired, 0); + info->timer->refcnt = 1; ++ info->timer->send_nl_msg = (info->send_nl_msg == 0) ? false : true; ++ info->timer->active = true; ++ info->timer->timeout = info->timeout; ++ ++ info->timer->delayed_timer_trigger.tv_sec = 0; ++ info->timer->delayed_timer_trigger.tv_nsec = 0; ++ info->timer->work_pending = false; ++ info->timer->uid = 0; ++ info->timer->last_modified_timer = ++ ktime_to_timespec64(ktime_get_boottime()); ++ ++ info->timer->pm_nb.notifier_call = idletimer_resume; ++ ret = register_pm_notifier(&info->timer->pm_nb); ++ if (ret) ++ printk(KERN_WARNING "[%s] Failed to register pm notifier %d\n", ++ __func__, ret); + + INIT_WORK(&info->timer->work, idletimer_tg_work); + +@@ -160,6 +339,42 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) + return ret; + } + ++static void reset_timer(const struct idletimer_tg_info *info, ++ struct sk_buff *skb) ++{ ++ unsigned long now = jiffies; ++ struct idletimer_tg *timer = info->timer; ++ bool timer_prev; ++ ++ spin_lock_bh(×tamp_lock); ++ timer_prev = timer->active; ++ timer->active = true; ++ /* timer_prev is used to guard overflow problem in time_before*/ ++ if (!timer_prev || time_before(timer->timer.expires, now)) { ++ pr_debug("Starting Checkentry timer (Expired, Jiffies): %lu, %lu\n", ++ timer->timer.expires, now); ++ ++ /* Stores the uid resposible for waking up the radio */ ++ if (skb && (skb->sk)) { ++ timer->uid = from_kuid_munged(current_user_ns(), ++ sock_i_uid(skb_to_full_sk(skb))); ++ } ++ ++ /* checks if there is a pending inactive notification*/ ++ if (timer->work_pending) ++ timer->delayed_timer_trigger = timer->last_modified_timer; ++ else { ++ timer->work_pending = true; ++ schedule_work(&timer->work); ++ } ++ } ++ ++ timer->last_modified_timer = ktime_to_timespec64(ktime_get_boottime()); ++ mod_timer(&timer->timer, ++ msecs_to_jiffies(info->timeout * 1000) + now); ++ spin_unlock_bh(×tamp_lock); ++} ++ + /* + * The actual xt_tables plugin. + */ +@@ -167,13 +382,23 @@ static unsigned int idletimer_tg_target(struct sk_buff *skb, + const struct xt_action_param *par) + { + const struct idletimer_tg_info *info = par->targinfo; ++ unsigned long now = jiffies; + + pr_debug("resetting timer %s, timeout period %u\n", + info->label, info->timeout); + +- mod_timer(&info->timer->timer, +- msecs_to_jiffies(info->timeout * 1000) + jiffies); ++ BUG_ON(!info->timer); ++ ++ info->timer->active = true; ++ ++ if (time_before(info->timer->timer.expires, now)) { ++ schedule_work(&info->timer->work); ++ pr_debug("Starting timer %s (Expired, Jiffies): %lu, %lu\n", ++ info->label, info->timer->timer.expires, now); ++ } + ++ /* TODO: Avoid modifying timers on each packet */ ++ reset_timer(info, skb); + return XT_CONTINUE; + } + +@@ -182,7 +407,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) + struct idletimer_tg_info *info = par->targinfo; + int ret; + +- pr_debug("checkentry targinfo%s\n", info->label); ++ pr_debug("checkentry targinfo %s\n", info->label); + + if (info->timeout == 0) { + pr_debug("timeout value is zero\n"); +@@ -204,9 +429,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) + info->timer = __idletimer_tg_find_by_label(info->label); + if (info->timer) { + info->timer->refcnt++; +- mod_timer(&info->timer->timer, +- msecs_to_jiffies(info->timeout * 1000) + jiffies); +- ++ reset_timer(info, NULL); + pr_debug("increased refcnt of timer %s to %u\n", + info->label, info->timer->refcnt); + } else { +@@ -219,6 +442,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) + } + + mutex_unlock(&list_mutex); ++ + return 0; + } + +@@ -235,13 +459,14 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) + + list_del(&info->timer->entry); + del_timer_sync(&info->timer->timer); +- cancel_work_sync(&info->timer->work); + sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); ++ unregister_pm_notifier(&info->timer->pm_nb); ++ cancel_work_sync(&info->timer->work); + kfree(info->timer->attr.attr.name); + kfree(info->timer); + } else { + pr_debug("decreased refcnt of timer %s to %u\n", +- info->label, info->timer->refcnt); ++ info->label, info->timer->refcnt); + } + + mutex_unlock(&list_mutex); +@@ -249,6 +474,7 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) + + static struct xt_target idletimer_tg __read_mostly = { + .name = "IDLETIMER", ++ .revision = 1, + .family = NFPROTO_UNSPEC, + .target = idletimer_tg_target, + .targetsize = sizeof(struct idletimer_tg_info), +@@ -315,3 +541,4 @@ MODULE_DESCRIPTION("Xtables: idle time monitor"); + MODULE_LICENSE("GPL v2"); + MODULE_ALIAS("ipt_IDLETIMER"); + MODULE_ALIAS("ip6t_IDLETIMER"); ++MODULE_ALIAS("arpt_IDLETIMER"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quot.patch b/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quot.patch new file mode 100644 index 000000000000..00376f08f8ea --- /dev/null +++ b/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quot.patch @@ -0,0 +1,518 @@ +From d4048cc3980014dc9411bf762ae4aa154018fd22 Mon Sep 17 00:00:00 2001 +From: JP Abgrall +Date: Tue, 21 Jun 2011 11:14:49 -0700 +Subject: ANDROID: netfilter: xt_quota2: adding the original + quota2 from xtables-addons + +The original xt_quota in the kernel is plain broken: + - counts quota at a per CPU level + (was written back when ubiquitous SMP was just a dream) + - provides no way to count across IPV4/IPV6. + +This patch is the original unaltered code from: + http://sourceforge.net/projects/xtables-addons + + at commit e84391ce665cef046967f796dd91026851d6bbf3 + +Bug: 120445421 +Change-Id: I19d49858840effee9ecf6cff03c23b45a97efdeb +Signed-off-by: JP Abgrall +[astrachan: Folded 4d33aa305871 ("netfilter: xt_quota2: fixup the quota2, + and enable.") into this patch] +Signed-off-by: Alistair Strachan +--- + include/linux/netfilter/xt_quota2.h | 25 ++ + net/netfilter/Kconfig | 23 ++ + net/netfilter/Makefile | 1 + + net/netfilter/xt_quota2.c | 401 ++++++++++++++++++++++++++++ + 4 files changed, 450 insertions(+) + create mode 100644 include/linux/netfilter/xt_quota2.h + create mode 100644 net/netfilter/xt_quota2.c + +diff --git a/include/linux/netfilter/xt_quota2.h b/include/linux/netfilter/xt_quota2.h +new file mode 100644 +index 0000000000000..eadc6903314e7 +--- /dev/null ++++ b/include/linux/netfilter/xt_quota2.h +@@ -0,0 +1,25 @@ ++#ifndef _XT_QUOTA_H ++#define _XT_QUOTA_H ++ ++enum xt_quota_flags { ++ XT_QUOTA_INVERT = 1 << 0, ++ XT_QUOTA_GROW = 1 << 1, ++ XT_QUOTA_PACKET = 1 << 2, ++ XT_QUOTA_NO_CHANGE = 1 << 3, ++ XT_QUOTA_MASK = 0x0F, ++}; ++ ++struct xt_quota_counter; ++ ++struct xt_quota_mtinfo2 { ++ char name[15]; ++ u_int8_t flags; ++ ++ /* Comparison-invariant */ ++ aligned_u64 quota; ++ ++ /* Used internally by the kernel */ ++ struct xt_quota_counter *master __attribute__((aligned(8))); ++}; ++ ++#endif /* _XT_QUOTA_H */ +diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig +index 0d65f4d394943..ce30e128f0daa 100644 +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -1484,6 +1484,29 @@ config NETFILTER_XT_MATCH_QUOTA + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + ++config NETFILTER_XT_MATCH_QUOTA2 ++ tristate '"quota2" match support' ++ depends on NETFILTER_ADVANCED ++ help ++ This option adds a `quota2' match, which allows to match on a ++ byte counter correctly and not per CPU. ++ It allows naming the quotas. ++ This is based on http://xtables-addons.git.sourceforge.net ++ ++ If you want to compile it as a module, say M here and read ++ . If unsure, say `N'. ++ ++config NETFILTER_XT_MATCH_QUOTA2_LOG ++ bool '"quota2" Netfilter LOG support' ++ depends on NETFILTER_XT_MATCH_QUOTA2 ++ default n ++ help ++ This option allows `quota2' to log ONCE when a quota limit ++ is passed. It logs via NETLINK using the NETLINK_NFLOG family. ++ It logs similarly to how ipt_ULOG would without data. ++ ++ If unsure, say `N'. ++ + config NETFILTER_XT_MATCH_RATEEST + tristate '"rateest" match support' + depends on NETFILTER_ADVANCED +diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile +index 9270a7fae4844..112b6416f0699 100644 +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -192,6 +192,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o + obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o + obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o + obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o ++obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA2) += xt_quota2.o + obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o + obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o + obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o +diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c +new file mode 100644 +index 0000000000000..24b774263aa6a +--- /dev/null ++++ b/net/netfilter/xt_quota2.c +@@ -0,0 +1,401 @@ ++/* ++ * xt_quota2 - enhanced xt_quota that can count upwards and in packets ++ * as a minimal accounting match. ++ * by Jan Engelhardt , 2008 ++ * ++ * Originally based on xt_quota.c: ++ * netfilter module to enforce network quotas ++ * Sam Johnston ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License; either ++ * version 2 of the License, as published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG ++/* For compatibility, these definitions are copied from the ++ * deprecated header file */ ++#define ULOG_MAC_LEN 80 ++#define ULOG_PREFIX_LEN 32 ++ ++/* Format of the ULOG packets passed through netlink */ ++typedef struct ulog_packet_msg { ++ unsigned long mark; ++ long timestamp_sec; ++ long timestamp_usec; ++ unsigned int hook; ++ char indev_name[IFNAMSIZ]; ++ char outdev_name[IFNAMSIZ]; ++ size_t data_len; ++ char prefix[ULOG_PREFIX_LEN]; ++ unsigned char mac_len; ++ unsigned char mac[ULOG_MAC_LEN]; ++ unsigned char payload[0]; ++} ulog_packet_msg_t; ++#endif ++ ++/** ++ * @lock: lock to protect quota writers from each other ++ */ ++struct xt_quota_counter { ++ u_int64_t quota; ++ spinlock_t lock; ++ struct list_head list; ++ atomic_t ref; ++ char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)]; ++ struct proc_dir_entry *procfs_entry; ++}; ++ ++#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG ++/* Harald's favorite number +1 :D From ipt_ULOG.C */ ++static int qlog_nl_event = 112; ++module_param_named(event_num, qlog_nl_event, uint, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(event_num, ++ "Event number for NETLINK_NFLOG message. 0 disables log." ++ "111 is what ipt_ULOG uses."); ++static struct sock *nflognl; ++#endif ++ ++static LIST_HEAD(counter_list); ++static DEFINE_SPINLOCK(counter_list_lock); ++ ++static struct proc_dir_entry *proc_xt_quota; ++static unsigned int quota_list_perms = S_IRUGO | S_IWUSR; ++static kuid_t quota_list_uid = KUIDT_INIT(0); ++static kgid_t quota_list_gid = KGIDT_INIT(0); ++module_param_named(perms, quota_list_perms, uint, S_IRUGO | S_IWUSR); ++ ++#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG ++static void quota2_log(unsigned int hooknum, ++ const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const char *prefix) ++{ ++ ulog_packet_msg_t *pm; ++ struct sk_buff *log_skb; ++ size_t size; ++ struct nlmsghdr *nlh; ++ ++ if (!qlog_nl_event) ++ return; ++ ++ size = NLMSG_SPACE(sizeof(*pm)); ++ size = max(size, (size_t)NLMSG_GOODSIZE); ++ log_skb = alloc_skb(size, GFP_ATOMIC); ++ if (!log_skb) { ++ pr_err("xt_quota2: cannot alloc skb for logging\n"); ++ return; ++ } ++ ++ nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, qlog_nl_event, ++ sizeof(*pm), 0); ++ if (!nlh) { ++ pr_err("xt_quota2: nlmsg_put failed\n"); ++ kfree_skb(log_skb); ++ return; ++ } ++ pm = nlmsg_data(nlh); ++ if (skb->tstamp == 0) ++ __net_timestamp((struct sk_buff *)skb); ++ pm->data_len = 0; ++ pm->hook = hooknum; ++ if (prefix != NULL) ++ strlcpy(pm->prefix, prefix, sizeof(pm->prefix)); ++ else ++ *(pm->prefix) = '\0'; ++ if (in) ++ strlcpy(pm->indev_name, in->name, sizeof(pm->indev_name)); ++ else ++ pm->indev_name[0] = '\0'; ++ ++ if (out) ++ strlcpy(pm->outdev_name, out->name, sizeof(pm->outdev_name)); ++ else ++ pm->outdev_name[0] = '\0'; ++ ++ NETLINK_CB(log_skb).dst_group = 1; ++ pr_debug("throwing 1 packets to netlink group 1\n"); ++ netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC); ++} ++#else ++static void quota2_log(unsigned int hooknum, ++ const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const char *prefix) ++{ ++} ++#endif /* if+else CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG */ ++ ++static ssize_t quota_proc_read(struct file *file, char __user *buf, ++ size_t size, loff_t *ppos) ++{ ++ struct xt_quota_counter *e = PDE_DATA(file_inode(file)); ++ char tmp[24]; ++ size_t tmp_size; ++ ++ spin_lock_bh(&e->lock); ++ tmp_size = scnprintf(tmp, sizeof(tmp), "%llu\n", e->quota); ++ spin_unlock_bh(&e->lock); ++ return simple_read_from_buffer(buf, size, ppos, tmp, tmp_size); ++} ++ ++static ssize_t quota_proc_write(struct file *file, const char __user *input, ++ size_t size, loff_t *ppos) ++{ ++ struct xt_quota_counter *e = PDE_DATA(file_inode(file)); ++ char buf[sizeof("18446744073709551616")]; ++ ++ if (size > sizeof(buf)) ++ size = sizeof(buf); ++ if (copy_from_user(buf, input, size) != 0) ++ return -EFAULT; ++ buf[sizeof(buf)-1] = '\0'; ++ ++ spin_lock_bh(&e->lock); ++ e->quota = simple_strtoull(buf, NULL, 0); ++ spin_unlock_bh(&e->lock); ++ return size; ++} ++ ++static const struct file_operations q2_counter_fops = { ++ .read = quota_proc_read, ++ .write = quota_proc_write, ++ .llseek = default_llseek, ++}; ++ ++static struct xt_quota_counter * ++q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon) ++{ ++ struct xt_quota_counter *e; ++ unsigned int size; ++ ++ /* Do not need all the procfs things for anonymous counters. */ ++ size = anon ? offsetof(typeof(*e), list) : sizeof(*e); ++ e = kmalloc(size, GFP_KERNEL); ++ if (e == NULL) ++ return NULL; ++ ++ e->quota = q->quota; ++ spin_lock_init(&e->lock); ++ if (!anon) { ++ INIT_LIST_HEAD(&e->list); ++ atomic_set(&e->ref, 1); ++ strlcpy(e->name, q->name, sizeof(e->name)); ++ } ++ return e; ++} ++ ++/** ++ * q2_get_counter - get ref to counter or create new ++ * @name: name of counter ++ */ ++static struct xt_quota_counter * ++q2_get_counter(const struct xt_quota_mtinfo2 *q) ++{ ++ struct proc_dir_entry *p; ++ struct xt_quota_counter *e = NULL; ++ struct xt_quota_counter *new_e; ++ ++ if (*q->name == '\0') ++ return q2_new_counter(q, true); ++ ++ /* No need to hold a lock while getting a new counter */ ++ new_e = q2_new_counter(q, false); ++ if (new_e == NULL) ++ goto out; ++ ++ spin_lock_bh(&counter_list_lock); ++ list_for_each_entry(e, &counter_list, list) ++ if (strcmp(e->name, q->name) == 0) { ++ atomic_inc(&e->ref); ++ spin_unlock_bh(&counter_list_lock); ++ kfree(new_e); ++ pr_debug("xt_quota2: old counter name=%s", e->name); ++ return e; ++ } ++ e = new_e; ++ pr_debug("xt_quota2: new_counter name=%s", e->name); ++ list_add_tail(&e->list, &counter_list); ++ /* The entry having a refcount of 1 is not directly destructible. ++ * This func has not yet returned the new entry, thus iptables ++ * has not references for destroying this entry. ++ * For another rule to try to destroy it, it would 1st need for this ++ * func* to be re-invoked, acquire a new ref for the same named quota. ++ * Nobody will access the e->procfs_entry either. ++ * So release the lock. */ ++ spin_unlock_bh(&counter_list_lock); ++ ++ /* create_proc_entry() is not spin_lock happy */ ++ p = e->procfs_entry = proc_create_data(e->name, quota_list_perms, ++ proc_xt_quota, &q2_counter_fops, e); ++ ++ if (IS_ERR_OR_NULL(p)) { ++ spin_lock_bh(&counter_list_lock); ++ list_del(&e->list); ++ spin_unlock_bh(&counter_list_lock); ++ goto out; ++ } ++ proc_set_user(p, quota_list_uid, quota_list_gid); ++ return e; ++ ++ out: ++ kfree(e); ++ return NULL; ++} ++ ++static int quota_mt2_check(const struct xt_mtchk_param *par) ++{ ++ struct xt_quota_mtinfo2 *q = par->matchinfo; ++ ++ pr_debug("xt_quota2: check() flags=0x%04x", q->flags); ++ ++ if (q->flags & ~XT_QUOTA_MASK) ++ return -EINVAL; ++ ++ q->name[sizeof(q->name)-1] = '\0'; ++ if (*q->name == '.' || strchr(q->name, '/') != NULL) { ++ printk(KERN_ERR "xt_quota.3: illegal name\n"); ++ return -EINVAL; ++ } ++ ++ q->master = q2_get_counter(q); ++ if (q->master == NULL) { ++ printk(KERN_ERR "xt_quota.3: memory alloc failure\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static void quota_mt2_destroy(const struct xt_mtdtor_param *par) ++{ ++ struct xt_quota_mtinfo2 *q = par->matchinfo; ++ struct xt_quota_counter *e = q->master; ++ ++ if (*q->name == '\0') { ++ kfree(e); ++ return; ++ } ++ ++ spin_lock_bh(&counter_list_lock); ++ if (!atomic_dec_and_test(&e->ref)) { ++ spin_unlock_bh(&counter_list_lock); ++ return; ++ } ++ ++ list_del(&e->list); ++ remove_proc_entry(e->name, proc_xt_quota); ++ spin_unlock_bh(&counter_list_lock); ++ kfree(e); ++} ++ ++static bool ++quota_mt2(const struct sk_buff *skb, struct xt_action_param *par) ++{ ++ struct xt_quota_mtinfo2 *q = (void *)par->matchinfo; ++ struct xt_quota_counter *e = q->master; ++ bool ret = q->flags & XT_QUOTA_INVERT; ++ ++ spin_lock_bh(&e->lock); ++ if (q->flags & XT_QUOTA_GROW) { ++ /* ++ * While no_change is pointless in "grow" mode, we will ++ * implement it here simply to have a consistent behavior. ++ */ ++ if (!(q->flags & XT_QUOTA_NO_CHANGE)) { ++ e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; ++ } ++ ret = true; ++ } else { ++ if (e->quota >= skb->len) { ++ if (!(q->flags & XT_QUOTA_NO_CHANGE)) ++ e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; ++ ret = !ret; ++ } else { ++ /* We are transitioning, log that fact. */ ++ if (e->quota) { ++ quota2_log(xt_hooknum(par), ++ skb, ++ xt_in(par), ++ xt_out(par), ++ q->name); ++ } ++ /* we do not allow even small packets from now on */ ++ e->quota = 0; ++ } ++ } ++ spin_unlock_bh(&e->lock); ++ return ret; ++} ++ ++static struct xt_match quota_mt2_reg[] __read_mostly = { ++ { ++ .name = "quota2", ++ .revision = 3, ++ .family = NFPROTO_IPV4, ++ .checkentry = quota_mt2_check, ++ .match = quota_mt2, ++ .destroy = quota_mt2_destroy, ++ .matchsize = sizeof(struct xt_quota_mtinfo2), ++ .me = THIS_MODULE, ++ }, ++ { ++ .name = "quota2", ++ .revision = 3, ++ .family = NFPROTO_IPV6, ++ .checkentry = quota_mt2_check, ++ .match = quota_mt2, ++ .destroy = quota_mt2_destroy, ++ .matchsize = sizeof(struct xt_quota_mtinfo2), ++ .me = THIS_MODULE, ++ }, ++}; ++ ++static int __init quota_mt2_init(void) ++{ ++ int ret; ++ pr_debug("xt_quota2: init()"); ++ ++#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG ++ nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, NULL); ++ if (!nflognl) ++ return -ENOMEM; ++#endif ++ ++ proc_xt_quota = proc_mkdir("xt_quota", init_net.proc_net); ++ if (proc_xt_quota == NULL) ++ return -EACCES; ++ ++ ret = xt_register_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg)); ++ if (ret < 0) ++ remove_proc_entry("xt_quota", init_net.proc_net); ++ pr_debug("xt_quota2: init() %d", ret); ++ return ret; ++} ++ ++static void __exit quota_mt2_exit(void) ++{ ++ xt_unregister_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg)); ++ remove_proc_entry("xt_quota", init_net.proc_net); ++} ++ ++module_init(quota_mt2_init); ++module_exit(quota_mt2_exit); ++MODULE_DESCRIPTION("Xtables: countdown quota match; up counter"); ++MODULE_AUTHOR("Sam Johnston "); ++MODULE_AUTHOR("Jan Engelhardt "); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ipt_quota2"); ++MODULE_ALIAS("ip6t_quota2"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-opti.patch b/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-opti.patch new file mode 100644 index 000000000000..a3b39a9e4dbb --- /dev/null +++ b/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-opti.patch @@ -0,0 +1,180 @@ +From 33e54476c27f7f9691cb7e08f07181329ad31abe Mon Sep 17 00:00:00 2001 +From: Doug Anderson +Date: Thu, 2 Feb 2012 22:58:28 -0800 +Subject: ANDROID: of: Support CONFIG_CMDLINE_EXTEND config + option + +The old logic assumes CMDLINE_FROM_BOOTLOADER vs. CMDLINE_FORCE and +ignores CMDLINE_EXTEND. Here's the old logic: + +- CONFIG_CMDLINE_FORCE=true + CONFIG_CMDLINE +- dt bootargs=non-empty: + dt bootargs +- dt bootargs=empty, @data is non-empty string + @data is left unchanged +- dt bootargs=empty, @data is empty string + CONFIG_CMDLINE (or "" if that's not defined) + +The new logic is now documented in of_fdt.h and is copied here for +reference: + +- CONFIG_CMDLINE_FORCE=true + CONFIG_CMDLINE +- CONFIG_CMDLINE_EXTEND=true, @data is non-empty string + @data + dt bootargs (even if dt bootargs are empty) +- CONFIG_CMDLINE_EXTEND=true, @data is empty string + CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) +- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: + dt bootargs +- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string + @data is left unchanged +- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string + CONFIG_CMDLINE (or "" if that's not defined) + +Signed-off-by: Doug Anderson +CC: devicetree-discuss@lists.ozlabs.org +CC: Grant Likely +CC: Benjamin Herrenschmidt +CC: Rob Herring +Bug: 120440972 +Change-Id: I40ace250847f813358125dfcaa8998fd32cf7ea3 +Signed-off-by: Colin Cross +[AmitP: Folded following android-4.9 commit changes into this patch + e820270abb5d ("ANDROID: of: fix CONFIG_CMDLINE_EXTEND") + 9a4a74055444 ("ANDROID: of: Fix build warnings")] +Signed-off-by: Amit Pundir +--- + drivers/of/fdt.c | 74 ++++++++++++++++++++++++++++-------------- + include/linux/of_fdt.h | 21 ++++++++++++ + 2 files changed, 70 insertions(+), 25 deletions(-) + +Index: common/drivers/of/fdt.c +=================================================================== +--- common.orig/drivers/of/fdt.c ++++ common/drivers/of/fdt.c +@@ -1040,43 +1040,67 @@ int __init early_init_dt_scan_memory(uns + return 0; + } + ++/* ++ * Convert configs to something easy to use in C code ++ */ ++#if defined(CONFIG_CMDLINE_FORCE) ++static const int overwrite_incoming_cmdline = 1; ++static const int read_dt_cmdline; ++static const int concat_cmdline; ++#elif defined(CONFIG_CMDLINE_EXTEND) ++static const int overwrite_incoming_cmdline; ++static const int read_dt_cmdline = 1; ++static const int concat_cmdline = 1; ++#else /* CMDLINE_FROM_BOOTLOADER */ ++static const int overwrite_incoming_cmdline; ++static const int read_dt_cmdline = 1; ++static const int concat_cmdline; ++#endif ++ ++#ifdef CONFIG_CMDLINE ++static const char *config_cmdline = CONFIG_CMDLINE; ++#else ++static const char *config_cmdline = ""; ++#endif ++ + int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, + int depth, void *data) + { +- int l; +- const char *p; ++ int l = 0; ++ const char *p = NULL; + const void *rng_seed; ++ char *cmdline = data; + + pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + +- if (depth != 1 || !data || ++ if (depth != 1 || !cmdline || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) + return 0; + + early_init_dt_check_for_initrd(node); + +- /* Retrieve command line */ +- p = of_get_flat_dt_prop(node, "bootargs", &l); +- if (p != NULL && l > 0) +- strlcpy(data, p, min(l, COMMAND_LINE_SIZE)); +- +- /* +- * CONFIG_CMDLINE is meant to be a default in case nothing else +- * managed to set the command line, unless CONFIG_CMDLINE_FORCE +- * is set in which case we override whatever was found earlier. +- */ +-#ifdef CONFIG_CMDLINE +-#if defined(CONFIG_CMDLINE_EXTEND) +- strlcat(data, " ", COMMAND_LINE_SIZE); +- strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +-#elif defined(CONFIG_CMDLINE_FORCE) +- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +-#else +- /* No arguments from boot loader, use kernel's cmdl*/ +- if (!((char *)data)[0]) +- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +-#endif +-#endif /* CONFIG_CMDLINE */ ++ /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */ ++ if (overwrite_incoming_cmdline || !cmdline[0]) ++ strlcpy(cmdline, config_cmdline, COMMAND_LINE_SIZE); ++ ++ /* Retrieve command line unless forcing */ ++ if (read_dt_cmdline) ++ p = of_get_flat_dt_prop(node, "bootargs", &l); ++ ++ if (p != NULL && l > 0) { ++ if (concat_cmdline) { ++ int cmdline_len; ++ int copy_len; ++ strlcat(cmdline, " ", COMMAND_LINE_SIZE); ++ cmdline_len = strlen(cmdline); ++ copy_len = COMMAND_LINE_SIZE - cmdline_len - 1; ++ copy_len = min((int)l, copy_len); ++ strncpy(cmdline + cmdline_len, p, copy_len); ++ cmdline[cmdline_len + copy_len] = '\0'; ++ } else { ++ strlcpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); ++ } ++ } + + pr_debug("Command line is: %s\n", (char*)data); + +Index: common/include/linux/of_fdt.h +=================================================================== +--- common.orig/include/linux/of_fdt.h ++++ common/include/linux/of_fdt.h +@@ -58,6 +58,27 @@ extern int of_flat_dt_is_compatible(unsi + extern unsigned long of_get_flat_dt_root(void); + extern uint32_t of_get_flat_dt_phandle(unsigned long node); + ++/* ++ * early_init_dt_scan_chosen - scan the device tree for ramdisk and bootargs ++ * ++ * The boot arguments will be placed into the memory pointed to by @data. ++ * That memory should be COMMAND_LINE_SIZE big and initialized to be a valid ++ * (possibly empty) string. Logic for what will be in @data after this ++ * function finishes: ++ * ++ * - CONFIG_CMDLINE_FORCE=true ++ * CONFIG_CMDLINE ++ * - CONFIG_CMDLINE_EXTEND=true, @data is non-empty string ++ * @data + dt bootargs (even if dt bootargs are empty) ++ * - CONFIG_CMDLINE_EXTEND=true, @data is empty string ++ * CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) ++ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: ++ * dt bootargs ++ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string ++ * @data is left unchanged ++ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string ++ * CONFIG_CMDLINE (or "" if that's not defined) ++ */ + extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, + int depth, void *data); + extern int early_init_dt_scan_memory(unsigned long node, const char *uname, diff --git a/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup.patch b/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup.patch new file mode 100644 index 000000000000..2b97c137b46d --- /dev/null +++ b/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup.patch @@ -0,0 +1,588 @@ +From 14114330161e3edb4aec1c881446ca71444f2647 Mon Sep 17 00:00:00 2001 +From: Ruchi Kandoi +Date: Wed, 19 Feb 2014 15:30:47 -0800 +Subject: ANDROID: power: wakeup_reason: add an API to log + wakeup reasons + +Add API log_wakeup_reason() and expose it to userspace via sysfs path +/sys/kernel/wakeup_reasons/last_resume_reason + +Bug: 120445600 +Signed-off-by: Ruchi Kandoi +[AmitP: Folded following android-4.9 commit changes into this patch + 1135122a192a ("ANDROID: POWER: fix compile warnings in log_wakeup_reason") + b4e6247778b0 ("ANDROID: Power: Changes the permission to read only for sysfs file /sys/kernel/wakeup_reasons/last_resume_reason") + e13dbc7c69cd ("ANDROID: power: wakeup_reason: rename irq_count to irqcount")] +Signed-off-by: Amit Pundir +[astrachan: Folded the following changes into this patch: + 39d7c7fe91c0 ("ANDROID: power: wakeup_reason: Add guard condition for maximum wakeup reasons") + 0730434bdf49 ("ANDROID: power: wakeup_reason: Avoids bogus error messages for the suspend aborts.") + 4e42dceae54e ("ANDROID: power: wakeup_reason: Adds functionality to log the last suspend abort reason.") + f21313b70ac7 ("ANDROID: power: wakeup_reason: Report suspend times from last_suspend_time") + f97ec34442ac ("ANDROID: power: wakeup_reason: fix suspend time reporting") + cd92df73e504 ("ANDROID: power: wakeup: Add last wake up source logging for suspend abort reason.") + 546b6ae3c087 ("ANDROID: power: wakeup: Add the guard condition for len in pm_get_active_wakeup_sources") + 1453d9ffcdbe ("ANDROID: power: wakeup_reason: make logging work in an interrupt context.")] +Change-Id: I81addaf420f1338255c5d0638b0d244a99d777d1 +Signed-off-by: Alistair Strachan +--- + .../ABI/testing/sysfs-kernel-wakeup_reasons | 16 ++ + drivers/base/power/main.c | 5 + + drivers/base/power/wakeup.c | 32 +++ + drivers/base/syscore.c | 5 +- + include/linux/suspend.h | 1 + + include/linux/wakeup_reason.h | 30 +++ + kernel/power/Makefile | 1 + + kernel/power/process.c | 22 +- + kernel/power/suspend.c | 20 +- + kernel/power/wakeup_reason.c | 215 ++++++++++++++++++ + 10 files changed, 339 insertions(+), 8 deletions(-) + create mode 100644 Documentation/ABI/testing/sysfs-kernel-wakeup_reasons + create mode 100644 include/linux/wakeup_reason.h + create mode 100644 kernel/power/wakeup_reason.c + +diff --git a/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons b/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons +new file mode 100644 +index 0000000000000..acb19b91c192b +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons +@@ -0,0 +1,16 @@ ++What: /sys/kernel/wakeup_reasons/last_resume_reason ++Date: February 2014 ++Contact: Ruchi Kandoi ++Description: ++ The /sys/kernel/wakeup_reasons/last_resume_reason is ++ used to report wakeup reasons after system exited suspend. ++ ++What: /sys/kernel/wakeup_reasons/last_suspend_time ++Date: March 2015 ++Contact: jinqian ++Description: ++ The /sys/kernel/wakeup_reasons/last_suspend_time is ++ used to report time spent in last suspend cycle. It contains ++ two numbers (in seconds) separated by space. First number is ++ the time spent in suspend and resume processes. Second number ++ is the time spent in sleep state. +\ No newline at end of file +diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c +index 7fb2c39bc7254..11d2eae19b07b 100644 +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "../base.h" + #include "power.h" +@@ -1694,6 +1695,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) + pm_callback_t callback = NULL; + const char *info = NULL; + int error = 0; ++ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; + DECLARE_DPM_WATCHDOG_ON_STACK(wd); + + TRACE_DEVICE(dev); +@@ -1717,6 +1719,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) + + if (pm_wakeup_pending()) { + dev->power.direct_complete = false; ++ pm_get_active_wakeup_sources(suspend_abort, ++ MAX_SUSPEND_ABORT_LEN); ++ log_suspend_abort_reason(suspend_abort); + async_error = -EBUSY; + goto Complete; + } +diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c +index ee31d4f8d856e..bfcdf5f195703 100644 +--- a/drivers/base/power/wakeup.c ++++ b/drivers/base/power/wakeup.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #include "power.h" +@@ -793,6 +794,37 @@ void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard) + } + EXPORT_SYMBOL_GPL(pm_wakeup_dev_event); + ++void pm_get_active_wakeup_sources(char *pending_wakeup_source, size_t max) ++{ ++ struct wakeup_source *ws, *last_active_ws = NULL; ++ int len = 0; ++ bool active = false; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(ws, &wakeup_sources, entry) { ++ if (ws->active && len < max) { ++ if (!active) ++ len += scnprintf(pending_wakeup_source, max, ++ "Pending Wakeup Sources: "); ++ len += scnprintf(pending_wakeup_source + len, max - len, ++ "%s ", ws->name); ++ active = true; ++ } else if (!active && ++ (!last_active_ws || ++ ktime_to_ns(ws->last_time) > ++ ktime_to_ns(last_active_ws->last_time))) { ++ last_active_ws = ws; ++ } ++ } ++ if (!active && last_active_ws) { ++ scnprintf(pending_wakeup_source, max, ++ "Last active Wakeup Source: %s", ++ last_active_ws->name); ++ } ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(pm_get_active_wakeup_sources); ++ + void pm_print_active_wakeup_sources(void) + { + struct wakeup_source *ws; +diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c +index 0d346a3071408..f3ca20cc817ba 100644 +--- a/drivers/base/syscore.c ++++ b/drivers/base/syscore.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + static LIST_HEAD(syscore_ops_list); + static DEFINE_MUTEX(syscore_ops_lock); +@@ -74,7 +75,9 @@ int syscore_suspend(void) + return 0; + + err_out: +- pr_err("PM: System core suspend callback %pS failed.\n", ops->suspend); ++ log_suspend_abort_reason("System core suspend callback %pS failed", ++ ops->suspend); ++ pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend); + + list_for_each_entry_continue(ops, &syscore_ops_list, node) + if (ops->resume) +diff --git a/include/linux/suspend.h b/include/linux/suspend.h +index 9c0ad1a3a7271..1c8f1703a155a 100644 +--- a/include/linux/suspend.h ++++ b/include/linux/suspend.h +@@ -501,6 +501,7 @@ extern bool pm_get_wakeup_count(unsigned int *count, bool block); + extern bool pm_save_wakeup_count(unsigned int count); + extern void pm_wakep_autosleep_enabled(bool set); + extern void pm_print_active_wakeup_sources(void); ++extern void pm_get_active_wakeup_sources(char *pending_sources, size_t max); + + extern void lock_system_sleep(void); + extern void unlock_system_sleep(void); +diff --git a/include/linux/wakeup_reason.h b/include/linux/wakeup_reason.h +new file mode 100644 +index 0000000000000..9fbe209c71779 +--- /dev/null ++++ b/include/linux/wakeup_reason.h +@@ -0,0 +1,30 @@ ++/* ++ * include/linux/wakeup_reason.h ++ * ++ * Logs the reason which caused the kernel to resume ++ * from the suspend mode. ++ * ++ * Copyright (C) 2014 Google, Inc. ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _LINUX_WAKEUP_REASON_H ++#define _LINUX_WAKEUP_REASON_H ++ ++#define MAX_SUSPEND_ABORT_LEN 256 ++ ++void log_wakeup_reason(int irq); ++#ifdef CONFIG_SUSPEND ++void log_suspend_abort_reason(const char *fmt, ...); ++#else ++static inline void log_suspend_abort_reason(const char *fmt, ...) { } ++#endif ++ ++#endif /* _LINUX_WAKEUP_REASON_H */ +diff --git a/kernel/power/Makefile b/kernel/power/Makefile +index e7e47d9be1e56..c673a1b739735 100644 +--- a/kernel/power/Makefile ++++ b/kernel/power/Makefile +@@ -16,4 +16,5 @@ obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o + + obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o + ++obj-$(CONFIG_SUSPEND) += wakeup_reason.o + obj-$(CONFIG_ENERGY_MODEL) += energy_model.o +diff --git a/kernel/power/process.c b/kernel/power/process.c +index 4b6a54da7e65b..dfd2494543c1c 100644 +--- a/kernel/power/process.c ++++ b/kernel/power/process.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + /* + * Timeout for stopping processes +@@ -38,6 +39,9 @@ static int try_to_freeze_tasks(bool user_only) + unsigned int elapsed_msecs; + bool wakeup = false; + int sleep_usecs = USEC_PER_MSEC; ++#ifdef CONFIG_PM_SLEEP ++ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; ++#endif + + start = ktime_get_boottime(); + +@@ -67,6 +71,11 @@ static int try_to_freeze_tasks(bool user_only) + break; + + if (pm_wakeup_pending()) { ++#ifdef CONFIG_PM_SLEEP ++ pm_get_active_wakeup_sources(suspend_abort, ++ MAX_SUSPEND_ABORT_LEN); ++ log_suspend_abort_reason(suspend_abort); ++#endif + wakeup = true; + break; + } +@@ -85,18 +94,21 @@ static int try_to_freeze_tasks(bool user_only) + elapsed = ktime_sub(end, start); + elapsed_msecs = ktime_to_ms(elapsed); + +- if (todo) { ++ if (wakeup) { + pr_cont("\n"); +- pr_err("Freezing of tasks %s after %d.%03d seconds " +- "(%d tasks refusing to freeze, wq_busy=%d):\n", +- wakeup ? "aborted" : "failed", ++ pr_err("Freezing of tasks aborted after %d.%03d seconds", ++ elapsed_msecs / 1000, elapsed_msecs % 1000); ++ } else if (todo) { ++ pr_cont("\n"); ++ pr_err("Freezing of tasks failed after %d.%03d seconds" ++ " (%d tasks refusing to freeze, wq_busy=%d):\n", + elapsed_msecs / 1000, elapsed_msecs % 1000, + todo - wq_busy, wq_busy); + + if (wq_busy) + show_workqueue_state(); + +- if (!wakeup || pm_debug_messages_on) { ++ if (pm_debug_messages_on) { + read_lock(&tasklist_lock); + for_each_process_thread(g, p) { + if (p != current && !freezer_should_skip(p) +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index c874a7026e249..058c2be53d070 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "power.h" + +@@ -400,7 +401,8 @@ void __weak arch_suspend_enable_irqs(void) + */ + static int suspend_enter(suspend_state_t state, bool *wakeup) + { +- int error; ++ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; ++ int error, last_dev; + + error = platform_suspend_prepare(state); + if (error) +@@ -408,7 +410,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) + + error = dpm_suspend_late(PMSG_SUSPEND); + if (error) { ++ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; ++ last_dev %= REC_FAILED_NUM; + pr_err("late suspend of devices failed\n"); ++ log_suspend_abort_reason("%s device failed to power down", ++ suspend_stats.failed_devs[last_dev]); + goto Platform_finish; + } + error = platform_suspend_prepare_late(state); +@@ -422,7 +428,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) + + error = dpm_suspend_noirq(PMSG_SUSPEND); + if (error) { ++ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; ++ last_dev %= REC_FAILED_NUM; + pr_err("noirq suspend of devices failed\n"); ++ log_suspend_abort_reason("noirq suspend of %s device failed", ++ suspend_stats.failed_devs[last_dev]); + goto Platform_early_resume; + } + error = platform_suspend_prepare_noirq(state); +@@ -433,8 +443,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) + goto Platform_wake; + + error = suspend_disable_secondary_cpus(); +- if (error || suspend_test(TEST_CPUS)) ++ if (error || suspend_test(TEST_CPUS)) { ++ log_suspend_abort_reason("Disabling non-boot cpus failed"); + goto Enable_cpus; ++ } + + arch_suspend_disable_irqs(); + BUG_ON(!irqs_disabled()); +@@ -451,6 +463,9 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) + trace_suspend_resume(TPS("machine_suspend"), + state, false); + } else if (*wakeup) { ++ pm_get_active_wakeup_sources(suspend_abort, ++ MAX_SUSPEND_ABORT_LEN); ++ log_suspend_abort_reason(suspend_abort); + error = -EBUSY; + } + syscore_resume(); +@@ -505,6 +520,7 @@ int suspend_devices_and_enter(suspend_state_t state) + error = dpm_suspend_start(PMSG_SUSPEND); + if (error) { + pr_err("Some devices failed to suspend, or early wake event detected\n"); ++ log_suspend_abort_reason("Some devices failed to suspend, or early wake event detected"); + goto Recover_platform; + } + suspend_test_finish("suspend devices"); +diff --git a/kernel/power/wakeup_reason.c b/kernel/power/wakeup_reason.c +new file mode 100644 +index 0000000000000..3ce5c902e3d3c +--- /dev/null ++++ b/kernel/power/wakeup_reason.c +@@ -0,0 +1,215 @@ ++/* ++ * kernel/power/wakeup_reason.c ++ * ++ * Logs the reasons which caused the kernel to resume from ++ * the suspend mode. ++ * ++ * Copyright (C) 2014 Google, Inc. ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define MAX_WAKEUP_REASON_IRQS 32 ++static int irq_list[MAX_WAKEUP_REASON_IRQS]; ++static int irqcount; ++static bool suspend_abort; ++static char abort_reason[MAX_SUSPEND_ABORT_LEN]; ++static struct kobject *wakeup_reason; ++static spinlock_t resume_reason_lock; ++ ++static ktime_t last_monotime; /* monotonic time before last suspend */ ++static ktime_t curr_monotime; /* monotonic time after last suspend */ ++static ktime_t last_stime; /* monotonic boottime offset before last suspend */ ++static ktime_t curr_stime; /* monotonic boottime offset after last suspend */ ++ ++static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf) ++{ ++ int irq_no, buf_offset = 0; ++ struct irq_desc *desc; ++ unsigned long flags; ++ spin_lock_irqsave(&resume_reason_lock, flags); ++ if (suspend_abort) { ++ buf_offset = sprintf(buf, "Abort: %s", abort_reason); ++ } else { ++ for (irq_no = 0; irq_no < irqcount; irq_no++) { ++ desc = irq_to_desc(irq_list[irq_no]); ++ if (desc && desc->action && desc->action->name) ++ buf_offset += sprintf(buf + buf_offset, "%d %s\n", ++ irq_list[irq_no], desc->action->name); ++ else ++ buf_offset += sprintf(buf + buf_offset, "%d\n", ++ irq_list[irq_no]); ++ } ++ } ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++ return buf_offset; ++} ++ ++static ssize_t last_suspend_time_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ struct timespec64 sleep_time; ++ struct timespec64 total_time; ++ struct timespec64 suspend_resume_time; ++ ++ /* ++ * total_time is calculated from monotonic bootoffsets because ++ * unlike CLOCK_MONOTONIC it include the time spent in suspend state. ++ */ ++ total_time = ktime_to_timespec64(ktime_sub(curr_stime, last_stime)); ++ ++ /* ++ * suspend_resume_time is calculated as monotonic (CLOCK_MONOTONIC) ++ * time interval before entering suspend and post suspend. ++ */ ++ suspend_resume_time = ++ ktime_to_timespec64(ktime_sub(curr_monotime, last_monotime)); ++ ++ /* sleep_time = total_time - suspend_resume_time */ ++ sleep_time = timespec64_sub(total_time, suspend_resume_time); ++ ++ /* Export suspend_resume_time and sleep_time in pair here. */ ++ return sprintf(buf, "%llu.%09lu %llu.%09lu\n", ++ suspend_resume_time.tv_sec, suspend_resume_time.tv_nsec, ++ sleep_time.tv_sec, sleep_time.tv_nsec); ++} ++ ++static struct kobj_attribute resume_reason = __ATTR_RO(last_resume_reason); ++static struct kobj_attribute suspend_time = __ATTR_RO(last_suspend_time); ++ ++static struct attribute *attrs[] = { ++ &resume_reason.attr, ++ &suspend_time.attr, ++ NULL, ++}; ++static struct attribute_group attr_group = { ++ .attrs = attrs, ++}; ++ ++/* ++ * logs all the wake up reasons to the kernel ++ * stores the irqs to expose them to the userspace via sysfs ++ */ ++void log_wakeup_reason(int irq) ++{ ++ struct irq_desc *desc; ++ unsigned long flags; ++ desc = irq_to_desc(irq); ++ if (desc && desc->action && desc->action->name) ++ printk(KERN_INFO "Resume caused by IRQ %d, %s\n", irq, ++ desc->action->name); ++ else ++ printk(KERN_INFO "Resume caused by IRQ %d\n", irq); ++ ++ spin_lock_irqsave(&resume_reason_lock, flags); ++ if (irqcount == MAX_WAKEUP_REASON_IRQS) { ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++ printk(KERN_WARNING "Resume caused by more than %d IRQs\n", ++ MAX_WAKEUP_REASON_IRQS); ++ return; ++ } ++ ++ irq_list[irqcount++] = irq; ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++} ++ ++void log_suspend_abort_reason(const char *fmt, ...) ++{ ++ unsigned long flags; ++ va_list args; ++ ++ spin_lock_irqsave(&resume_reason_lock, flags); ++ ++ //Suspend abort reason has already been logged. ++ if (suspend_abort) { ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++ return; ++ } ++ ++ suspend_abort = true; ++ va_start(args, fmt); ++ vsnprintf(abort_reason, MAX_SUSPEND_ABORT_LEN, fmt, args); ++ va_end(args); ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++} ++ ++/* Detects a suspend and clears all the previous wake up reasons*/ ++static int wakeup_reason_pm_event(struct notifier_block *notifier, ++ unsigned long pm_event, void *unused) ++{ ++ unsigned long flags; ++ switch (pm_event) { ++ case PM_SUSPEND_PREPARE: ++ spin_lock_irqsave(&resume_reason_lock, flags); ++ irqcount = 0; ++ suspend_abort = false; ++ spin_unlock_irqrestore(&resume_reason_lock, flags); ++ /* monotonic time since boot */ ++ last_monotime = ktime_get(); ++ /* monotonic time since boot including the time spent in suspend */ ++ last_stime = ktime_get_boottime(); ++ break; ++ case PM_POST_SUSPEND: ++ /* monotonic time since boot */ ++ curr_monotime = ktime_get(); ++ /* monotonic time since boot including the time spent in suspend */ ++ curr_stime = ktime_get_boottime(); ++ break; ++ default: ++ break; ++ } ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block wakeup_reason_pm_notifier_block = { ++ .notifier_call = wakeup_reason_pm_event, ++}; ++ ++/* Initializes the sysfs parameter ++ * registers the pm_event notifier ++ */ ++int __init wakeup_reason_init(void) ++{ ++ int retval; ++ spin_lock_init(&resume_reason_lock); ++ retval = register_pm_notifier(&wakeup_reason_pm_notifier_block); ++ if (retval) ++ printk(KERN_WARNING "[%s] failed to register PM notifier %d\n", ++ __func__, retval); ++ ++ wakeup_reason = kobject_create_and_add("wakeup_reasons", kernel_kobj); ++ if (!wakeup_reason) { ++ printk(KERN_WARNING "[%s] failed to create a sysfs kobject\n", ++ __func__); ++ return 1; ++ } ++ retval = sysfs_create_group(wakeup_reason, &attr_group); ++ if (retval) { ++ kobject_put(wakeup_reason); ++ printk(KERN_WARNING "[%s] failed to create a sysfs group %d\n", ++ __func__, retval); ++ } ++ return 0; ++} ++ ++late_initcall(wakeup_reason_init); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-proc-Add-proc-uid-directory.patch b/patches/ANDROID-proc-Add-proc-uid-directory.patch new file mode 100644 index 000000000000..dfa426d44da5 --- /dev/null +++ b/patches/ANDROID-proc-Add-proc-uid-directory.patch @@ -0,0 +1,436 @@ +From 48f01a0b664488b5245fd5a5d40d39b6898d65b1 Mon Sep 17 00:00:00 2001 +From: Connor O'Brien +Date: Mon, 16 Oct 2017 10:30:24 -0700 +Subject: ANDROID: proc: Add /proc/uid directory + +Add support for reporting per-uid information through procfs, roughly +following the approach used for per-tid and per-tgid directories in +fs/proc/base.c. +This also entails some new tracking of which uids have been used, to +avoid losing information when the last task with a given uid exits. + +Bug: 72339335 +Bug: 127641090 +Test: ls /proc/uid/; compare with UIDs in /proc/uid_time_in_state +Change-Id: I0908f0c04438b11ceb673d860e58441bf503d478 +Signed-off-by: Connor O'Brien +[AmitP: Fix proc_fill_cache() now that upstream commit + 0168b9e38c42 ("procfs: switch instantiate_t to d_splice_alias()"), + switched instantiate() callback to d_splice_alias()] +Signed-off-by: Amit Pundir +[astrachan: Folded 97b7790f505e ("ANDROID: proc: fix undefined behavior + in proc_uid_base_readdir") into this change] +Signed-off-by: Alistair Strachan +--- + fs/proc/Kconfig | 6 + + fs/proc/Makefile | 1 + + fs/proc/internal.h | 9 ++ + fs/proc/root.c | 1 + + fs/proc/uid.c | 290 ++++++++++++++++++++++++++++++++++++++++ + include/linux/proc_fs.h | 6 + + kernel/user.c | 3 + + 7 files changed, 316 insertions(+) + create mode 100644 fs/proc/uid.c + +diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig +index cb5629bd5fffe..313ae27bb674d 100644 +--- a/fs/proc/Kconfig ++++ b/fs/proc/Kconfig +@@ -103,3 +103,9 @@ config PROC_CHILDREN + config PROC_PID_ARCH_STATUS + def_bool n + depends on PROC_FS ++ ++config PROC_UID ++ bool "Include /proc/uid/ files" ++ depends on PROC_FS && RT_MUTEXES ++ help ++ Provides aggregated per-uid information under /proc/uid. +diff --git a/fs/proc/Makefile b/fs/proc/Makefile +index ead487e805108..3f849ca0edcea 100644 +--- a/fs/proc/Makefile ++++ b/fs/proc/Makefile +@@ -27,6 +27,7 @@ proc-y += softirqs.o + proc-y += namespaces.o + proc-y += self.o + proc-y += thread_self.o ++proc-$(CONFIG_PROC_UID) += uid.o + proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o + proc-$(CONFIG_NET) += proc_net.o + proc-$(CONFIG_PROC_KCORE) += kcore.o +diff --git a/fs/proc/internal.h b/fs/proc/internal.h +index cd0c8d5ce9a13..95846552ef245 100644 +--- a/fs/proc/internal.h ++++ b/fs/proc/internal.h +@@ -253,6 +253,15 @@ static inline void proc_sys_evict_inode(struct inode *inode, + struct ctl_table_header *head) { } + #endif + ++/* ++ * uid.c ++ */ ++#ifdef CONFIG_PROC_UID ++extern int proc_uid_init(void); ++#else ++static inline void proc_uid_init(void) { } ++#endif ++ + /* + * proc_tty.c + */ +diff --git a/fs/proc/root.c b/fs/proc/root.c +index 33f72d1b92cca..132a86b3bcf99 100644 +--- a/fs/proc/root.c ++++ b/fs/proc/root.c +@@ -222,6 +222,7 @@ void __init proc_root_init(void) + proc_symlink("mounts", NULL, "self/mounts"); + + proc_net_init(); ++ proc_uid_init(); + proc_mkdir("fs", NULL); + proc_mkdir("driver", NULL); + proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */ +diff --git a/fs/proc/uid.c b/fs/proc/uid.c +new file mode 100644 +index 0000000000000..ae720b93a0ed2 +--- /dev/null ++++ b/fs/proc/uid.c +@@ -0,0 +1,290 @@ ++/* ++ * /proc/uid support ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "internal.h" ++ ++static struct proc_dir_entry *proc_uid; ++ ++#define UID_HASH_BITS 10 ++ ++static DECLARE_HASHTABLE(proc_uid_hash_table, UID_HASH_BITS); ++ ++/* ++ * use rt_mutex here to avoid priority inversion between high-priority readers ++ * of these files and tasks calling proc_register_uid(). ++ */ ++static DEFINE_RT_MUTEX(proc_uid_lock); /* proc_uid_hash_table */ ++ ++struct uid_hash_entry { ++ uid_t uid; ++ struct hlist_node hash; ++}; ++ ++/* Caller must hold proc_uid_lock */ ++static bool uid_hash_entry_exists_locked(uid_t uid) ++{ ++ struct uid_hash_entry *entry; ++ ++ hash_for_each_possible(proc_uid_hash_table, entry, hash, uid) { ++ if (entry->uid == uid) ++ return true; ++ } ++ return false; ++} ++ ++void proc_register_uid(kuid_t kuid) ++{ ++ struct uid_hash_entry *entry; ++ bool exists; ++ uid_t uid = from_kuid_munged(current_user_ns(), kuid); ++ ++ rt_mutex_lock(&proc_uid_lock); ++ exists = uid_hash_entry_exists_locked(uid); ++ rt_mutex_unlock(&proc_uid_lock); ++ if (exists) ++ return; ++ ++ entry = kzalloc(sizeof(struct uid_hash_entry), GFP_KERNEL); ++ if (!entry) ++ return; ++ entry->uid = uid; ++ ++ rt_mutex_lock(&proc_uid_lock); ++ if (uid_hash_entry_exists_locked(uid)) ++ kfree(entry); ++ else ++ hash_add(proc_uid_hash_table, &entry->hash, uid); ++ rt_mutex_unlock(&proc_uid_lock); ++} ++ ++struct uid_entry { ++ const char *name; ++ int len; ++ umode_t mode; ++ const struct inode_operations *iop; ++ const struct file_operations *fop; ++}; ++ ++#define NOD(NAME, MODE, IOP, FOP) { \ ++ .name = (NAME), \ ++ .len = sizeof(NAME) - 1, \ ++ .mode = MODE, \ ++ .iop = IOP, \ ++ .fop = FOP, \ ++} ++ ++static const struct uid_entry uid_base_stuff[] = {}; ++ ++static const struct inode_operations proc_uid_def_inode_operations = { ++ .setattr = proc_setattr, ++}; ++ ++static struct inode *proc_uid_make_inode(struct super_block *sb, kuid_t kuid) ++{ ++ struct inode *inode; ++ ++ inode = new_inode(sb); ++ if (!inode) ++ return NULL; ++ ++ inode->i_ino = get_next_ino(); ++ inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); ++ inode->i_op = &proc_uid_def_inode_operations; ++ inode->i_uid = kuid; ++ ++ return inode; ++} ++ ++static struct dentry *proc_uident_instantiate(struct dentry *dentry, ++ struct task_struct *unused, const void *ptr) ++{ ++ const struct uid_entry *u = ptr; ++ struct inode *inode; ++ ++ uid_t uid = name_to_int(&dentry->d_name); ++ kuid_t kuid; ++ bool uid_exists; ++ rt_mutex_lock(&proc_uid_lock); ++ uid_exists = uid_hash_entry_exists_locked(uid); ++ rt_mutex_unlock(&proc_uid_lock); ++ if (uid_exists) { ++ kuid = make_kuid(current_user_ns(), uid); ++ inode = proc_uid_make_inode(dentry->d_sb, kuid); ++ if (!inode) ++ return ERR_PTR(-ENOENT); ++ } else { ++ return ERR_PTR(-ENOENT); ++ } ++ ++ inode->i_mode = u->mode; ++ if (S_ISDIR(inode->i_mode)) ++ set_nlink(inode, 2); ++ if (u->iop) ++ inode->i_op = u->iop; ++ if (u->fop) ++ inode->i_fop = u->fop; ++ ++ return d_splice_alias(inode, dentry); ++} ++ ++static struct dentry *proc_uid_base_lookup(struct inode *dir, ++ struct dentry *dentry, ++ unsigned int flags) ++{ ++ const struct uid_entry *u, *last; ++ unsigned int nents = ARRAY_SIZE(uid_base_stuff); ++ ++ if (nents == 0) ++ return ERR_PTR(-ENOENT); ++ ++ last = &uid_base_stuff[nents - 1]; ++ for (u = uid_base_stuff; u <= last; u++) { ++ if (u->len != dentry->d_name.len) ++ continue; ++ if (!memcmp(dentry->d_name.name, u->name, u->len)) ++ break; ++ } ++ if (u > last) ++ return ERR_PTR(-ENOENT); ++ ++ return proc_uident_instantiate(dentry, NULL, u); ++} ++ ++static int proc_uid_base_readdir(struct file *file, struct dir_context *ctx) ++{ ++ unsigned int nents = ARRAY_SIZE(uid_base_stuff); ++ const struct uid_entry *u; ++ ++ if (!dir_emit_dots(file, ctx)) ++ return 0; ++ ++ if (ctx->pos >= nents + 2) ++ return 0; ++ ++ for (u = uid_base_stuff + (ctx->pos - 2); ++ u < uid_base_stuff + nents; u++) { ++ if (!proc_fill_cache(file, ctx, u->name, u->len, ++ proc_uident_instantiate, NULL, u)) ++ break; ++ ctx->pos++; ++ } ++ ++ return 0; ++} ++ ++static const struct inode_operations proc_uid_base_inode_operations = { ++ .lookup = proc_uid_base_lookup, ++ .setattr = proc_setattr, ++}; ++ ++static const struct file_operations proc_uid_base_operations = { ++ .read = generic_read_dir, ++ .iterate = proc_uid_base_readdir, ++ .llseek = default_llseek, ++}; ++ ++static struct dentry *proc_uid_instantiate(struct dentry *dentry, ++ struct task_struct *unused, const void *ptr) ++{ ++ unsigned int i, len; ++ nlink_t nlinks; ++ kuid_t *kuid = (kuid_t *)ptr; ++ struct inode *inode = proc_uid_make_inode(dentry->d_sb, *kuid); ++ ++ if (!inode) ++ return ERR_PTR(-ENOENT); ++ ++ inode->i_mode = S_IFDIR | 0555; ++ inode->i_op = &proc_uid_base_inode_operations; ++ inode->i_fop = &proc_uid_base_operations; ++ inode->i_flags |= S_IMMUTABLE; ++ ++ nlinks = 2; ++ len = ARRAY_SIZE(uid_base_stuff); ++ for (i = 0; i < len; ++i) { ++ if (S_ISDIR(uid_base_stuff[i].mode)) ++ ++nlinks; ++ } ++ set_nlink(inode, nlinks); ++ ++ return d_splice_alias(inode, dentry); ++} ++ ++static int proc_uid_readdir(struct file *file, struct dir_context *ctx) ++{ ++ int last_shown, i; ++ unsigned long bkt; ++ struct uid_hash_entry *entry; ++ ++ if (!dir_emit_dots(file, ctx)) ++ return 0; ++ ++ i = 0; ++ last_shown = ctx->pos - 2; ++ rt_mutex_lock(&proc_uid_lock); ++ hash_for_each(proc_uid_hash_table, bkt, entry, hash) { ++ int len; ++ char buf[PROC_NUMBUF]; ++ ++ if (i < last_shown) ++ continue; ++ len = snprintf(buf, sizeof(buf), "%u", entry->uid); ++ if (!proc_fill_cache(file, ctx, buf, len, ++ proc_uid_instantiate, NULL, &entry->uid)) ++ break; ++ i++; ++ ctx->pos++; ++ } ++ rt_mutex_unlock(&proc_uid_lock); ++ return 0; ++} ++ ++static struct dentry *proc_uid_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags) ++{ ++ int result = -ENOENT; ++ ++ uid_t uid = name_to_int(&dentry->d_name); ++ bool uid_exists; ++ ++ rt_mutex_lock(&proc_uid_lock); ++ uid_exists = uid_hash_entry_exists_locked(uid); ++ rt_mutex_unlock(&proc_uid_lock); ++ if (uid_exists) { ++ kuid_t kuid = make_kuid(current_user_ns(), uid); ++ ++ return proc_uid_instantiate(dentry, NULL, &kuid); ++ } ++ return ERR_PTR(result); ++} ++ ++static const struct file_operations proc_uid_operations = { ++ .read = generic_read_dir, ++ .iterate = proc_uid_readdir, ++ .llseek = default_llseek, ++}; ++ ++static const struct inode_operations proc_uid_inode_operations = { ++ .lookup = proc_uid_lookup, ++ .setattr = proc_setattr, ++}; ++ ++int __init proc_uid_init(void) ++{ ++ proc_uid = proc_mkdir("uid", NULL); ++ if (!proc_uid) ++ return -ENOMEM; ++ proc_uid->proc_iops = &proc_uid_inode_operations; ++ proc_uid->proc_fops = &proc_uid_operations; ++ ++ return 0; ++} +diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h +index a705aa2d03f91..35e83f86e51ad 100644 +--- a/include/linux/proc_fs.h ++++ b/include/linux/proc_fs.h +@@ -131,6 +131,12 @@ static inline struct pid *tgid_pidfd_to_pid(const struct file *file) + + #endif /* CONFIG_PROC_FS */ + ++#ifdef CONFIG_PROC_UID ++extern void proc_register_uid(kuid_t uid); ++#else ++static inline void proc_register_uid(kuid_t uid) {} ++#endif ++ + struct net; + + static inline struct proc_dir_entry *proc_net_mkdir( +diff --git a/kernel/user.c b/kernel/user.c +index 5235d7f49982e..a32a8a59a13c5 100644 +--- a/kernel/user.c ++++ b/kernel/user.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -205,6 +206,7 @@ struct user_struct *alloc_uid(kuid_t uid) + } + spin_unlock_irq(&uidhash_lock); + } ++ proc_register_uid(uid); + + return up; + } +@@ -223,6 +225,7 @@ static int __init uid_cache_init(void) + spin_lock_irq(&uidhash_lock); + uid_hash_insert(&root_user, uidhashentry(GLOBAL_ROOT_UID)); + spin_unlock_irq(&uidhash_lock); ++ proc_register_uid(GLOBAL_ROOT_UID); + + return 0; + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-refactor-build.config-files-to-remove-duplic.patch b/patches/ANDROID-refactor-build.config-files-to-remove-duplic.patch new file mode 100644 index 000000000000..65b0109db723 --- /dev/null +++ b/patches/ANDROID-refactor-build.config-files-to-remove-duplic.patch @@ -0,0 +1,116 @@ +From 6ef7169ac9fd79a47ee777a9f4f0e9a2e13a5978 Mon Sep 17 00:00:00 2001 +From: Matthias Maennich +Date: Thu, 29 Aug 2019 12:34:52 +0100 +Subject: ANDROID: refactor build.config files to remove + duplication + +The build.config.* files largely contain duplicate information by their +nature. Reorganize them reduce duplication and to allow adding new +configurations without copying the definitions again. + +Bug: 140224784 +Change-Id: I6a3810a125b0ed48591690ca33bb5c02be58218a +Signed-off-by: Matthias Maennich +--- + build.config.aarch64 | 11 +++++++++++ + build.config.common | 9 +++++++++ + build.config.gki | 4 ++++ + build.config.gki.aarch64 | 23 ++++------------------- + build.config.gki.x86_64 | 23 ++++------------------- + build.config.x86_64 | 11 +++++++++++ + 6 files changed, 43 insertions(+), 38 deletions(-) + create mode 100644 build.config.aarch64 + create mode 100644 build.config.common + create mode 100644 build.config.gki + create mode 100644 build.config.x86_64 + +diff --git a/build.config.aarch64 b/build.config.aarch64 +new file mode 100644 +index 0000000000000..523bbc0449f75 +--- /dev/null ++++ b/build.config.aarch64 +@@ -0,0 +1,11 @@ ++ARCH=arm64 ++ ++CLANG_TRIPLE=aarch64-linux-gnu- ++CROSS_COMPILE=aarch64-linux-androidkernel- ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin ++ ++FILES=" ++arch/arm64/boot/Image.gz ++vmlinux ++System.map ++" +diff --git a/build.config.common b/build.config.common +new file mode 100644 +index 0000000000000..3f1fac231a826 +--- /dev/null ++++ b/build.config.common +@@ -0,0 +1,9 @@ ++BRANCH=android-mainline ++KERNEL_DIR=common ++ ++CC=clang ++CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin ++BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 ++ ++EXTRA_CMDS='' ++STOP_SHIP_TRACEPRINTK=1 +diff --git a/build.config.gki b/build.config.gki +new file mode 100644 +index 0000000000000..66f6eb8baadbd +--- /dev/null ++++ b/build.config.gki +@@ -0,0 +1,4 @@ ++DEFCONFIG=gki_defconfig ++POST_DEFCONFIG_CMDS="check_defconfig" ++BUILD_INITRAMFS=1 ++ +diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 +index 5c2db37a28712..627d1e1c27ab0 100644 +--- a/build.config.gki.x86_64 ++++ b/build.config.gki.x86_64 +@@ -1,19 +1,4 @@ +-ARCH=x86_64 +-BRANCH=android-mainline +-CLANG_TRIPLE=x86_64-linux-gnu- +-CROSS_COMPILE=x86_64-linux-androidkernel- +-CC=clang +-DEFCONFIG=gki_defconfig +-EXTRA_CMDS='' +-KERNEL_DIR=common +-POST_DEFCONFIG_CMDS="check_defconfig" +-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin +-BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 +-LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin +-FILES=" +-arch/x86/boot/bzImage +-vmlinux +-System.map +-" +-STOP_SHIP_TRACEPRINTK=1 +-BUILD_INITRAMFS=1 ++. ${ROOT_DIR}/common/build.config.common ++. ${ROOT_DIR}/common/build.config.x86_64 ++. ${ROOT_DIR}/common/build.config.gki ++ +diff --git a/build.config.x86_64 b/build.config.x86_64 +new file mode 100644 +index 0000000000000..df73a47e72208 +--- /dev/null ++++ b/build.config.x86_64 +@@ -0,0 +1,11 @@ ++ARCH=x86_64 ++ ++CLANG_TRIPLE=x86_64-linux-gnu- ++CROSS_COMPILE=x86_64-linux-androidkernel- ++LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin ++ ++FILES=" ++arch/x86/boot/bzImage ++vmlinux ++System.map ++" +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wra.patch b/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wra.patch new file mode 100644 index 000000000000..0bf3d669dbbd --- /dev/null +++ b/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wra.patch @@ -0,0 +1,71 @@ +From 0e00b6f9dd78f16d214959bb4b1af7ec4e62f9e4 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Tue, 30 Jul 2019 13:58:29 +0100 +Subject: ANDROID: sched: Introduce uclamp latency and boost + wrapper + +Introduce a simple helper to read the latency_sensitive flag from a +task. It is called uclamp_latency_sensitive() to match the API +proposed by Patrick. + +While at it, introduce uclamp_boosted() which returns true only when a +task has a non-null min-clamp. + +Change-Id: I5fc747da8b58625257a6604a3c88487b657fbe7a +Suggested-by: Patrick Bellasi +Signed-off-by: Quentin Perret +--- + kernel/sched/sched.h | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 7de9f16cb838..4f0d1668c283 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -2333,6 +2333,11 @@ static inline unsigned int uclamp_util(struct rq *rq, unsigned int util) + { + return uclamp_util_with(rq, util, NULL); + } ++ ++static inline bool uclamp_boosted(struct task_struct *p) ++{ ++ return uclamp_eff_value(p, UCLAMP_MIN) > 0; ++} + #else /* CONFIG_UCLAMP_TASK */ + static inline unsigned int uclamp_util_with(struct rq *rq, unsigned int util, + struct task_struct *p) +@@ -2343,8 +2348,31 @@ static inline unsigned int uclamp_util(struct rq *rq, unsigned int util) + { + return util; + } ++static inline bool uclamp_boosted(struct task_struct *p) ++{ ++ return false; ++} + #endif /* CONFIG_UCLAMP_TASK */ + ++#ifdef CONFIG_UCLAMP_TASK_GROUP ++static inline bool uclamp_latency_sensitive(struct task_struct *p) ++{ ++ struct cgroup_subsys_state *css = task_css(p, cpu_cgrp_id); ++ struct task_group *tg; ++ ++ if (!css) ++ return false; ++ tg = container_of(css, struct task_group, css); ++ ++ return tg->latency_sensitive; ++} ++#else ++static inline bool uclamp_latency_sensitive(struct task_struct *p) ++{ ++ return false; ++} ++#endif /* CONFIG_UCLAMP_TASK_GROUP */ ++ + #ifdef arch_scale_freq_capacity + # ifndef arch_scale_freq_invariant + # define arch_scale_freq_invariant() true +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-.patch b/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-.patch new file mode 100644 index 000000000000..2270b18b83b1 --- /dev/null +++ b/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-.patch @@ -0,0 +1,63 @@ +From 65b8ddef4ef06f78b29207ef5ec508fb58ad807f Mon Sep 17 00:00:00 2001 +From: Morten Rasmussen +Date: Thu, 2 Jul 2015 17:16:34 +0100 +Subject: ANDROID: sched: Prevent unnecessary active balance of + single task in sched group + +Scenarios with the busiest group having just one task and the local +being idle on topologies with sched groups with different numbers of +cpus manage to dodge all load-balance bailout conditions resulting the +nr_balance_failed counter to be incremented. This eventually causes a +pointless active migration of the task. This patch prevents this by not +incrementing the counter when the busiest group only has one task. +ASYM_PACKING migrations and migrations due to reduced capacity should +still take place as these are explicitly captured by +need_active_balance(). + +A better solution would be to not attempt the load-balance in the first +place, but that requires significant changes to the order of bailout +conditions and statistics gathering. + +Change-Id: I28f69c72febe0211decbe77b7bc3e48839d3d7b3 +cc: Ingo Molnar +cc: Peter Zijlstra +Signed-off-by: Morten Rasmussen +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index b4314e918c29..df279e422001 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -7112,6 +7112,7 @@ struct lb_env { + int new_dst_cpu; + enum cpu_idle_type idle; + long imbalance; ++ unsigned int src_grp_nr_running; + /* The set of CPUs under consideration for load-balancing */ + struct cpumask *cpus; + +@@ -8294,6 +8295,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd + if (env->sd->flags & SD_NUMA) + env->fbq_type = fbq_classify_group(&sds->busiest_stat); + ++ env->src_grp_nr_running = sds->busiest_stat.sum_nr_running; ++ + if (!env->sd->parent) { + struct root_domain *rd = env->dst_rq->rd; + +@@ -8988,7 +8991,8 @@ static int load_balance(int this_cpu, struct rq *this_rq, + * excessive cache_hot migrations and active balances. + */ + if (idle != CPU_NEWLY_IDLE) +- sd->nr_balance_failed++; ++ if (env.src_grp_nr_running > 1) ++ sd->nr_balance_failed++; + + if (need_active_balance(&env)) { + unsigned long flags; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-en.patch b/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-en.patch new file mode 100644 index 000000000000..2b270ac2a43d --- /dev/null +++ b/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-en.patch @@ -0,0 +1,64 @@ +From 79e3a4a27ee502ffed05bb8011d9540867a66719 Mon Sep 17 00:00:00 2001 +From: Chris Redpath +Date: Wed, 27 Mar 2019 17:15:17 +0000 +Subject: ANDROID: sched: Unconditionally honor sync flag for + energy-aware wakeups + +Since we don't do energy-aware wakeups when we are overutilized, always +honoring sync wakeups in this state does not prevent wake-wide mechanics +overruling the flag as normal. + +This patch is based upon previous work to build EAS for android products. + +sync-hint code taken from commit 4a5e890ec60d +"sched/fair: add tunable to force selection at cpu granularity" written +by Juri Lelli + +Change-Id: I4b3d79141fc8e53dc51cd63ac11096c2e3cb10f5 +Signed-off-by: Chris Redpath +(cherry-picked from commit f1ec666a62dec1083ed52fe1ddef093b84373aaf) +[ Moved the feature to find_energy_efficient_cpu() and removed the + sysctl knob ] +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index c80cf449f9fb..baefb5ebc85e 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -6336,7 +6336,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) + * other use-cases too. So, until someone finds a better way to solve this, + * let's keep things simple by re-using the existing slow path. + */ +-static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) ++static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sync) + { + unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; + struct root_domain *rd = cpu_rq(smp_processor_id())->rd; +@@ -6350,6 +6350,12 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + if (!pd || READ_ONCE(rd->overutilized)) + goto fail; + ++ cpu = smp_processor_id(); ++ if (sync && cpumask_test_cpu(cpu, p->cpus_ptr)) { ++ rcu_read_unlock(); ++ return cpu; ++ } ++ + /* + * Energy-aware wake-up happens on the lowest sched_domain starting + * from sd_asym_cpucapacity spanning over this_cpu and prev_cpu. +@@ -6461,7 +6467,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f + record_wakee(p); + + if (sched_energy_enabled()) { +- new_cpu = find_energy_efficient_cpu(p, prev_cpu); ++ new_cpu = find_energy_efficient_cpu(p, prev_cpu, sync); + if (new_cpu >= 0) + return new_cpu; + new_cpu = prev_cpu; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max.patch b/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max.patch new file mode 100644 index 000000000000..5bc8c35d50a5 --- /dev/null +++ b/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max.patch @@ -0,0 +1,222 @@ +From 24c44377976ea7812e321072d6bb366a648f7356 Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann +Date: Sat, 26 Sep 2015 18:19:54 +0100 +Subject: ANDROID: sched: Update max cpu capacity in case of + max frequency constraints + +Wakeup balancing uses cpu capacity awareness and needs to know the +system-wide maximum cpu capacity. + +Patch "sched: Store system-wide maximum cpu capacity in root domain" +finds the system-wide maximum cpu capacity during scheduler domain +hierarchy setup. This is sufficient as long as maximum frequency +invariance is not enabled. + +If it is enabled, the system-wide maximum cpu capacity can change +between scheduler domain hierarchy setups due to frequency capping. + +The cpu capacity is changed in update_cpu_capacity() which is called in +load balance on the lowest scheduler domain hierarchy level. To be able +to know if a change in cpu capacity for a certain cpu also has an effect +on the system-wide maximum cpu capacity it is normally necessary to +iterate over all cpus. This would be way too costly. That's why this +patch follows a different approach. + +The unsigned long max_cpu_capacity value in struct root_domain is +replaced with a struct max_cpu_capacity, containing value (the +max_cpu_capacity) and cpu (the cpu index of the cpu providing the +maximum cpu_capacity). + +Changes to the system-wide maximum cpu capacity and the cpu index are +made if: + + 1 System-wide maximum cpu capacity < cpu capacity + 2 System-wide maximum cpu capacity > cpu capacity and cpu index == cpu + +There are no changes to the system-wide maximum cpu capacity in all +other cases. + +Atomic read and write access to the pair (max_cpu_capacity.val, +max_cpu_capacity.cpu) is enforced by max_cpu_capacity.lock. + +The access to max_cpu_capacity.val in task_fits_max() is still performed +without taking the max_cpu_capacity.lock. + +The code to set max cpu capacity in build_sched_domains() has been +removed because the whole functionality is now provided by +update_cpu_capacity() instead. + +This approach can introduce errors temporarily, e.g. in case the cpu +currently providing the max cpu capacity has its cpu capacity lowered +due to frequency capping and calls update_cpu_capacity() before any cpu +which might provide the max cpu now. + +Change-Id: I5063befab088fbf49e5d5e484ce0c6ee6165283a +Signed-off-by: Ionela Voinescu * +Signed-off-by: Dietmar Eggemann +(- Fixed cherry-pick issues, and conflict with a0fe2cf086ae "sched/fair: + Tune down misfit NOHZ kicks" which makes use of max_cpu_capacity + - Squashed "sched/fair: remove printk while schedule is in progress" + fix from Caesar Wang ) +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 34 ++++++++++++++++++++++++++++++++-- + kernel/sched/sched.h | 10 +++++++++- + kernel/sched/topology.c | 15 +++------------ + 3 files changed, 44 insertions(+), 15 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index fee99f8cb193..b4314e918c29 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -6195,7 +6195,7 @@ static int wake_cap(struct task_struct *p, int cpu, int prev_cpu) + return 0; + + min_cap = min(capacity_orig_of(prev_cpu), capacity_orig_of(cpu)); +- max_cap = cpu_rq(cpu)->rd->max_cpu_capacity; ++ max_cap = cpu_rq(cpu)->rd->max_cpu_capacity.val; + + /* Minimum capacity is close to max, no need to abort wake_affine */ + if (max_cap - min_cap < max_cap >> 3) +@@ -7747,16 +7747,46 @@ static unsigned long scale_rt_capacity(int cpu, unsigned long max) + return scale_irq_capacity(free, irq, max); + } + ++void init_max_cpu_capacity(struct max_cpu_capacity *mcc) { ++ raw_spin_lock_init(&mcc->lock); ++ mcc->val = 0; ++ mcc->cpu = -1; ++} ++ + static void update_cpu_capacity(struct sched_domain *sd, int cpu) + { + unsigned long capacity = arch_scale_cpu_capacity(cpu); + struct sched_group *sdg = sd->groups; ++ struct max_cpu_capacity *mcc; ++ unsigned long max_capacity; ++ int max_cap_cpu; ++ unsigned long flags; + + cpu_rq(cpu)->cpu_capacity_orig = capacity; + + capacity *= arch_scale_max_freq_capacity(sd, cpu); + capacity >>= SCHED_CAPACITY_SHIFT; + ++ mcc = &cpu_rq(cpu)->rd->max_cpu_capacity; ++ ++ raw_spin_lock_irqsave(&mcc->lock, flags); ++ max_capacity = mcc->val; ++ max_cap_cpu = mcc->cpu; ++ ++ if ((max_capacity > capacity && max_cap_cpu == cpu) || ++ (max_capacity < capacity)) { ++ mcc->val = capacity; ++ mcc->cpu = cpu; ++#ifdef CONFIG_SCHED_DEBUG ++ raw_spin_unlock_irqrestore(&mcc->lock, flags); ++ printk_deferred(KERN_INFO "CPU%d: update max cpu_capacity %lu\n", ++ cpu, capacity); ++ goto skip_unlock; ++#endif ++ } ++ raw_spin_unlock_irqrestore(&mcc->lock, flags); ++ ++skip_unlock: __attribute__ ((unused)); + capacity = scale_rt_capacity(cpu, capacity); + + if (!capacity) +@@ -7861,7 +7891,7 @@ check_cpu_capacity(struct rq *rq, struct sched_domain *sd) + static inline int check_misfit_status(struct rq *rq, struct sched_domain *sd) + { + return rq->misfit_task_load && +- (rq->cpu_capacity_orig < rq->rd->max_cpu_capacity || ++ (rq->cpu_capacity_orig < rq->rd->max_cpu_capacity.val || + check_cpu_capacity(rq, sd)); + } + +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index f0b6e3ab2c96..9015c687de19 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -717,6 +717,12 @@ struct perf_domain { + struct rcu_head rcu; + }; + ++struct max_cpu_capacity { ++ raw_spinlock_t lock; ++ unsigned long val; ++ int cpu; ++}; ++ + /* Scheduling group status flags */ + #define SG_OVERLOAD 0x1 /* More than one runnable task on a CPU. */ + #define SG_OVERUTILIZED 0x2 /* One or more CPUs are over-utilized. */ +@@ -775,7 +781,8 @@ struct root_domain { + cpumask_var_t rto_mask; + struct cpupri cpupri; + +- unsigned long max_cpu_capacity; ++ /* Maximum cpu capacity in the system. */ ++ struct max_cpu_capacity max_cpu_capacity; + + /* + * NULL-terminated list of performance domains intersecting with the +@@ -785,6 +792,7 @@ struct root_domain { + }; + + extern void init_defrootdomain(void); ++extern void init_max_cpu_capacity(struct max_cpu_capacity *mcc); + extern int sched_init_domains(const struct cpumask *cpu_map); + extern void rq_attach_root(struct rq *rq, struct root_domain *rd); + extern void sched_get_rd(struct root_domain *rd); +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index b5667a273bf6..4ad1e5194555 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -510,6 +510,9 @@ static int init_rootdomain(struct root_domain *rd) + + if (cpupri_init(&rd->cpupri) != 0) + goto free_cpudl; ++ ++ init_max_cpu_capacity(&rd->max_cpu_capacity); ++ + return 0; + + free_cpudl: +@@ -1951,7 +1954,6 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att + enum s_alloc alloc_state; + struct sched_domain *sd; + struct s_data d; +- struct rq *rq = NULL; + int i, ret = -ENOMEM; + struct sched_domain_topology_level *tl_asym; + bool has_asym = false; +@@ -2014,13 +2016,7 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att + /* Attach the domains */ + rcu_read_lock(); + for_each_cpu(i, cpu_map) { +- rq = cpu_rq(i); + sd = *per_cpu_ptr(d.sd, i); +- +- /* Use READ_ONCE()/WRITE_ONCE() to avoid load/store tearing: */ +- if (rq->cpu_capacity_orig > READ_ONCE(d.rd->max_cpu_capacity)) +- WRITE_ONCE(d.rd->max_cpu_capacity, rq->cpu_capacity_orig); +- + cpu_attach_domain(sd, d.rd, i); + } + rcu_read_unlock(); +@@ -2028,11 +2024,6 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att + if (has_asym) + static_branch_enable_cpuslocked(&sched_asym_cpucapacity); + +- if (rq && sched_debug_enabled) { +- pr_info("root domain span: %*pbl (max cpu_capacity = %lu)\n", +- cpumask_pr_args(cpu_map), rq->rd->max_cpu_capacity); +- } +- + ret = 0; + error: + __free_domain_allocs(&d, alloc_state, cpu_map); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-u.patch b/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-u.patch new file mode 100644 index 000000000000..c81d19e46091 --- /dev/null +++ b/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-u.patch @@ -0,0 +1,100 @@ +From c28f9d3945f10f655983cd4fb0e71d972efa747b Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Tue, 30 Jul 2019 13:54:00 +0100 +Subject: ANDROID: sched/core: Add a latency-sensitive flag to + uclamp + +Add a 'latency_sensitive' flag to uclamp in order to express the need +for some tasks to find a CPU where they can wake-up quickly. This is not +expected to be used without cgroup support, so add solely a cgroup +interface for it. + +As this flag represents a boolean attribute and not an amount of +resources to be shared, it is not clear what the delegation logic should +be. As such, it is kept simple: every new cgroup starts with +latency_sensitive set to false, regardless of the parent. + +In essence, this is similar to SchedTune's prefer-idle flag which was +used in android-4.19 and prior. + +Change-Id: I722d8ecabb428bb7b95a5b54bc70a87f182dde2a +Signed-off-by: Quentin Perret +--- + kernel/sched/core.c | 33 +++++++++++++++++++++++++++++++++ + kernel/sched/sched.h | 2 ++ + 2 files changed, 35 insertions(+) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 7880f4f64d0e..7571fc49af89 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -7356,6 +7356,27 @@ static int cpu_uclamp_max_show(struct seq_file *sf, void *v) + cpu_uclamp_print(sf, UCLAMP_MAX); + return 0; + } ++ ++static int cpu_uclamp_ls_write_u64(struct cgroup_subsys_state *css, ++ struct cftype *cftype, u64 ls) ++{ ++ struct task_group *tg; ++ ++ if (ls > 1) ++ return -EINVAL; ++ tg = css_tg(css); ++ tg->latency_sensitive = (unsigned int) ls; ++ ++ return 0; ++} ++ ++static u64 cpu_uclamp_ls_read_u64(struct cgroup_subsys_state *css, ++ struct cftype *cft) ++{ ++ struct task_group *tg = css_tg(css); ++ ++ return (u64) tg->latency_sensitive; ++} + #endif /* CONFIG_UCLAMP_TASK_GROUP */ + + #ifdef CONFIG_FAIR_GROUP_SCHED +@@ -7716,6 +7737,12 @@ static struct cftype cpu_legacy_files[] = { + .seq_show = cpu_uclamp_max_show, + .write = cpu_uclamp_max_write, + }, ++ { ++ .name = "uclamp.latency_sensitive", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .read_u64 = cpu_uclamp_ls_read_u64, ++ .write_u64 = cpu_uclamp_ls_write_u64, ++ }, + #endif + { } /* Terminate */ + }; +@@ -7897,6 +7924,12 @@ static struct cftype cpu_files[] = { + .seq_show = cpu_uclamp_max_show, + .write = cpu_uclamp_max_write, + }, ++ { ++ .name = "uclamp.latency_sensitive", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .read_u64 = cpu_uclamp_ls_read_u64, ++ .write_u64 = cpu_uclamp_ls_write_u64, ++ }, + #endif + { } /* terminate */ + }; +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 9015c687de19..7de9f16cb838 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -399,6 +399,8 @@ struct task_group { + struct uclamp_se uclamp_req[UCLAMP_CNT]; + /* Effective clamp values used for a task group */ + struct uclamp_se uclamp[UCLAMP_CNT]; ++ /* Latency-sensitive flag used for a task group */ ++ unsigned int latency_sensitive; + #endif + + }; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-grou.patch b/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-grou.patch new file mode 100644 index 000000000000..5f402d6eddb3 --- /dev/null +++ b/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-grou.patch @@ -0,0 +1,37 @@ +From 44ab1611a8fa4ee1dc59a80b656f8b2e6aa4e57d Mon Sep 17 00:00:00 2001 +From: Chris Redpath +Date: Tue, 5 Jun 2018 12:21:33 +0100 +Subject: ANDROID: sched/fair: Also do misfit in overloaded + groups + +If we can classify the group as overloaded, that overrides +any classification as misfit but we may still have misfit +tasks present. Check the rq we're looking at to see if +this is the case. + +Change-Id: Ida8eb66aa625e34de3fe2ee1b0dd8a78926273d8 +Signed-off-by: Chris Redpath +[Removed stray reference to rq_has_misfit] +Signed-off-by: Valentin Schneider +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index af23c63eca32..4012266f4f64 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8798,6 +8798,9 @@ static int need_active_balance(struct lb_env *env) + if (voluntary_active_balance(env)) + return 1; + ++ if (env->src_grp_type == group_overloaded && env->src_rq->misfit_task_load) ++ return 1; ++ + return unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2); + } + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for.patch b/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for.patch new file mode 100644 index 000000000000..b0ee71549580 --- /dev/null +++ b/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for.patch @@ -0,0 +1,55 @@ +From f351885fc72a3c13e5a713fcc37097f7c2eceee8 Mon Sep 17 00:00:00 2001 +From: Chris Redpath +Date: Fri, 1 Jun 2018 20:34:10 +0100 +Subject: ANDROID: sched/fair: Attempt to improve throughput + for asym cap systems + +In some systems the capacity and group weights line up to defeat all the +small imbalance correction conditions in fix_small_imbalance, which can +cause bad task placement. Add a new condition if the existing code can't +see anything to fix: + +If we have asymmetric capacity, and there are more tasks than CPUs in +the busiest group *and* there are less tasks than CPUs in the local group +then we try to pull something. There could be transient small tasks which +prevent this from working, but on the whole it is beneficial for those +systems with inconvenient capacity/cluster size relationships. + +Change-Id: Icf81cde215c082a61f816534b7990ccb70aee409 +Signed-off-by: Chris Redpath +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index df279e422001..1962e68fcf60 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8425,7 +8425,22 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) + capa_move /= SCHED_CAPACITY_SCALE; + + /* Move if we gain throughput */ +- if (capa_move > capa_now) ++ if (capa_move > capa_now) { ++ env->imbalance = busiest->load_per_task; ++ return; ++ } ++ ++ /* We can't see throughput improvement with the load-based ++ * method, but it is possible depending upon group size and ++ * capacity range that there might still be an underutilized ++ * cpu available in an asymmetric capacity system. Do one last ++ * check just in case. ++ */ ++ if (env->sd->flags & SD_ASYM_CPUCAPACITY && ++ busiest->group_type == group_overloaded && ++ busiest->sum_nr_running > busiest->group_weight && ++ local->sum_nr_running < local->group_weight && ++ local->group_capacity < busiest->group_capacity) + env->imbalance = busiest->load_per_task; + } + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch b/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch new file mode 100644 index 000000000000..c5271f2f45ba --- /dev/null +++ b/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch @@ -0,0 +1,129 @@ +From 760b82c9b88d2c8125abfc5f732cc3cd460b2a54 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Wed, 27 Feb 2019 11:21:24 +0000 +Subject: ANDROID: sched/fair: Bias EAS placement for latency + +Add to find_energy_efficient_cpu() a latency sensitive case which mimics +what was done for prefer-idle in android-4.19 and before (see [1] for +reference). + +This isn't strictly equivalent to the legacy algorithm but comes real +close, and isn't very invasive. Overall, the idea is to select the +biggest idle CPU we can find for latency-sensitive boosted tasks, and +the smallest CPU where the can fit for latency-sensitive non-boosted +tasks. + +The main differences with the legacy behaviour are the following: + + 1. the policy for 'prefer idle' when there isn't a single idle CPU in + the system is simpler now. We just pick the CPU with the highest + spare capacity; + + 2. the cstate awareness is implemented by minimizing the exit latency + rather than the idle state index. This is how it is done in the slow + path (find_idlest_group_cpu()), it doesn't require us to keep hooks + into CPUIdle, and should actually be better because what we want is + a CPU that can wake up quickly; + + 3. non-latency-sensitive tasks just use the standard mainline + energy-aware wake-up path, which decides the placement using the + Energy Model; + + 4. the 'boosted' and 'latency_sensitive' attributes of a task come from + util_clamp (which now replaces schedtune). + +[1] https://android.googlesource.com/kernel/common.git/+/c27c56105dcaaae54ecc39ef33fbfac87a1486fc + +Change-Id: Ia58516906e9cb5abe08385a8cd088097043d8703 +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 4012266f4f64..9b43520dc248 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -6340,8 +6340,13 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy + { + unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; + struct root_domain *rd = cpu_rq(smp_processor_id())->rd; ++ int max_spare_cap_cpu_ls = prev_cpu, best_idle_cpu = -1; ++ unsigned long max_spare_cap_ls = 0, target_cap; + unsigned long cpu_cap, util, base_energy = 0; ++ bool boosted, latency_sensitive = false; ++ unsigned int min_exit_lat = UINT_MAX; + int cpu, best_energy_cpu = prev_cpu; ++ struct cpuidle_state *idle; + struct sched_domain *sd; + struct perf_domain *pd; + +@@ -6370,6 +6375,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy + if (!task_util_est(p)) + goto unlock; + ++ latency_sensitive = uclamp_latency_sensitive(p); ++ boosted = uclamp_boosted(p); ++ target_cap = boosted ? 0 : ULONG_MAX; ++ + for (; pd; pd = pd->next) { + unsigned long cur_delta, spare_cap, max_spare_cap = 0; + unsigned long base_energy_pd; +@@ -6394,7 +6403,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy + continue; + + /* Always use prev_cpu as a candidate. */ +- if (cpu == prev_cpu) { ++ if (!latency_sensitive && cpu == prev_cpu) { + prev_delta = compute_energy(p, prev_cpu, pd); + prev_delta -= base_energy_pd; + best_delta = min(best_delta, prev_delta); +@@ -6409,10 +6418,34 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy + max_spare_cap = spare_cap; + max_spare_cap_cpu = cpu; + } ++ ++ if (!latency_sensitive) ++ continue; ++ ++ if (idle_cpu(cpu)) { ++ cpu_cap = capacity_orig_of(cpu); ++ if (boosted && cpu_cap < target_cap) ++ continue; ++ if (!boosted && cpu_cap > target_cap) ++ continue; ++ idle = idle_get_state(cpu_rq(cpu)); ++ if (idle && idle->exit_latency > min_exit_lat && ++ cpu_cap == target_cap) ++ continue; ++ ++ if (idle) ++ min_exit_lat = idle->exit_latency; ++ target_cap = cpu_cap; ++ best_idle_cpu = cpu; ++ } else if (spare_cap > max_spare_cap_ls) { ++ max_spare_cap_ls = spare_cap; ++ max_spare_cap_cpu_ls = cpu; ++ } + } + + /* Evaluate the energy impact of using this CPU. */ +- if (max_spare_cap_cpu >= 0 && max_spare_cap_cpu != prev_cpu) { ++ if (!latency_sensitive && max_spare_cap_cpu >= 0 && ++ max_spare_cap_cpu != prev_cpu) { + cur_delta = compute_energy(p, max_spare_cap_cpu, pd); + cur_delta -= base_energy_pd; + if (cur_delta < best_delta) { +@@ -6424,6 +6457,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy + unlock: + rcu_read_unlock(); + ++ if (latency_sensitive) ++ return best_idle_cpu >= 0 ? best_idle_cpu : max_spare_cap_cpu_ls; ++ + /* + * Pick the best CPU if prev_cpu cannot be used, or if it saves at + * least 6% of the energy used by prev_cpu. +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would.patch b/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would.patch new file mode 100644 index 000000000000..51e16992409f --- /dev/null +++ b/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would.patch @@ -0,0 +1,60 @@ +From a7455f8123479ddcad3ff7b366ce143cb78a9ae3 Mon Sep 17 00:00:00 2001 +From: Chris Redpath +Date: Tue, 5 Jun 2018 11:47:57 +0100 +Subject: ANDROID: sched/fair: Don't balance misfits if it + would overload local group + +When load balancing in a system with misfit tasks present, if we always +pull a misfit task to the local group this can lead to pulling a running +task from a smaller capacity CPUs to a bigger CPU which is busy. In this +situation, the pulled task is likely not to get a chance to run before +an idle balance on another small CPU pulls it back. This penalises the +pulled task as it is stopped for a short amount of time and then likely +relocated to a different CPU (since the original CPU just did a NEWLY_IDLE +balance and reset the periodic interval). + +If we only do this unconditionally for NEWLY_IDLE balance, we can be +sure that any tasks and load which are present on the local group are +related to short-running tasks which we are happy to displace for a +longer running task in a system with misfit tasks present. + +However, other balance types should only pull a task if we think +that the local group is underutilized - checking the number of tasks +gives us a conservative estimate here since if they were short tasks +we would have been doing NEWLY_IDLE balances instead. + +Change-Id: I710add1ab1139482620b6addc8370ad194791beb +Signed-off-by: Chris Redpath +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 1962e68fcf60..af23c63eca32 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8509,8 +8509,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s + (sds->avg_load - local->avg_load) * local->group_capacity + ) / SCHED_CAPACITY_SCALE; + +- /* Boost imbalance to allow misfit task to be balanced. */ +- if (busiest->group_type == group_misfit_task) { ++ /* Boost imbalance to allow misfit task to be balanced. ++ * Always do this if we are doing a NEWLY_IDLE balance ++ * on the assumption that any tasks we have must not be ++ * long-running (and hence we cannot rely upon load). ++ * However if we are not idle, we should assume the tasks ++ * we have are longer running and not override load-based ++ * calculations above unless we are sure that the local ++ * group is underutilized. ++ */ ++ if (busiest->group_type == group_misfit_task && ++ (env->idle == CPU_NEWLY_IDLE || ++ local->sum_nr_running < local->group_weight)) { + env->imbalance = max_t(long, env->imbalance, + busiest->group_misfit_task_load); + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_en.patch b/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_en.patch new file mode 100644 index 000000000000..8dc9c3a38e6a --- /dev/null +++ b/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_en.patch @@ -0,0 +1,66 @@ +From b61876ed122f816660fe49e0de1b7ee4891deaa2 Mon Sep 17 00:00:00 2001 +From: Patrick Bellasi +Date: Tue, 18 Dec 2018 10:31:30 +0000 +Subject: ANDROID: sched/fair: EAS: Add uclamp support to + find_energy_efficient_cpu() + +Utilization clamping can be used to boost the utilization of small tasks +or cap that of big tasks. Thus, one of its possible usages is to bias +tasks placement to "promote" small tasks on higher capacity (less energy +efficient) CPUs or "constraint" big tasks on small capacity (more energy +efficient) CPUs. + +When the Energy Aware Scheduler (EAS) looks for the most energy +efficient CPU to run a task on, it currently considers only the +effective utiliation estimated for a task. + +Fix this by adding an additional check to skip CPUs which capacity is +smaller then the task clamped utilization. + +Change-Id: I43fa6fa27e27c1eb5272c6a45d1a6a5b0faae1aa +Signed-off-by: Patrick Bellasi +Cc: Ingo Molnar +Cc: Peter Zijlstra +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 83ab35e2374f..c80cf449f9fb 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -6026,6 +6026,19 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) + return target; + } + ++static unsigned int uclamp_task_util(struct task_struct *p) ++{ ++#ifdef CONFIG_UCLAMP_TASK ++ unsigned int min_util = uclamp_eff_value(p, UCLAMP_MIN); ++ unsigned int max_util = uclamp_eff_value(p, UCLAMP_MAX); ++ unsigned int est_util = task_util_est(p); ++ ++ return clamp(est_util, min_util, max_util); ++#else ++ return task_util_est(p); ++#endif ++} ++ + /** + * Amount of capacity of a CPU that is (estimated to be) used by CFS tasks + * @cpu: the CPU to get the utilization of +@@ -6370,6 +6383,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + if (!fits_capacity(util, cpu_cap)) + continue; + ++ /* Skip CPUs which do not fit task requirements */ ++ if (cpu_cap < uclamp_task_util(p)) ++ continue; ++ + /* Always use prev_cpu as a candidate. */ + if (cpu == prev_cpu) { + prev_delta = compute_energy(p, prev_cpu, pd); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max.patch b/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max.patch new file mode 100644 index 000000000000..f993bf5d0220 --- /dev/null +++ b/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max.patch @@ -0,0 +1,83 @@ +From 27ad2abc032bff8761bd0dd03f6e90d0bbd9e3e3 Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann +Date: Thu, 10 May 2018 15:48:06 +0100 +Subject: ANDROID: sched/fair: add arch scaling function for + max frequency capping + +To be able to scale the cpu capacity by this factor introduce a call to +the new arch scaling function arch_scale_max_freq_capacity() in +update_cpu_capacity() and provide a default implementation which returns +SCHED_CAPACITY_SCALE. + +Another subsystem (e.g. cpufreq) or architectural or platform specific +code can overwrite this default implementation, exactly as for frequency +and cpu invariance. It has to be enabled by the arch by defining +arch_scale_max_freq_capacity to the actual implementation. + +Change-Id: I770a8b1f4f7340e9e314f71c64a765bf880f4b4d +Signed-off-by: Ionela Voinescu +Signed-off-by: Dietmar Eggemann +( Fixed conflict with scaling against the PELT-based scale_rt_capacity ) +Signed-off-by: Quentin Perret +--- + kernel/sched/fair.c | 12 ++++++++---- + kernel/sched/sched.h | 9 +++++++++ + 2 files changed, 17 insertions(+), 4 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index baefb5ebc85e..fee99f8cb193 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -7725,10 +7725,9 @@ static inline void init_sd_lb_stats(struct sd_lb_stats *sds) + }; + } + +-static unsigned long scale_rt_capacity(struct sched_domain *sd, int cpu) ++static unsigned long scale_rt_capacity(int cpu, unsigned long max) + { + struct rq *rq = cpu_rq(cpu); +- unsigned long max = arch_scale_cpu_capacity(cpu); + unsigned long used, free; + unsigned long irq; + +@@ -7750,10 +7749,15 @@ static unsigned long scale_rt_capacity(struct sched_domain *sd, int cpu) + + static void update_cpu_capacity(struct sched_domain *sd, int cpu) + { +- unsigned long capacity = scale_rt_capacity(sd, cpu); ++ unsigned long capacity = arch_scale_cpu_capacity(cpu); + struct sched_group *sdg = sd->groups; + +- cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu); ++ cpu_rq(cpu)->cpu_capacity_orig = capacity; ++ ++ capacity *= arch_scale_max_freq_capacity(sd, cpu); ++ capacity >>= SCHED_CAPACITY_SHIFT; ++ ++ capacity = scale_rt_capacity(cpu, capacity); + + if (!capacity) + capacity = 1; +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 0db2c1b3361e..f0b6e3ab2c96 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -1961,6 +1961,15 @@ unsigned long arch_scale_freq_capacity(int cpu) + } + #endif + ++#ifndef arch_scale_max_freq_capacity ++struct sched_domain; ++static __always_inline ++unsigned long arch_scale_max_freq_capacity(struct sched_domain *sd, int cpu) ++{ ++ return SCHED_CAPACITY_SCALE; ++} ++#endif ++ + #ifdef CONFIG_SMP + #ifdef CONFIG_PREEMPTION + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch b/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch new file mode 100644 index 000000000000..afd686f8a59b --- /dev/null +++ b/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch @@ -0,0 +1,5182 @@ +From 273959637936f73df12b9f7f081f3f09cf8695b7 Mon Sep 17 00:00:00 2001 +From: Daniel Campello +Date: Mon, 20 Jul 2015 16:23:50 -0700 +Subject: ANDROID: sdcardfs: Add sdcardfs filesystem + +Bug: 11118565 +Bug: 27915347 +Bug: 27992761 +Bug: 28024488 +Bug: 30013843 +Bug: 30954918 +Bug: 34133558 +Bug: 34262585 +Bug: 34542611 +Bug: 34691169 +Bug: 34723223 +Bug: 35307857 +Bug: 35331000 +Bug: 35633782 +Bug: 35643557 +Bug: 35666680 +bug: 35766959 +Bug: 35766959 +Bug: 35848445 +Bug: 36004503 +Bug: 36007653 +Bug: 36138424 +Bug: 36160015 +Bug: 37193650 +Bug: 37231161 +Bug: 37488099 +Bug: 37516160 +Bug: 38045152 +Bug: 38117720 +Bug: 38502532 +Bug: 62390017 +Bug: 63245673 +Bug: 63260873 +Bug: 63785372 +Bug: 64672411 +Bug: 70278506 +Bug: 72007585 +Bug: 73055997 +Bug: 73287721 +Bug: 75987238 +Bug: 77923821 +Bug: 78262592 +Bug: 111641492 +Bug: 111642636 +Bug: 111860541 +Change-Id: Ic1e01e602ce335d97342be54f3da0c5c65c087cc +Signed-off-by: Daniel Rosenberg +[astrachan: Folded the following changes into this patch: + 903cea7ab0b2 ("ANDROID: Included sdcardfs source code for kernel 3.0") + 612a725e3d97 ("ANDROID: Port of sdcardfs to 4.4") + e4187c55208b ("ANDROID: Changed type-casting in packagelist management") + cf76072a5cd8 ("ANDROID: sdcardfs: Bring up to date with Android M permissions:") + a43aa502c608 ("ANDROID: sdcardfs: Add support for d_canonical_path") + d8fefbf85af2 ("ANDROID: sdcardfs: remove effectless config option") + 416677409336 ("ANDROID: sdcardfs: Remove unused code") + 8e49a570d351 ("ANDROID: sdcardfs: remove unneeded __init and __exit") + 40ee0e93f1d7 ("ANDROID: sdcardfs: Truncate packages_gid.list on overflow") + b1d9602aa3fe ("ANDROID: sdcardfs: fix itnull.cocci warnings") + 60a177f5a167 ("ANDROID: sdcardfs: override umask on mkdir and create") + efb3d2695203 ("ANDROID: sdcardfs: Check for other cases on path lookup") + 0da87f63666f ("ANDROID: sdcardfs: Fix locking for permission fix up") + 75b93060655e ("ANDROID: sdcardfs: Switch package list to RCU") + 657b0a00f497 ("ANDROID: sdcardfs: Added top to sdcardfs_inode_info") + 5008d91cba25 ("ANDROID: sdcardfs: fix external storage exporting incorrect uid") + e06c452d0d07 ("ANDROID: sdcardfs: Move directory unlock before touch") + 72e5443a2816 ("ANDROID: sdcardfs: User new permission2 functions") + ae8be7da556d ("ANDROID: sdcardfs: Add gid and mask to private mount data") + 151a3efe57a6 ("ANDROID: sdcardfs: Use per mount permissions") + cff865a370f3 ("ANDROID: sdcardfs: Switch ->d_inode to d_inode()") + 065ac66804bf ("ANDROID: sdcardfs: Fix locking issue with permision fix up") + 31ea603eb3c4 ("ANDROID: sdcardfs: use wrappers to access i_mutex") + c25c2f5018a2 ("ANDROID: sdcardfs: add parent pointer into dentry name hash") + 58616bb4ec68 ("ANDROID: sdcardfs: get rid of 'parent' argument of ->d_compare()") + 1654d7ffdd20 ("ANDROID: sdcardfs: Propagate dentry down to inode_change_ok()") + 39335cac1d2f ("ANDROID: sdcardfs: make it use new .rename i_op") + 7622bb3fcc79 ("ANDROID: sdcardfs: eliminate the offset argument to ->direct_IO") + 843bd7295ee0 ("ANDROID: sdcardfs: Allow non-owners to touch") + e3d74804d174 ("ANDROID: sdcardfs: Refactor configfs interface") + 5833eda87a72 ("ANDROID: sdcardfs: add support for user permission isolation") + d83fb1f41dd4 ("ANDROID: sdcardfs: Remove redundant operation") + 8767af17c0e5 ("ANDROID: sdcardfs: Add GID Derivation to sdcardfs") + 7119d96ad3ee ("ANDROID: sdcardfs: switch to full_name_hash and qstr") + 778e02a54859 ("ANDROID: sdcardfs: Switch strcasecmp for internal call") + cd4965d04404 ("ANDROID: sdcardfs: Fix incorrect hash") + 40a2ee053505 ("ANDROID: sdcardfs: Add missing path_put") + da5342bac57a ("ANDROID: sdcardfs: Don't bother deleting freelist") + c91857b01e05 ("ANDROID: sdcardfs: implement vm_ops->page_mkwrite") + f62b3906044b ("ANDROID: sdcardfs: support direct-IO (DIO) operations") + c2e216d36d63 ("ANDROID: sdcardfs: Fix case insensitive lookup") + 57b92ab6f774 ("ANDROID: sdcardfs: rate limit warning print") + 8534cee39a81 ("ANDROID: sdcardfs: Replace get/put with d_lock") + 156085b2fccf ("ANDROID: sdcardfs: Use spin_lock_nested") + 8a260cabac4e ("ANDROID: sdcardfs: Switch to internal case insensitive compare") + a8d51569573c ("ANDROID: sdcardfs: Use d_invalidate instead of drop_recurisve") + 932a6071de63 ("ANDROID: sdcardfs: Get the blocksize from the lower fs") + 0ad4c0f87527 ("ANDROID: sdcardfs: declare MODULE_ALIAS_FS") + b97c83b5b683 ("ANDROID: sdcardfs: Use case insensitive hash function") + 9920dfb08265 ("ANDROID: sdcardfs: move path_put outside of spinlock") + f9a25348b233 ("ANDROID: sdcardfs: Remove uninformative prints") + 720d9030bea1 ("ANDROID: sdcardfs: Fix gid issue") + 4cbb7fa6e66c ("ANDROID: sdcardfs: correct order of descriptors") + 6cff6cc301ed ("ANDROID: sdcardfs: Fix formatting") + ac2a40412e26 ("ANDROID: sdcardfs: Fix style issues with comments") + 2212bb8ec064 ("ANDROID: sdcardfs: remove unneeded null check") + 4c1a0add8d21 ("ANDROID: sdcardfs: Use pr_[...] instead of printk") + 74535fe211ac ("ANDROID: sdcardfs: Use to kstrout") + e6cf8dffd014 ("ANDROID: sdcardfs: Use seq_puts over seq_printf") + 2b1ac93a90b6 ("ANDROID: sdcardfs: Fix style issues in macros") + bab6d117426f ("ANDROID: sdcardfs: remove unnecessary call to do_munmap") + 1c0bf09f19b6 ("ANDROID: sdcardfs: copy lower inode attributes in ->ioctl") + 42f3db55942b ("ANDROID: sdcardfs: fix ->llseek to update upper and lower offset") + 97ad6205055e ("ANDROID: sdcardfs: add read_iter/write_iter opeations") + be9abc81332b ("ANDROID: sdcardfs: use d_splice_alias") + 4e90114cb1b4 ("ANDROID: sdcardfs: update module info") + 0e1f7ab14924 ("ANDROID: sdcardfs: Directly pass lower file for mmap") + 28be4beb43f9 ("ANDROID: sdcardfs: Change cache GID value") + 9fc2c452aefe ("ANDROID: sdcardfs: ->iget fixes") + 9bb72cf15cbc ("ANDROID: sdcardfs: Don't do d_add for lower fs") + 1bc21a04c11b ("ANDROID: sdcardfs: Don't complain in fixup_lower_ownership") + 0fb5b10b28a9 ("ANDROID: sdcardfs: Use filesystem specific hash") + 30e2f0aadce2 ("ANDROID: sdcardfs: Copy meta-data from lower inode") + f748c7053194 ("ANDROID: sdcardfs: Avoid setting GIDs outside of valid ranges") + 3d38f08bacdb ("ANDROID: sdcardfs: Call lower fs's revalidate") + 2d1f1c203978 ("ANDROID: sdcardfs: Don't iput if we didn't igrab") + 857fc5e717fc ("ANDROID: sdcardfs: fix sdcardfs_destroy_inode for the inode RCU approach") + 4fceeccf1d23 ("ANDROID: sdcardfs: Move top to its own struct") + f51470044a15 ("ANDROID: sdcardfs: Check for NULL in revalidate") + 8c7f6c97ac81 ("ANDROID: sdcardfs: d_splice_alias can return error values") + 17da01b37d61 ("ANDROID: sdcardfs: remove dead function open_flags_to_access_mode()") + 16662dd604be ("ANDROID: sdcardfs: use mount_nodev and fix a issue in sdcardfs_kill_sb") + 43c0dca6039a ("ANDROID: sdcardfs: Remove unnecessary lock") + 48960c25cdc1 ("ANDROID: sdcardfs: override credential for ioctl to lower fs") + 5d6410b9a88d ("ANDROID: Sdcardfs: Move gid derivation under flag") + c7dd98431f83 ("ANDROID: sdcardfs: Add default_normal option") + db9bf31a5d86 ("ANDROID: sdcardfs: port to 4.14") + c70c9d1e82d2 ("ANDROID: sdcardfs: Use lower getattr times/size") + 04e961477d62 ("ANDROID: sdcardfs: Protect set_top") + 1ed04b79d281 ("ANDROID: sdcardfs: Hold i_mutex for i_size_write") + 77f52fc10982 ("ANDROID: sdcardfs: Set num in extension_details during make_item") + d71596efa247 ("ANDROID: sdcardfs: fix lock issue on 32 bit/SMP architectures") + ee6b07fced4a ("ANDROID: sdcardfs: Fix sdcardfs to stop creating cases-sensitive duplicate entries.") + ce12807d5b75 ("ANDROID: sdcardfs: Check for private data earlier") + c080450304cd ("ANDROID: sdcardfs: d_make_root calls iput") + 900e77796781 ("ANDROID: sdcardfs: Set s_root to NULL after putting") + 49092e89ffa4 ("ANDROID: sdcardfs: Don't d_drop in d_revalidate") + e1f978bc9b9c ("ANDROID: sdcardfs: fix potential crash when reserved_mb is not zero") + faa148eaf8ed ("ANDROID: sdcardfs: Check stacked filesystem depth") + 6edd721e972c ("ANDROID: sdcardfs: Don't use OVERRIDE_CRED macro") + 11ca578b4336 ("ANDROID: sdcardfs: Change current->fs under lock") + 83dea6ba6ea7 ("ANDROID: sdcardfs: Use inode iversion helpers") + 12064f3a794e ("ANDROID: sdcardfs: Add option to drop unused dentries") + d9fe221bbf84 ("ANDROID: sdcardfs: Add sandbox") + f544ad0b1547 ("ANDROID: sdcardfs: Add option to not link obb")] +Signed-off-by: Alistair Strachan +[drosen: folded in e6e368c99975 ("fs: sdcardfs: Add missing option to show_options")] +--- + fs/Kconfig | 1 + + fs/Makefile | 1 + + fs/sdcardfs/Kconfig | 13 + + fs/sdcardfs/Makefile | 7 + + fs/sdcardfs/dentry.c | 196 +++++++++ + fs/sdcardfs/derived_perm.c | 477 ++++++++++++++++++++ + fs/sdcardfs/file.c | 467 ++++++++++++++++++++ + fs/sdcardfs/inode.c | 821 ++++++++++++++++++++++++++++++++++ + fs/sdcardfs/lookup.c | 470 ++++++++++++++++++++ + fs/sdcardfs/main.c | 454 +++++++++++++++++++ + fs/sdcardfs/mmap.c | 87 ++++ + fs/sdcardfs/multiuser.h | 53 +++ + fs/sdcardfs/packagelist.c | 882 +++++++++++++++++++++++++++++++++++++ + fs/sdcardfs/sdcardfs.h | 662 ++++++++++++++++++++++++++++ + fs/sdcardfs/super.c | 297 +++++++++++++ + 15 files changed, 4888 insertions(+) + create mode 100644 fs/sdcardfs/Kconfig + create mode 100644 fs/sdcardfs/Makefile + create mode 100644 fs/sdcardfs/dentry.c + create mode 100644 fs/sdcardfs/derived_perm.c + create mode 100644 fs/sdcardfs/file.c + create mode 100644 fs/sdcardfs/inode.c + create mode 100644 fs/sdcardfs/lookup.c + create mode 100644 fs/sdcardfs/main.c + create mode 100644 fs/sdcardfs/mmap.c + create mode 100644 fs/sdcardfs/multiuser.h + create mode 100644 fs/sdcardfs/packagelist.c + create mode 100644 fs/sdcardfs/sdcardfs.h + create mode 100644 fs/sdcardfs/super.c + +diff --git a/fs/Kconfig b/fs/Kconfig +index bfb1c6095c7a7..fd08690573d0e 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -241,6 +241,7 @@ source "fs/orangefs/Kconfig" + source "fs/adfs/Kconfig" + source "fs/affs/Kconfig" + source "fs/ecryptfs/Kconfig" ++source "fs/sdcardfs/Kconfig" + source "fs/hfs/Kconfig" + source "fs/hfsplus/Kconfig" + source "fs/befs/Kconfig" +diff --git a/fs/Makefile b/fs/Makefile +index d60089fd689bc..b54f564755dcb 100644 +--- a/fs/Makefile ++++ b/fs/Makefile +@@ -86,6 +86,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/ + obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ + obj-$(CONFIG_HFS_FS) += hfs/ + obj-$(CONFIG_ECRYPT_FS) += ecryptfs/ ++obj-$(CONFIG_SDCARD_FS) += sdcardfs/ + obj-$(CONFIG_VXFS_FS) += freevxfs/ + obj-$(CONFIG_NFS_FS) += nfs/ + obj-$(CONFIG_EXPORTFS) += exportfs/ +diff --git a/fs/sdcardfs/Kconfig b/fs/sdcardfs/Kconfig +new file mode 100644 +index 0000000000000..a1c103316ac79 +--- /dev/null ++++ b/fs/sdcardfs/Kconfig +@@ -0,0 +1,13 @@ ++config SDCARD_FS ++ tristate "sdcard file system" ++ depends on CONFIGFS_FS ++ default n ++ help ++ Sdcardfs is based on Wrapfs file system. ++ ++config SDCARD_FS_FADV_NOACTIVE ++ bool "sdcardfs fadvise noactive support" ++ depends on FADV_NOACTIVE ++ default y ++ help ++ Sdcardfs supports fadvise noactive mode. +diff --git a/fs/sdcardfs/Makefile b/fs/sdcardfs/Makefile +new file mode 100644 +index 0000000000000..b84fbb2b45a47 +--- /dev/null ++++ b/fs/sdcardfs/Makefile +@@ -0,0 +1,7 @@ ++SDCARDFS_VERSION="0.1" ++ ++EXTRA_CFLAGS += -DSDCARDFS_VERSION=\"$(SDCARDFS_VERSION)\" ++ ++obj-$(CONFIG_SDCARD_FS) += sdcardfs.o ++ ++sdcardfs-y := dentry.o file.o inode.o main.o super.o lookup.o mmap.o packagelist.o derived_perm.o +diff --git a/fs/sdcardfs/dentry.c b/fs/sdcardfs/dentry.c +new file mode 100644 +index 0000000000000..cb573f1efbfc4 +--- /dev/null ++++ b/fs/sdcardfs/dentry.c +@@ -0,0 +1,196 @@ ++/* ++ * fs/sdcardfs/dentry.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#include "linux/ctype.h" ++ ++/* ++ * returns: -ERRNO if error (returned to user) ++ * 0: tell VFS to invalidate dentry ++ * 1: dentry is valid ++ */ ++static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ int err = 1; ++ struct path parent_lower_path, lower_path; ++ struct dentry *parent_dentry = NULL; ++ struct dentry *parent_lower_dentry = NULL; ++ struct dentry *lower_cur_parent_dentry = NULL; ++ struct dentry *lower_dentry = NULL; ++ struct inode *inode; ++ struct sdcardfs_inode_data *data; ++ ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ ++ spin_lock(&dentry->d_lock); ++ if (IS_ROOT(dentry)) { ++ spin_unlock(&dentry->d_lock); ++ return 1; ++ } ++ spin_unlock(&dentry->d_lock); ++ ++ /* check uninitialized obb_dentry and ++ * whether the base obbpath has been changed or not ++ */ ++ if (is_obbpath_invalid(dentry)) { ++ return 0; ++ } ++ ++ parent_dentry = dget_parent(dentry); ++ sdcardfs_get_lower_path(parent_dentry, &parent_lower_path); ++ sdcardfs_get_real_lower(dentry, &lower_path); ++ parent_lower_dentry = parent_lower_path.dentry; ++ lower_dentry = lower_path.dentry; ++ lower_cur_parent_dentry = dget_parent(lower_dentry); ++ ++ if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) { ++ err = lower_dentry->d_op->d_revalidate(lower_dentry, flags); ++ if (err == 0) { ++ goto out; ++ } ++ } ++ ++ spin_lock(&lower_dentry->d_lock); ++ if (d_unhashed(lower_dentry)) { ++ spin_unlock(&lower_dentry->d_lock); ++ err = 0; ++ goto out; ++ } ++ spin_unlock(&lower_dentry->d_lock); ++ ++ if (parent_lower_dentry != lower_cur_parent_dentry) { ++ err = 0; ++ goto out; ++ } ++ ++ if (dentry < lower_dentry) { ++ spin_lock(&dentry->d_lock); ++ spin_lock_nested(&lower_dentry->d_lock, DENTRY_D_LOCK_NESTED); ++ } else { ++ spin_lock(&lower_dentry->d_lock); ++ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); ++ } ++ ++ if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) { ++ err = 0; ++ } ++ ++ if (dentry < lower_dentry) { ++ spin_unlock(&lower_dentry->d_lock); ++ spin_unlock(&dentry->d_lock); ++ } else { ++ spin_unlock(&dentry->d_lock); ++ spin_unlock(&lower_dentry->d_lock); ++ } ++ if (!err) ++ goto out; ++ ++ /* If our top's inode is gone, we may be out of date */ ++ inode = igrab(d_inode(dentry)); ++ if (inode) { ++ data = top_data_get(SDCARDFS_I(inode)); ++ if (!data || data->abandoned) { ++ err = 0; ++ } ++ if (data) ++ data_put(data); ++ iput(inode); ++ } ++ ++out: ++ dput(parent_dentry); ++ dput(lower_cur_parent_dentry); ++ sdcardfs_put_lower_path(parent_dentry, &parent_lower_path); ++ sdcardfs_put_real_lower(dentry, &lower_path); ++ return err; ++} ++ ++/* 1 = delete, 0 = cache */ ++static int sdcardfs_d_delete(const struct dentry *d) ++{ ++ return SDCARDFS_SB(d->d_sb)->options.nocache ? 1 : 0; ++} ++ ++static void sdcardfs_d_release(struct dentry *dentry) ++{ ++ if (!dentry || !dentry->d_fsdata) ++ return; ++ /* release and reset the lower paths */ ++ if (has_graft_path(dentry)) ++ sdcardfs_put_reset_orig_path(dentry); ++ sdcardfs_put_reset_lower_path(dentry); ++ free_dentry_private_data(dentry); ++} ++ ++static int sdcardfs_hash_ci(const struct dentry *dentry, ++ struct qstr *qstr) ++{ ++ /* ++ * This function is copy of vfat_hashi. ++ * FIXME Should we support national language? ++ * Refer to vfat_hashi() ++ * struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; ++ */ ++ const unsigned char *name; ++ unsigned int len; ++ unsigned long hash; ++ ++ name = qstr->name; ++ len = qstr->len; ++ ++ hash = init_name_hash(dentry); ++ while (len--) ++ hash = partial_name_hash(tolower(*name++), hash); ++ qstr->hash = end_name_hash(hash); ++ ++ return 0; ++} ++ ++/* ++ * Case insensitive compare of two vfat names. ++ */ ++static int sdcardfs_cmp_ci(const struct dentry *dentry, ++ unsigned int len, const char *str, const struct qstr *name) ++{ ++ /* FIXME Should we support national language? */ ++ ++ if (name->len == len) { ++ if (str_n_case_eq(name->name, str, len)) ++ return 0; ++ } ++ return 1; ++} ++ ++static void sdcardfs_canonical_path(const struct path *path, ++ struct path *actual_path) ++{ ++ sdcardfs_get_real_lower(path->dentry, actual_path); ++} ++ ++const struct dentry_operations sdcardfs_ci_dops = { ++ .d_revalidate = sdcardfs_d_revalidate, ++ .d_delete = sdcardfs_d_delete, ++ .d_release = sdcardfs_d_release, ++ .d_hash = sdcardfs_hash_ci, ++ .d_compare = sdcardfs_cmp_ci, ++ .d_canonical_path = sdcardfs_canonical_path, ++}; ++ +diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c +new file mode 100644 +index 0000000000000..78a669c8a4d62 +--- /dev/null ++++ b/fs/sdcardfs/derived_perm.c +@@ -0,0 +1,477 @@ ++/* ++ * fs/sdcardfs/derived_perm.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++ ++/* copy derived state from parent inode */ ++static void inherit_derived_state(struct inode *parent, struct inode *child) ++{ ++ struct sdcardfs_inode_info *pi = SDCARDFS_I(parent); ++ struct sdcardfs_inode_info *ci = SDCARDFS_I(child); ++ ++ ci->data->perm = PERM_INHERIT; ++ ci->data->userid = pi->data->userid; ++ ci->data->d_uid = pi->data->d_uid; ++ ci->data->under_android = pi->data->under_android; ++ ci->data->under_cache = pi->data->under_cache; ++ ci->data->under_obb = pi->data->under_obb; ++} ++ ++/* helper function for derived state */ ++void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid, ++ uid_t uid) ++{ ++ struct sdcardfs_inode_info *info = SDCARDFS_I(inode); ++ ++ info->data->perm = perm; ++ info->data->userid = userid; ++ info->data->d_uid = uid; ++ info->data->under_android = false; ++ info->data->under_cache = false; ++ info->data->under_obb = false; ++} ++ ++/* While renaming, there is a point where we want the path from dentry, ++ * but the name from newdentry ++ */ ++void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, ++ const struct qstr *name) ++{ ++ struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry)); ++ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); ++ struct sdcardfs_inode_data *parent_data = parent_info->data; ++ appid_t appid; ++ unsigned long user_num; ++ int err; ++ struct qstr q_Android = QSTR_LITERAL("Android"); ++ struct qstr q_data = QSTR_LITERAL("data"); ++ struct qstr q_sandbox = QSTR_LITERAL("sandbox"); ++ struct qstr q_obb = QSTR_LITERAL("obb"); ++ struct qstr q_media = QSTR_LITERAL("media"); ++ struct qstr q_cache = QSTR_LITERAL("cache"); ++ ++ /* By default, each inode inherits from its parent. ++ * the properties are maintained on its private fields ++ * because the inode attributes will be modified with that of ++ * its lower inode. ++ * These values are used by our custom permission call instead ++ * of using the inode permissions. ++ */ ++ ++ inherit_derived_state(d_inode(parent), d_inode(dentry)); ++ ++ /* Files don't get special labels */ ++ if (!S_ISDIR(d_inode(dentry)->i_mode)) { ++ set_top(info, parent_info); ++ return; ++ } ++ /* Derive custom permissions based on parent and current node */ ++ switch (parent_data->perm) { ++ case PERM_INHERIT: ++ case PERM_ANDROID_PACKAGE_CACHE: ++ set_top(info, parent_info); ++ break; ++ case PERM_PRE_ROOT: ++ /* Legacy internal layout places users at top level */ ++ info->data->perm = PERM_ROOT; ++ err = kstrtoul(name->name, 10, &user_num); ++ if (err) ++ info->data->userid = 0; ++ else ++ info->data->userid = user_num; ++ break; ++ case PERM_ROOT: ++ /* Assume masked off by default. */ ++ if (qstr_case_eq(name, &q_Android)) { ++ /* App-specific directories inside; let anyone traverse */ ++ info->data->perm = PERM_ANDROID; ++ info->data->under_android = true; ++ } else { ++ set_top(info, parent_info); ++ } ++ break; ++ case PERM_ANDROID: ++ if (qstr_case_eq(name, &q_data)) { ++ /* App-specific directories inside; let anyone traverse */ ++ info->data->perm = PERM_ANDROID_DATA; ++ } else if (qstr_case_eq(name, &q_sandbox)) { ++ /* App-specific directories inside; let anyone traverse */ ++ info->data->perm = PERM_ANDROID_DATA; ++ } else if (qstr_case_eq(name, &q_obb)) { ++ /* App-specific directories inside; let anyone traverse */ ++ info->data->perm = PERM_ANDROID_OBB; ++ info->data->under_obb = true; ++ /* Single OBB directory is always shared */ ++ } else if (qstr_case_eq(name, &q_media)) { ++ /* App-specific directories inside; let anyone traverse */ ++ info->data->perm = PERM_ANDROID_MEDIA; ++ } else { ++ set_top(info, parent_info); ++ } ++ break; ++ case PERM_ANDROID_OBB: ++ case PERM_ANDROID_DATA: ++ case PERM_ANDROID_MEDIA: ++ info->data->perm = PERM_ANDROID_PACKAGE; ++ appid = get_appid(name->name); ++ if (appid != 0 && !is_excluded(name->name, parent_data->userid)) ++ info->data->d_uid = ++ multiuser_get_uid(parent_data->userid, appid); ++ break; ++ case PERM_ANDROID_PACKAGE: ++ if (qstr_case_eq(name, &q_cache)) { ++ info->data->perm = PERM_ANDROID_PACKAGE_CACHE; ++ info->data->under_cache = true; ++ } ++ set_top(info, parent_info); ++ break; ++ } ++} ++ ++void get_derived_permission(struct dentry *parent, struct dentry *dentry) ++{ ++ get_derived_permission_new(parent, dentry, &dentry->d_name); ++} ++ ++static appid_t get_type(const char *name) ++{ ++ const char *ext = strrchr(name, '.'); ++ appid_t id; ++ ++ if (ext && ext[0]) { ++ ext = &ext[1]; ++ id = get_ext_gid(ext); ++ return id?:AID_MEDIA_RW; ++ } ++ return AID_MEDIA_RW; ++} ++ ++void fixup_lower_ownership(struct dentry *dentry, const char *name) ++{ ++ struct path path; ++ struct inode *inode; ++ struct inode *delegated_inode = NULL; ++ int error; ++ struct sdcardfs_inode_info *info; ++ struct sdcardfs_inode_data *info_d; ++ struct sdcardfs_inode_data *info_top; ++ perm_t perm; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ uid_t uid = sbi->options.fs_low_uid; ++ gid_t gid = sbi->options.fs_low_gid; ++ struct iattr newattrs; ++ ++ if (!sbi->options.gid_derivation) ++ return; ++ ++ info = SDCARDFS_I(d_inode(dentry)); ++ info_d = info->data; ++ perm = info_d->perm; ++ if (info_d->under_obb) { ++ perm = PERM_ANDROID_OBB; ++ } else if (info_d->under_cache) { ++ perm = PERM_ANDROID_PACKAGE_CACHE; ++ } else if (perm == PERM_INHERIT) { ++ info_top = top_data_get(info); ++ perm = info_top->perm; ++ data_put(info_top); ++ } ++ ++ switch (perm) { ++ case PERM_ROOT: ++ case PERM_ANDROID: ++ case PERM_ANDROID_DATA: ++ case PERM_ANDROID_MEDIA: ++ case PERM_ANDROID_PACKAGE: ++ case PERM_ANDROID_PACKAGE_CACHE: ++ uid = multiuser_get_uid(info_d->userid, uid); ++ break; ++ case PERM_ANDROID_OBB: ++ uid = AID_MEDIA_OBB; ++ break; ++ case PERM_PRE_ROOT: ++ default: ++ break; ++ } ++ switch (perm) { ++ case PERM_ROOT: ++ case PERM_ANDROID: ++ case PERM_ANDROID_DATA: ++ case PERM_ANDROID_MEDIA: ++ if (S_ISDIR(d_inode(dentry)->i_mode)) ++ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); ++ else ++ gid = multiuser_get_uid(info_d->userid, get_type(name)); ++ break; ++ case PERM_ANDROID_OBB: ++ gid = AID_MEDIA_OBB; ++ break; ++ case PERM_ANDROID_PACKAGE: ++ if (uid_is_app(info_d->d_uid)) ++ gid = multiuser_get_ext_gid(info_d->d_uid); ++ else ++ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); ++ break; ++ case PERM_ANDROID_PACKAGE_CACHE: ++ if (uid_is_app(info_d->d_uid)) ++ gid = multiuser_get_ext_cache_gid(info_d->d_uid); ++ else ++ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); ++ break; ++ case PERM_PRE_ROOT: ++ default: ++ break; ++ } ++ ++ sdcardfs_get_lower_path(dentry, &path); ++ inode = d_inode(path.dentry); ++ if (d_inode(path.dentry)->i_gid.val != gid || d_inode(path.dentry)->i_uid.val != uid) { ++retry_deleg: ++ newattrs.ia_valid = ATTR_GID | ATTR_UID | ATTR_FORCE; ++ newattrs.ia_uid = make_kuid(current_user_ns(), uid); ++ newattrs.ia_gid = make_kgid(current_user_ns(), gid); ++ if (!S_ISDIR(inode->i_mode)) ++ newattrs.ia_valid |= ++ ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; ++ inode_lock(inode); ++ error = security_path_chown(&path, newattrs.ia_uid, newattrs.ia_gid); ++ if (!error) ++ error = notify_change2(path.mnt, path.dentry, &newattrs, &delegated_inode); ++ inode_unlock(inode); ++ if (delegated_inode) { ++ error = break_deleg_wait(&delegated_inode); ++ if (!error) ++ goto retry_deleg; ++ } ++ if (error) ++ pr_debug("sdcardfs: Failed to touch up lower fs gid/uid for %s\n", name); ++ } ++ sdcardfs_put_lower_path(dentry, &path); ++} ++ ++static int descendant_may_need_fixup(struct sdcardfs_inode_data *data, ++ struct limit_search *limit) ++{ ++ if (data->perm == PERM_ROOT) ++ return (limit->flags & BY_USERID) ? ++ data->userid == limit->userid : 1; ++ if (data->perm == PERM_PRE_ROOT || data->perm == PERM_ANDROID) ++ return 1; ++ return 0; ++} ++ ++static int needs_fixup(perm_t perm) ++{ ++ if (perm == PERM_ANDROID_DATA || perm == PERM_ANDROID_OBB ++ || perm == PERM_ANDROID_MEDIA) ++ return 1; ++ return 0; ++} ++ ++static void __fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit, int depth) ++{ ++ struct dentry *child; ++ struct sdcardfs_inode_info *info; ++ ++ /* ++ * All paths will terminate their recursion on hitting PERM_ANDROID_OBB, ++ * PERM_ANDROID_MEDIA, or PERM_ANDROID_DATA. This happens at a depth of ++ * at most 3. ++ */ ++ WARN(depth > 3, "%s: Max expected depth exceeded!\n", __func__); ++ spin_lock_nested(&dentry->d_lock, depth); ++ if (!d_inode(dentry)) { ++ spin_unlock(&dentry->d_lock); ++ return; ++ } ++ info = SDCARDFS_I(d_inode(dentry)); ++ ++ if (needs_fixup(info->data->perm)) { ++ list_for_each_entry(child, &dentry->d_subdirs, d_child) { ++ spin_lock_nested(&child->d_lock, depth + 1); ++ if (!(limit->flags & BY_NAME) || qstr_case_eq(&child->d_name, &limit->name)) { ++ if (d_inode(child)) { ++ get_derived_permission(dentry, child); ++ fixup_tmp_permissions(d_inode(child)); ++ spin_unlock(&child->d_lock); ++ break; ++ } ++ } ++ spin_unlock(&child->d_lock); ++ } ++ } else if (descendant_may_need_fixup(info->data, limit)) { ++ list_for_each_entry(child, &dentry->d_subdirs, d_child) { ++ __fixup_perms_recursive(child, limit, depth + 1); ++ } ++ } ++ spin_unlock(&dentry->d_lock); ++} ++ ++void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit) ++{ ++ __fixup_perms_recursive(dentry, limit, 0); ++} ++ ++/* main function for updating derived permission */ ++inline void update_derived_permission_lock(struct dentry *dentry) ++{ ++ struct dentry *parent; ++ ++ if (!dentry || !d_inode(dentry)) { ++ pr_err("sdcardfs: %s: invalid dentry\n", __func__); ++ return; ++ } ++ /* FIXME: ++ * 1. need to check whether the dentry is updated or not ++ * 2. remove the root dentry update ++ */ ++ if (!IS_ROOT(dentry)) { ++ parent = dget_parent(dentry); ++ if (parent) { ++ get_derived_permission(parent, dentry); ++ dput(parent); ++ } ++ } ++ fixup_tmp_permissions(d_inode(dentry)); ++} ++ ++int need_graft_path(struct dentry *dentry) ++{ ++ int ret = 0; ++ struct dentry *parent = dget_parent(dentry); ++ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ struct qstr obb = QSTR_LITERAL("obb"); ++ ++ if (!sbi->options.unshared_obb && ++ parent_info->data->perm == PERM_ANDROID && ++ qstr_case_eq(&dentry->d_name, &obb)) { ++ ++ /* /Android/obb is the base obbpath of DERIVED_UNIFIED */ ++ if (!(sbi->options.multiuser == false ++ && parent_info->data->userid == 0)) { ++ ret = 1; ++ } ++ } ++ dput(parent); ++ return ret; ++} ++ ++int is_obbpath_invalid(struct dentry *dent) ++{ ++ int ret = 0; ++ struct sdcardfs_dentry_info *di = SDCARDFS_D(dent); ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dent->d_sb); ++ char *path_buf, *obbpath_s; ++ int need_put = 0; ++ struct path lower_path; ++ ++ /* check the base obbpath has been changed. ++ * this routine can check an uninitialized obb dentry as well. ++ * regarding the uninitialized obb, refer to the sdcardfs_mkdir() ++ */ ++ spin_lock(&di->lock); ++ if (di->orig_path.dentry) { ++ if (!di->lower_path.dentry) { ++ ret = 1; ++ } else { ++ path_get(&di->lower_path); ++ ++ path_buf = kmalloc(PATH_MAX, GFP_ATOMIC); ++ if (!path_buf) { ++ ret = 1; ++ pr_err("sdcardfs: fail to allocate path_buf in %s.\n", __func__); ++ } else { ++ obbpath_s = d_path(&di->lower_path, path_buf, PATH_MAX); ++ if (d_unhashed(di->lower_path.dentry) || ++ !str_case_eq(sbi->obbpath_s, obbpath_s)) { ++ ret = 1; ++ } ++ kfree(path_buf); ++ } ++ ++ pathcpy(&lower_path, &di->lower_path); ++ need_put = 1; ++ } ++ } ++ spin_unlock(&di->lock); ++ if (need_put) ++ path_put(&lower_path); ++ return ret; ++} ++ ++int is_base_obbpath(struct dentry *dentry) ++{ ++ int ret = 0; ++ struct dentry *parent = dget_parent(dentry); ++ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ struct qstr q_obb = QSTR_LITERAL("obb"); ++ ++ spin_lock(&SDCARDFS_D(dentry)->lock); ++ if (sbi->options.multiuser) { ++ if (parent_info->data->perm == PERM_PRE_ROOT && ++ qstr_case_eq(&dentry->d_name, &q_obb)) { ++ ret = 1; ++ } ++ } else if (parent_info->data->perm == PERM_ANDROID && ++ qstr_case_eq(&dentry->d_name, &q_obb)) { ++ ret = 1; ++ } ++ spin_unlock(&SDCARDFS_D(dentry)->lock); ++ return ret; ++} ++ ++/* The lower_path will be stored to the dentry's orig_path ++ * and the base obbpath will be copyed to the lower_path variable. ++ * if an error returned, there's no change in the lower_path ++ * returns: -ERRNO if error (0: no error) ++ */ ++int setup_obb_dentry(struct dentry *dentry, struct path *lower_path) ++{ ++ int err = 0; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ struct path obbpath; ++ ++ /* A local obb dentry must have its own orig_path to support rmdir ++ * and mkdir of itself. Usually, we expect that the sbi->obbpath ++ * is avaiable on this stage. ++ */ ++ sdcardfs_set_orig_path(dentry, lower_path); ++ ++ err = kern_path(sbi->obbpath_s, ++ LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &obbpath); ++ ++ if (!err) { ++ /* the obbpath base has been found */ ++ pathcpy(lower_path, &obbpath); ++ } else { ++ /* if the sbi->obbpath is not available, we can optionally ++ * setup the lower_path with its orig_path. ++ * but, the current implementation just returns an error ++ * because the sdcard daemon also regards this case as ++ * a lookup fail. ++ */ ++ pr_info("sdcardfs: the sbi->obbpath is not available\n"); ++ } ++ return err; ++} ++ ++ +diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c +new file mode 100644 +index 0000000000000..271c4c4cb760f +--- /dev/null ++++ b/fs/sdcardfs/file.c +@@ -0,0 +1,467 @@ ++/* ++ * fs/sdcardfs/file.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE ++#include ++#endif ++ ++static ssize_t sdcardfs_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ int err; ++ struct file *lower_file; ++ struct dentry *dentry = file->f_path.dentry; ++#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE ++ struct backing_dev_info *bdi; ++#endif ++ ++ lower_file = sdcardfs_lower_file(file); ++ ++#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE ++ if (file->f_mode & FMODE_NOACTIVE) { ++ if (!(lower_file->f_mode & FMODE_NOACTIVE)) { ++ bdi = lower_file->f_mapping->backing_dev_info; ++ lower_file->f_ra.ra_pages = bdi->ra_pages * 2; ++ spin_lock(&lower_file->f_lock); ++ lower_file->f_mode |= FMODE_NOACTIVE; ++ spin_unlock(&lower_file->f_lock); ++ } ++ } ++#endif ++ ++ err = vfs_read(lower_file, buf, count, ppos); ++ /* update our inode atime upon a successful lower read */ ++ if (err >= 0) ++ fsstack_copy_attr_atime(d_inode(dentry), ++ file_inode(lower_file)); ++ ++ return err; ++} ++ ++static ssize_t sdcardfs_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ int err; ++ struct file *lower_file; ++ struct dentry *dentry = file->f_path.dentry; ++ struct inode *inode = d_inode(dentry); ++ ++ /* check disk space */ ++ if (!check_min_free_space(dentry, count, 0)) { ++ pr_err("No minimum free space.\n"); ++ return -ENOSPC; ++ } ++ ++ lower_file = sdcardfs_lower_file(file); ++ err = vfs_write(lower_file, buf, count, ppos); ++ /* update our inode times+sizes upon a successful lower write */ ++ if (err >= 0) { ++ if (sizeof(loff_t) > sizeof(long)) ++ inode_lock(inode); ++ fsstack_copy_inode_size(inode, file_inode(lower_file)); ++ fsstack_copy_attr_times(inode, file_inode(lower_file)); ++ if (sizeof(loff_t) > sizeof(long)) ++ inode_unlock(inode); ++ } ++ ++ return err; ++} ++ ++static int sdcardfs_readdir(struct file *file, struct dir_context *ctx) ++{ ++ int err; ++ struct file *lower_file = NULL; ++ struct dentry *dentry = file->f_path.dentry; ++ ++ lower_file = sdcardfs_lower_file(file); ++ ++ lower_file->f_pos = file->f_pos; ++ err = iterate_dir(lower_file, ctx); ++ file->f_pos = lower_file->f_pos; ++ if (err >= 0) /* copy the atime */ ++ fsstack_copy_attr_atime(d_inode(dentry), ++ file_inode(lower_file)); ++ return err; ++} ++ ++static long sdcardfs_unlocked_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ long err = -ENOTTY; ++ struct file *lower_file; ++ const struct cred *saved_cred = NULL; ++ struct dentry *dentry = file->f_path.dentry; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ ++ lower_file = sdcardfs_lower_file(file); ++ ++ /* XXX: use vfs_ioctl if/when VFS exports it */ ++ if (!lower_file || !lower_file->f_op) ++ goto out; ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data); ++ if (!saved_cred) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ if (lower_file->f_op->unlocked_ioctl) ++ err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); ++ ++ /* some ioctls can change inode attributes (EXT2_IOC_SETFLAGS) */ ++ if (!err) ++ sdcardfs_copy_and_fix_attrs(file_inode(file), ++ file_inode(lower_file)); ++ revert_fsids(saved_cred); ++out: ++ return err; ++} ++ ++#ifdef CONFIG_COMPAT ++static long sdcardfs_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ long err = -ENOTTY; ++ struct file *lower_file; ++ const struct cred *saved_cred = NULL; ++ struct dentry *dentry = file->f_path.dentry; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ ++ lower_file = sdcardfs_lower_file(file); ++ ++ /* XXX: use vfs_ioctl if/when VFS exports it */ ++ if (!lower_file || !lower_file->f_op) ++ goto out; ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data); ++ if (!saved_cred) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ if (lower_file->f_op->compat_ioctl) ++ err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); ++ ++ revert_fsids(saved_cred); ++out: ++ return err; ++} ++#endif ++ ++static int sdcardfs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err = 0; ++ bool willwrite; ++ struct file *lower_file; ++ const struct vm_operations_struct *saved_vm_ops = NULL; ++ ++ /* this might be deferred to mmap's writepage */ ++ willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags); ++ ++ /* ++ * File systems which do not implement ->writepage may use ++ * generic_file_readonly_mmap as their ->mmap op. If you call ++ * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL. ++ * But we cannot call the lower ->mmap op, so we can't tell that ++ * writeable mappings won't work. Therefore, our only choice is to ++ * check if the lower file system supports the ->writepage, and if ++ * not, return EINVAL (the same error that ++ * generic_file_readonly_mmap returns in that case). ++ */ ++ lower_file = sdcardfs_lower_file(file); ++ if (willwrite && !lower_file->f_mapping->a_ops->writepage) { ++ err = -EINVAL; ++ pr_err("sdcardfs: lower file system does not support writeable mmap\n"); ++ goto out; ++ } ++ ++ /* ++ * find and save lower vm_ops. ++ * ++ * XXX: the VFS should have a cleaner way of finding the lower vm_ops ++ */ ++ if (!SDCARDFS_F(file)->lower_vm_ops) { ++ err = lower_file->f_op->mmap(lower_file, vma); ++ if (err) { ++ pr_err("sdcardfs: lower mmap failed %d\n", err); ++ goto out; ++ } ++ saved_vm_ops = vma->vm_ops; /* save: came from lower ->mmap */ ++ } ++ ++ /* ++ * Next 3 lines are all I need from generic_file_mmap. I definitely ++ * don't want its test for ->readpage which returns -ENOEXEC. ++ */ ++ file_accessed(file); ++ vma->vm_ops = &sdcardfs_vm_ops; ++ ++ file->f_mapping->a_ops = &sdcardfs_aops; /* set our aops */ ++ if (!SDCARDFS_F(file)->lower_vm_ops) /* save for our ->fault */ ++ SDCARDFS_F(file)->lower_vm_ops = saved_vm_ops; ++ vma->vm_private_data = file; ++ get_file(lower_file); ++ vma->vm_file = lower_file; ++ ++out: ++ return err; ++} ++ ++static int sdcardfs_open(struct inode *inode, struct file *file) ++{ ++ int err = 0; ++ struct file *lower_file = NULL; ++ struct path lower_path; ++ struct dentry *dentry = file->f_path.dentry; ++ struct dentry *parent = dget_parent(dentry); ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ const struct cred *saved_cred = NULL; ++ ++ /* don't open unhashed/deleted files */ ++ if (d_unhashed(dentry)) { ++ err = -ENOENT; ++ goto out_err; ++ } ++ ++ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { ++ err = -EACCES; ++ goto out_err; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(sbi, SDCARDFS_I(inode)->data); ++ if (!saved_cred) { ++ err = -ENOMEM; ++ goto out_err; ++ } ++ ++ file->private_data = ++ kzalloc(sizeof(struct sdcardfs_file_info), GFP_KERNEL); ++ if (!SDCARDFS_F(file)) { ++ err = -ENOMEM; ++ goto out_revert_cred; ++ } ++ ++ /* open lower object and link sdcardfs's file struct to lower's */ ++ sdcardfs_get_lower_path(file->f_path.dentry, &lower_path); ++ lower_file = dentry_open(&lower_path, file->f_flags, current_cred()); ++ path_put(&lower_path); ++ if (IS_ERR(lower_file)) { ++ err = PTR_ERR(lower_file); ++ lower_file = sdcardfs_lower_file(file); ++ if (lower_file) { ++ sdcardfs_set_lower_file(file, NULL); ++ fput(lower_file); /* fput calls dput for lower_dentry */ ++ } ++ } else { ++ sdcardfs_set_lower_file(file, lower_file); ++ } ++ ++ if (err) ++ kfree(SDCARDFS_F(file)); ++ else ++ sdcardfs_copy_and_fix_attrs(inode, sdcardfs_lower_inode(inode)); ++ ++out_revert_cred: ++ revert_fsids(saved_cred); ++out_err: ++ dput(parent); ++ return err; ++} ++ ++static int sdcardfs_flush(struct file *file, fl_owner_t id) ++{ ++ int err = 0; ++ struct file *lower_file = NULL; ++ ++ lower_file = sdcardfs_lower_file(file); ++ if (lower_file && lower_file->f_op && lower_file->f_op->flush) { ++ filemap_write_and_wait(file->f_mapping); ++ err = lower_file->f_op->flush(lower_file, id); ++ } ++ ++ return err; ++} ++ ++/* release all lower object references & free the file info structure */ ++static int sdcardfs_file_release(struct inode *inode, struct file *file) ++{ ++ struct file *lower_file; ++ ++ lower_file = sdcardfs_lower_file(file); ++ if (lower_file) { ++ sdcardfs_set_lower_file(file, NULL); ++ fput(lower_file); ++ } ++ ++ kfree(SDCARDFS_F(file)); ++ return 0; ++} ++ ++static int sdcardfs_fsync(struct file *file, loff_t start, loff_t end, ++ int datasync) ++{ ++ int err; ++ struct file *lower_file; ++ struct path lower_path; ++ struct dentry *dentry = file->f_path.dentry; ++ ++ err = __generic_file_fsync(file, start, end, datasync); ++ if (err) ++ goto out; ++ ++ lower_file = sdcardfs_lower_file(file); ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ err = vfs_fsync_range(lower_file, start, end, datasync); ++ sdcardfs_put_lower_path(dentry, &lower_path); ++out: ++ return err; ++} ++ ++static int sdcardfs_fasync(int fd, struct file *file, int flag) ++{ ++ int err = 0; ++ struct file *lower_file = NULL; ++ ++ lower_file = sdcardfs_lower_file(file); ++ if (lower_file->f_op && lower_file->f_op->fasync) ++ err = lower_file->f_op->fasync(fd, lower_file, flag); ++ ++ return err; ++} ++ ++/* ++ * Sdcardfs cannot use generic_file_llseek as ->llseek, because it would ++ * only set the offset of the upper file. So we have to implement our ++ * own method to set both the upper and lower file offsets ++ * consistently. ++ */ ++static loff_t sdcardfs_file_llseek(struct file *file, loff_t offset, int whence) ++{ ++ int err; ++ struct file *lower_file; ++ ++ err = generic_file_llseek(file, offset, whence); ++ if (err < 0) ++ goto out; ++ ++ lower_file = sdcardfs_lower_file(file); ++ err = generic_file_llseek(lower_file, offset, whence); ++ ++out: ++ return err; ++} ++ ++/* ++ * Sdcardfs read_iter, redirect modified iocb to lower read_iter ++ */ ++ssize_t sdcardfs_read_iter(struct kiocb *iocb, struct iov_iter *iter) ++{ ++ int err; ++ struct file *file = iocb->ki_filp, *lower_file; ++ ++ lower_file = sdcardfs_lower_file(file); ++ if (!lower_file->f_op->read_iter) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ get_file(lower_file); /* prevent lower_file from being released */ ++ iocb->ki_filp = lower_file; ++ err = lower_file->f_op->read_iter(iocb, iter); ++ iocb->ki_filp = file; ++ fput(lower_file); ++ /* update upper inode atime as needed */ ++ if (err >= 0 || err == -EIOCBQUEUED) ++ fsstack_copy_attr_atime(file->f_path.dentry->d_inode, ++ file_inode(lower_file)); ++out: ++ return err; ++} ++ ++/* ++ * Sdcardfs write_iter, redirect modified iocb to lower write_iter ++ */ ++ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter) ++{ ++ int err; ++ struct file *file = iocb->ki_filp, *lower_file; ++ struct inode *inode = file->f_path.dentry->d_inode; ++ ++ lower_file = sdcardfs_lower_file(file); ++ if (!lower_file->f_op->write_iter) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ get_file(lower_file); /* prevent lower_file from being released */ ++ iocb->ki_filp = lower_file; ++ err = lower_file->f_op->write_iter(iocb, iter); ++ iocb->ki_filp = file; ++ fput(lower_file); ++ /* update upper inode times/sizes as needed */ ++ if (err >= 0 || err == -EIOCBQUEUED) { ++ if (sizeof(loff_t) > sizeof(long)) ++ inode_lock(inode); ++ fsstack_copy_inode_size(inode, file_inode(lower_file)); ++ fsstack_copy_attr_times(inode, file_inode(lower_file)); ++ if (sizeof(loff_t) > sizeof(long)) ++ inode_unlock(inode); ++ } ++out: ++ return err; ++} ++ ++const struct file_operations sdcardfs_main_fops = { ++ .llseek = generic_file_llseek, ++ .read = sdcardfs_read, ++ .write = sdcardfs_write, ++ .unlocked_ioctl = sdcardfs_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = sdcardfs_compat_ioctl, ++#endif ++ .mmap = sdcardfs_mmap, ++ .open = sdcardfs_open, ++ .flush = sdcardfs_flush, ++ .release = sdcardfs_file_release, ++ .fsync = sdcardfs_fsync, ++ .fasync = sdcardfs_fasync, ++ .read_iter = sdcardfs_read_iter, ++ .write_iter = sdcardfs_write_iter, ++}; ++ ++/* trimmed directory options */ ++const struct file_operations sdcardfs_dir_fops = { ++ .llseek = sdcardfs_file_llseek, ++ .read = generic_read_dir, ++ .iterate = sdcardfs_readdir, ++ .unlocked_ioctl = sdcardfs_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = sdcardfs_compat_ioctl, ++#endif ++ .open = sdcardfs_open, ++ .release = sdcardfs_file_release, ++ .flush = sdcardfs_flush, ++ .fsync = sdcardfs_fsync, ++ .fasync = sdcardfs_fasync, ++}; +diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c +new file mode 100644 +index 0000000000000..4dd681e0d59d9 +--- /dev/null ++++ b/fs/sdcardfs/inode.c +@@ -0,0 +1,821 @@ ++/* ++ * fs/sdcardfs/inode.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#include ++#include ++#include ++ ++const struct cred *override_fsids(struct sdcardfs_sb_info *sbi, ++ struct sdcardfs_inode_data *data) ++{ ++ struct cred *cred; ++ const struct cred *old_cred; ++ uid_t uid; ++ ++ cred = prepare_creds(); ++ if (!cred) ++ return NULL; ++ ++ if (sbi->options.gid_derivation) { ++ if (data->under_obb) ++ uid = AID_MEDIA_OBB; ++ else ++ uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid); ++ } else { ++ uid = sbi->options.fs_low_uid; ++ } ++ cred->fsuid = make_kuid(&init_user_ns, uid); ++ cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid); ++ ++ old_cred = override_creds(cred); ++ ++ return old_cred; ++} ++ ++void revert_fsids(const struct cred *old_cred) ++{ ++ const struct cred *cur_cred; ++ ++ cur_cred = current->cred; ++ revert_creds(old_cred); ++ put_cred(cur_cred); ++} ++ ++static int sdcardfs_create(struct inode *dir, struct dentry *dentry, ++ umode_t mode, bool want_excl) ++{ ++ int err; ++ struct dentry *lower_dentry; ++ struct vfsmount *lower_dentry_mnt; ++ struct dentry *lower_parent_dentry = NULL; ++ struct path lower_path; ++ const struct cred *saved_cred = NULL; ++ struct fs_struct *saved_fs; ++ struct fs_struct *copied_fs; ++ ++ if (!check_caller_access_to_name(dir, &dentry->d_name)) { ++ err = -EACCES; ++ goto out_eacces; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), ++ SDCARDFS_I(dir)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ lower_dentry = lower_path.dentry; ++ lower_dentry_mnt = lower_path.mnt; ++ lower_parent_dentry = lock_parent(lower_dentry); ++ ++ /* set last 16bytes of mode field to 0664 */ ++ mode = (mode & S_IFMT) | 00664; ++ ++ /* temporarily change umask for lower fs write */ ++ saved_fs = current->fs; ++ copied_fs = copy_fs_struct(current->fs); ++ if (!copied_fs) { ++ err = -ENOMEM; ++ goto out_unlock; ++ } ++ copied_fs->umask = 0; ++ task_lock(current); ++ current->fs = copied_fs; ++ task_unlock(current); ++ ++ err = vfs_create2(lower_dentry_mnt, d_inode(lower_parent_dentry), lower_dentry, mode, want_excl); ++ if (err) ++ goto out; ++ ++ err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, ++ SDCARDFS_I(dir)->data->userid); ++ if (err) ++ goto out; ++ fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); ++ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); ++ fixup_lower_ownership(dentry, dentry->d_name.name); ++ ++out: ++ task_lock(current); ++ current->fs = saved_fs; ++ task_unlock(current); ++ free_fs_struct(copied_fs); ++out_unlock: ++ unlock_dir(lower_parent_dentry); ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ revert_fsids(saved_cred); ++out_eacces: ++ return err; ++} ++ ++static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int err; ++ struct dentry *lower_dentry; ++ struct vfsmount *lower_mnt; ++ struct inode *lower_dir_inode = sdcardfs_lower_inode(dir); ++ struct dentry *lower_dir_dentry; ++ struct path lower_path; ++ const struct cred *saved_cred = NULL; ++ ++ if (!check_caller_access_to_name(dir, &dentry->d_name)) { ++ err = -EACCES; ++ goto out_eacces; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), ++ SDCARDFS_I(dir)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ lower_dentry = lower_path.dentry; ++ lower_mnt = lower_path.mnt; ++ dget(lower_dentry); ++ lower_dir_dentry = lock_parent(lower_dentry); ++ ++ err = vfs_unlink2(lower_mnt, lower_dir_inode, lower_dentry, NULL); ++ ++ /* ++ * Note: unlinking on top of NFS can cause silly-renamed files. ++ * Trying to delete such files results in EBUSY from NFS ++ * below. Silly-renamed files will get deleted by NFS later on, so ++ * we just need to detect them here and treat such EBUSY errors as ++ * if the upper file was successfully deleted. ++ */ ++ if (err == -EBUSY && lower_dentry->d_flags & DCACHE_NFSFS_RENAMED) ++ err = 0; ++ if (err) ++ goto out; ++ fsstack_copy_attr_times(dir, lower_dir_inode); ++ fsstack_copy_inode_size(dir, lower_dir_inode); ++ set_nlink(d_inode(dentry), ++ sdcardfs_lower_inode(d_inode(dentry))->i_nlink); ++ d_inode(dentry)->i_ctime = dir->i_ctime; ++ d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */ ++out: ++ unlock_dir(lower_dir_dentry); ++ dput(lower_dentry); ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ revert_fsids(saved_cred); ++out_eacces: ++ return err; ++} ++ ++static int touch(char *abs_path, mode_t mode) ++{ ++ struct file *filp = filp_open(abs_path, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, mode); ++ ++ if (IS_ERR(filp)) { ++ if (PTR_ERR(filp) == -EEXIST) { ++ return 0; ++ } else { ++ pr_err("sdcardfs: failed to open(%s): %ld\n", ++ abs_path, PTR_ERR(filp)); ++ return PTR_ERR(filp); ++ } ++ } ++ filp_close(filp, current->files); ++ return 0; ++} ++ ++static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ int err; ++ int make_nomedia_in_obb = 0; ++ struct dentry *lower_dentry; ++ struct vfsmount *lower_mnt; ++ struct dentry *lower_parent_dentry = NULL; ++ struct dentry *parent_dentry = NULL; ++ struct path lower_path; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ const struct cred *saved_cred = NULL; ++ struct sdcardfs_inode_data *pd = SDCARDFS_I(dir)->data; ++ int touch_err = 0; ++ struct fs_struct *saved_fs; ++ struct fs_struct *copied_fs; ++ struct qstr q_obb = QSTR_LITERAL("obb"); ++ struct qstr q_data = QSTR_LITERAL("data"); ++ ++ if (!check_caller_access_to_name(dir, &dentry->d_name)) { ++ err = -EACCES; ++ goto out_eacces; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), ++ SDCARDFS_I(dir)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ /* check disk space */ ++ parent_dentry = dget_parent(dentry); ++ if (!check_min_free_space(parent_dentry, 0, 1)) { ++ pr_err("sdcardfs: No minimum free space.\n"); ++ err = -ENOSPC; ++ dput(parent_dentry); ++ goto out_revert; ++ } ++ dput(parent_dentry); ++ ++ /* the lower_dentry is negative here */ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ lower_dentry = lower_path.dentry; ++ lower_mnt = lower_path.mnt; ++ lower_parent_dentry = lock_parent(lower_dentry); ++ ++ /* set last 16bytes of mode field to 0775 */ ++ mode = (mode & S_IFMT) | 00775; ++ ++ /* temporarily change umask for lower fs write */ ++ saved_fs = current->fs; ++ copied_fs = copy_fs_struct(current->fs); ++ if (!copied_fs) { ++ err = -ENOMEM; ++ unlock_dir(lower_parent_dentry); ++ goto out_unlock; ++ } ++ copied_fs->umask = 0; ++ task_lock(current); ++ current->fs = copied_fs; ++ task_unlock(current); ++ ++ err = vfs_mkdir2(lower_mnt, d_inode(lower_parent_dentry), lower_dentry, mode); ++ ++ if (err) { ++ unlock_dir(lower_parent_dentry); ++ goto out; ++ } ++ ++ /* if it is a local obb dentry, setup it with the base obbpath */ ++ if (need_graft_path(dentry)) { ++ ++ err = setup_obb_dentry(dentry, &lower_path); ++ if (err) { ++ /* if the sbi->obbpath is not available, the lower_path won't be ++ * changed by setup_obb_dentry() but the lower path is saved to ++ * its orig_path. this dentry will be revalidated later. ++ * but now, the lower_path should be NULL ++ */ ++ sdcardfs_put_reset_lower_path(dentry); ++ ++ /* the newly created lower path which saved to its orig_path or ++ * the lower_path is the base obbpath. ++ * therefore, an additional path_get is required ++ */ ++ path_get(&lower_path); ++ } else ++ make_nomedia_in_obb = 1; ++ } ++ ++ err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, pd->userid); ++ if (err) { ++ unlock_dir(lower_parent_dentry); ++ goto out; ++ } ++ ++ fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); ++ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); ++ /* update number of links on parent directory */ ++ set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink); ++ fixup_lower_ownership(dentry, dentry->d_name.name); ++ unlock_dir(lower_parent_dentry); ++ if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb)) ++ && (pd->perm == PERM_ANDROID) && (pd->userid == 0)) ++ make_nomedia_in_obb = 1; ++ ++ /* When creating /Android/data and /Android/obb, mark them as .nomedia */ ++ if (make_nomedia_in_obb || ++ ((pd->perm == PERM_ANDROID) ++ && (qstr_case_eq(&dentry->d_name, &q_data)))) { ++ revert_fsids(saved_cred); ++ saved_cred = override_fsids(sbi, ++ SDCARDFS_I(d_inode(dentry))->data); ++ if (!saved_cred) { ++ pr_err("sdcardfs: failed to set up .nomedia in %s: %d\n", ++ lower_path.dentry->d_name.name, ++ -ENOMEM); ++ goto out; ++ } ++ set_fs_pwd(current->fs, &lower_path); ++ touch_err = touch(".nomedia", 0664); ++ if (touch_err) { ++ pr_err("sdcardfs: failed to create .nomedia in %s: %d\n", ++ lower_path.dentry->d_name.name, ++ touch_err); ++ goto out; ++ } ++ } ++out: ++ task_lock(current); ++ current->fs = saved_fs; ++ task_unlock(current); ++ ++ free_fs_struct(copied_fs); ++out_unlock: ++ sdcardfs_put_lower_path(dentry, &lower_path); ++out_revert: ++ revert_fsids(saved_cred); ++out_eacces: ++ return err; ++} ++ ++static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ struct dentry *lower_dentry; ++ struct dentry *lower_dir_dentry; ++ struct vfsmount *lower_mnt; ++ int err; ++ struct path lower_path; ++ const struct cred *saved_cred = NULL; ++ ++ if (!check_caller_access_to_name(dir, &dentry->d_name)) { ++ err = -EACCES; ++ goto out_eacces; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), ++ SDCARDFS_I(dir)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ /* sdcardfs_get_real_lower(): in case of remove an user's obb dentry ++ * the dentry on the original path should be deleted. ++ */ ++ sdcardfs_get_real_lower(dentry, &lower_path); ++ ++ lower_dentry = lower_path.dentry; ++ lower_mnt = lower_path.mnt; ++ lower_dir_dentry = lock_parent(lower_dentry); ++ ++ err = vfs_rmdir2(lower_mnt, d_inode(lower_dir_dentry), lower_dentry); ++ if (err) ++ goto out; ++ ++ d_drop(dentry); /* drop our dentry on success (why not VFS's job?) */ ++ if (d_inode(dentry)) ++ clear_nlink(d_inode(dentry)); ++ fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); ++ fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); ++ set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); ++ ++out: ++ unlock_dir(lower_dir_dentry); ++ sdcardfs_put_real_lower(dentry, &lower_path); ++ revert_fsids(saved_cred); ++out_eacces: ++ return err; ++} ++ ++/* ++ * The locking rules in sdcardfs_rename are complex. We could use a simpler ++ * superblock-level name-space lock for renames and copy-ups. ++ */ ++static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, ++ unsigned int flags) ++{ ++ int err = 0; ++ struct dentry *lower_old_dentry = NULL; ++ struct dentry *lower_new_dentry = NULL; ++ struct dentry *lower_old_dir_dentry = NULL; ++ struct dentry *lower_new_dir_dentry = NULL; ++ struct vfsmount *lower_mnt = NULL; ++ struct dentry *trap = NULL; ++ struct path lower_old_path, lower_new_path; ++ const struct cred *saved_cred = NULL; ++ ++ if (flags) ++ return -EINVAL; ++ ++ if (!check_caller_access_to_name(old_dir, &old_dentry->d_name) || ++ !check_caller_access_to_name(new_dir, &new_dentry->d_name)) { ++ err = -EACCES; ++ goto out_eacces; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(old_dir->i_sb), ++ SDCARDFS_I(new_dir)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ sdcardfs_get_real_lower(old_dentry, &lower_old_path); ++ sdcardfs_get_lower_path(new_dentry, &lower_new_path); ++ lower_old_dentry = lower_old_path.dentry; ++ lower_new_dentry = lower_new_path.dentry; ++ lower_mnt = lower_old_path.mnt; ++ lower_old_dir_dentry = dget_parent(lower_old_dentry); ++ lower_new_dir_dentry = dget_parent(lower_new_dentry); ++ ++ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++ /* source should not be ancestor of target */ ++ if (trap == lower_old_dentry) { ++ err = -EINVAL; ++ goto out; ++ } ++ /* target should not be ancestor of source */ ++ if (trap == lower_new_dentry) { ++ err = -ENOTEMPTY; ++ goto out; ++ } ++ ++ err = vfs_rename2(lower_mnt, ++ d_inode(lower_old_dir_dentry), lower_old_dentry, ++ d_inode(lower_new_dir_dentry), lower_new_dentry, ++ NULL, 0); ++ if (err) ++ goto out; ++ ++ /* Copy attrs from lower dir, but i_uid/i_gid */ ++ sdcardfs_copy_and_fix_attrs(new_dir, d_inode(lower_new_dir_dentry)); ++ fsstack_copy_inode_size(new_dir, d_inode(lower_new_dir_dentry)); ++ ++ if (new_dir != old_dir) { ++ sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry)); ++ fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry)); ++ } ++ get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name); ++ fixup_tmp_permissions(d_inode(old_dentry)); ++ fixup_lower_ownership(old_dentry, new_dentry->d_name.name); ++ d_invalidate(old_dentry); /* Can't fixup ownership recursively :( */ ++out: ++ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++ dput(lower_old_dir_dentry); ++ dput(lower_new_dir_dentry); ++ sdcardfs_put_real_lower(old_dentry, &lower_old_path); ++ sdcardfs_put_lower_path(new_dentry, &lower_new_path); ++ revert_fsids(saved_cred); ++out_eacces: ++ return err; ++} ++ ++#if 0 ++static int sdcardfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) ++{ ++ int err; ++ struct dentry *lower_dentry; ++ struct path lower_path; ++ /* XXX readlink does not requires overriding credential */ ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ lower_dentry = lower_path.dentry; ++ if (!d_inode(lower_dentry)->i_op || ++ !d_inode(lower_dentry)->i_op->readlink) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ err = d_inode(lower_dentry)->i_op->readlink(lower_dentry, ++ buf, bufsiz); ++ if (err < 0) ++ goto out; ++ fsstack_copy_attr_atime(d_inode(dentry), d_inode(lower_dentry)); ++ ++out: ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ return err; ++} ++#endif ++ ++#if 0 ++static const char *sdcardfs_follow_link(struct dentry *dentry, void **cookie) ++{ ++ char *buf; ++ int len = PAGE_SIZE, err; ++ mm_segment_t old_fs; ++ ++ /* This is freed by the put_link method assuming a successful call. */ ++ buf = kmalloc(len, GFP_KERNEL); ++ if (!buf) { ++ buf = ERR_PTR(-ENOMEM); ++ return buf; ++ } ++ ++ /* read the symlink, and then we will follow it */ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = sdcardfs_readlink(dentry, buf, len); ++ set_fs(old_fs); ++ if (err < 0) { ++ kfree(buf); ++ buf = ERR_PTR(err); ++ } else { ++ buf[err] = '\0'; ++ } ++ return *cookie = buf; ++} ++#endif ++ ++static int sdcardfs_permission_wrn(struct inode *inode, int mask) ++{ ++ WARN_RATELIMIT(1, "sdcardfs does not support permission. Use permission2.\n"); ++ return -EINVAL; ++} ++ ++void copy_attrs(struct inode *dest, const struct inode *src) ++{ ++ dest->i_mode = src->i_mode; ++ dest->i_uid = src->i_uid; ++ dest->i_gid = src->i_gid; ++ dest->i_rdev = src->i_rdev; ++ dest->i_atime = src->i_atime; ++ dest->i_mtime = src->i_mtime; ++ dest->i_ctime = src->i_ctime; ++ dest->i_blkbits = src->i_blkbits; ++ dest->i_flags = src->i_flags; ++#ifdef CONFIG_FS_POSIX_ACL ++ dest->i_acl = src->i_acl; ++#endif ++#ifdef CONFIG_SECURITY ++ dest->i_security = src->i_security; ++#endif ++} ++ ++static int sdcardfs_permission(struct vfsmount *mnt, struct inode *inode, int mask) ++{ ++ int err; ++ struct inode tmp; ++ struct sdcardfs_inode_data *top = top_data_get(SDCARDFS_I(inode)); ++ ++ if (IS_ERR(mnt)) ++ return PTR_ERR(mnt); ++ ++ if (!top) ++ return -EINVAL; ++ ++ /* ++ * Permission check on sdcardfs inode. ++ * Calling process should have AID_SDCARD_RW permission ++ * Since generic_permission only needs i_mode, i_uid, ++ * i_gid, and i_sb, we can create a fake inode to pass ++ * this information down in. ++ * ++ * The underlying code may attempt to take locks in some ++ * cases for features we're not using, but if that changes, ++ * locks must be dealt with to avoid undefined behavior. ++ */ ++ copy_attrs(&tmp, inode); ++ tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); ++ tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, inode->i_sb, top)); ++ tmp.i_mode = (inode->i_mode & S_IFMT) ++ | get_mode(mnt, SDCARDFS_I(inode), top); ++ data_put(top); ++ tmp.i_sb = inode->i_sb; ++ if (IS_POSIXACL(inode)) ++ pr_warn("%s: This may be undefined behavior...\n", __func__); ++ err = generic_permission(&tmp, mask); ++ return err; ++} ++ ++static int sdcardfs_setattr_wrn(struct dentry *dentry, struct iattr *ia) ++{ ++ WARN_RATELIMIT(1, "sdcardfs does not support setattr. User setattr2.\n"); ++ return -EINVAL; ++} ++ ++static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct iattr *ia) ++{ ++ int err; ++ struct dentry *lower_dentry; ++ struct vfsmount *lower_mnt; ++ struct inode *inode; ++ struct inode *lower_inode; ++ struct path lower_path; ++ struct iattr lower_ia; ++ struct dentry *parent; ++ struct inode tmp; ++ struct dentry tmp_d; ++ struct sdcardfs_inode_data *top; ++ ++ const struct cred *saved_cred = NULL; ++ ++ inode = d_inode(dentry); ++ top = top_data_get(SDCARDFS_I(inode)); ++ ++ if (!top) ++ return -EINVAL; ++ ++ /* ++ * Permission check on sdcardfs inode. ++ * Calling process should have AID_SDCARD_RW permission ++ * Since generic_permission only needs i_mode, i_uid, ++ * i_gid, and i_sb, we can create a fake inode to pass ++ * this information down in. ++ * ++ * The underlying code may attempt to take locks in some ++ * cases for features we're not using, but if that changes, ++ * locks must be dealt with to avoid undefined behavior. ++ * ++ */ ++ copy_attrs(&tmp, inode); ++ tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); ++ tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top)); ++ tmp.i_mode = (inode->i_mode & S_IFMT) ++ | get_mode(mnt, SDCARDFS_I(inode), top); ++ tmp.i_size = i_size_read(inode); ++ data_put(top); ++ tmp.i_sb = inode->i_sb; ++ tmp_d.d_inode = &tmp; ++ ++ /* ++ * Check if user has permission to change dentry. We don't check if ++ * this user can change the lower inode: that should happen when ++ * calling notify_change on the lower inode. ++ */ ++ /* prepare our own lower struct iattr (with the lower file) */ ++ memcpy(&lower_ia, ia, sizeof(lower_ia)); ++ /* Allow touch updating timestamps. A previous permission check ensures ++ * we have write access. Changes to mode, owner, and group are ignored ++ */ ++ ia->ia_valid |= ATTR_FORCE; ++ err = setattr_prepare(&tmp_d, ia); ++ ++ if (!err) { ++ /* check the Android group ID */ ++ parent = dget_parent(dentry); ++ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) ++ err = -EACCES; ++ dput(parent); ++ } ++ ++ if (err) ++ goto out_err; ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dentry->d_sb), ++ SDCARDFS_I(inode)->data); ++ if (!saved_cred) ++ return -ENOMEM; ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ lower_dentry = lower_path.dentry; ++ lower_mnt = lower_path.mnt; ++ lower_inode = sdcardfs_lower_inode(inode); ++ ++ if (ia->ia_valid & ATTR_FILE) ++ lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file); ++ ++ lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); ++ ++ /* ++ * If shrinking, first truncate upper level to cancel writing dirty ++ * pages beyond the new eof; and also if its' maxbytes is more ++ * limiting (fail with -EFBIG before making any change to the lower ++ * level). There is no need to vmtruncate the upper level ++ * afterwards in the other cases: we fsstack_copy_inode_size from ++ * the lower level. ++ */ ++ if (ia->ia_valid & ATTR_SIZE) { ++ err = inode_newsize_ok(&tmp, ia->ia_size); ++ if (err) { ++ goto out; ++ } ++ truncate_setsize(inode, ia->ia_size); ++ } ++ ++ /* ++ * mode change is for clearing setuid/setgid bits. Allow lower fs ++ * to interpret this in its own way. ++ */ ++ if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ lower_ia.ia_valid &= ~ATTR_MODE; ++ ++ /* notify the (possibly copied-up) lower inode */ ++ /* ++ * Note: we use d_inode(lower_dentry), because lower_inode may be ++ * unlinked (no inode->i_sb and i_ino==0. This happens if someone ++ * tries to open(), unlink(), then ftruncate() a file. ++ */ ++ inode_lock(d_inode(lower_dentry)); ++ err = notify_change2(lower_mnt, lower_dentry, &lower_ia, /* note: lower_ia */ ++ NULL); ++ inode_unlock(d_inode(lower_dentry)); ++ if (err) ++ goto out; ++ ++ /* get attributes from the lower inode and update derived permissions */ ++ sdcardfs_copy_and_fix_attrs(inode, lower_inode); ++ ++ /* ++ * Not running fsstack_copy_inode_size(inode, lower_inode), because ++ * VFS should update our inode size, and notify_change on ++ * lower_inode should update its size. ++ */ ++ ++out: ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ revert_fsids(saved_cred); ++out_err: ++ return err; ++} ++ ++static int sdcardfs_fillattr(struct vfsmount *mnt, struct inode *inode, ++ struct kstat *lower_stat, struct kstat *stat) ++{ ++ struct sdcardfs_inode_info *info = SDCARDFS_I(inode); ++ struct sdcardfs_inode_data *top = top_data_get(info); ++ struct super_block *sb = inode->i_sb; ++ ++ if (!top) ++ return -EINVAL; ++ ++ stat->dev = inode->i_sb->s_dev; ++ stat->ino = inode->i_ino; ++ stat->mode = (inode->i_mode & S_IFMT) | get_mode(mnt, info, top); ++ stat->nlink = inode->i_nlink; ++ stat->uid = make_kuid(&init_user_ns, top->d_uid); ++ stat->gid = make_kgid(&init_user_ns, get_gid(mnt, sb, top)); ++ stat->rdev = inode->i_rdev; ++ stat->size = lower_stat->size; ++ stat->atime = lower_stat->atime; ++ stat->mtime = lower_stat->mtime; ++ stat->ctime = lower_stat->ctime; ++ stat->blksize = lower_stat->blksize; ++ stat->blocks = lower_stat->blocks; ++ data_put(top); ++ return 0; ++} ++static int sdcardfs_getattr(const struct path *path, struct kstat *stat, ++ u32 request_mask, unsigned int flags) ++{ ++ struct vfsmount *mnt = path->mnt; ++ struct dentry *dentry = path->dentry; ++ struct kstat lower_stat; ++ struct path lower_path; ++ struct dentry *parent; ++ int err; ++ ++ parent = dget_parent(dentry); ++ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { ++ dput(parent); ++ return -EACCES; ++ } ++ dput(parent); ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ err = vfs_getattr(&lower_path, &lower_stat, request_mask, flags); ++ if (err) ++ goto out; ++ sdcardfs_copy_and_fix_attrs(d_inode(dentry), ++ d_inode(lower_path.dentry)); ++ err = sdcardfs_fillattr(mnt, d_inode(dentry), &lower_stat, stat); ++out: ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ return err; ++} ++ ++const struct inode_operations sdcardfs_symlink_iops = { ++ .permission2 = sdcardfs_permission, ++ .setattr2 = sdcardfs_setattr, ++ /* XXX Following operations are implemented, ++ * but FUSE(sdcard) or FAT does not support them ++ * These methods are *NOT* perfectly tested. ++ .readlink = sdcardfs_readlink, ++ .follow_link = sdcardfs_follow_link, ++ .put_link = kfree_put_link, ++ */ ++}; ++ ++const struct inode_operations sdcardfs_dir_iops = { ++ .create = sdcardfs_create, ++ .lookup = sdcardfs_lookup, ++ .permission = sdcardfs_permission_wrn, ++ .permission2 = sdcardfs_permission, ++ .unlink = sdcardfs_unlink, ++ .mkdir = sdcardfs_mkdir, ++ .rmdir = sdcardfs_rmdir, ++ .rename = sdcardfs_rename, ++ .setattr = sdcardfs_setattr_wrn, ++ .setattr2 = sdcardfs_setattr, ++ .getattr = sdcardfs_getattr, ++}; ++ ++const struct inode_operations sdcardfs_main_iops = { ++ .permission = sdcardfs_permission_wrn, ++ .permission2 = sdcardfs_permission, ++ .setattr = sdcardfs_setattr_wrn, ++ .setattr2 = sdcardfs_setattr, ++ .getattr = sdcardfs_getattr, ++}; +diff --git a/fs/sdcardfs/lookup.c b/fs/sdcardfs/lookup.c +new file mode 100644 +index 0000000000000..a5c9686090e0a +--- /dev/null ++++ b/fs/sdcardfs/lookup.c +@@ -0,0 +1,470 @@ ++/* ++ * fs/sdcardfs/lookup.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#include "linux/delay.h" ++ ++/* The dentry cache is just so we have properly sized dentries */ ++static struct kmem_cache *sdcardfs_dentry_cachep; ++ ++int sdcardfs_init_dentry_cache(void) ++{ ++ sdcardfs_dentry_cachep = ++ kmem_cache_create("sdcardfs_dentry", ++ sizeof(struct sdcardfs_dentry_info), ++ 0, SLAB_RECLAIM_ACCOUNT, NULL); ++ ++ return sdcardfs_dentry_cachep ? 0 : -ENOMEM; ++} ++ ++void sdcardfs_destroy_dentry_cache(void) ++{ ++ kmem_cache_destroy(sdcardfs_dentry_cachep); ++} ++ ++void free_dentry_private_data(struct dentry *dentry) ++{ ++ kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata); ++ dentry->d_fsdata = NULL; ++} ++ ++/* allocate new dentry private data */ ++int new_dentry_private_data(struct dentry *dentry) ++{ ++ struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry); ++ ++ /* use zalloc to init dentry_info.lower_path */ ++ info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC); ++ if (!info) ++ return -ENOMEM; ++ ++ spin_lock_init(&info->lock); ++ dentry->d_fsdata = info; ++ ++ return 0; ++} ++ ++struct inode_data { ++ struct inode *lower_inode; ++ userid_t id; ++}; ++ ++static int sdcardfs_inode_test(struct inode *inode, void *candidate_data/*void *candidate_lower_inode*/) ++{ ++ struct inode *current_lower_inode = sdcardfs_lower_inode(inode); ++ userid_t current_userid = SDCARDFS_I(inode)->data->userid; ++ ++ if (current_lower_inode == ((struct inode_data *)candidate_data)->lower_inode && ++ current_userid == ((struct inode_data *)candidate_data)->id) ++ return 1; /* found a match */ ++ else ++ return 0; /* no match */ ++} ++ ++static int sdcardfs_inode_set(struct inode *inode, void *lower_inode) ++{ ++ /* we do actual inode initialization in sdcardfs_iget */ ++ return 0; ++} ++ ++struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id) ++{ ++ struct sdcardfs_inode_info *info; ++ struct inode_data data; ++ struct inode *inode; /* the new inode to return */ ++ ++ if (!igrab(lower_inode)) ++ return ERR_PTR(-ESTALE); ++ ++ data.id = id; ++ data.lower_inode = lower_inode; ++ inode = iget5_locked(sb, /* our superblock */ ++ /* ++ * hashval: we use inode number, but we can ++ * also use "(unsigned long)lower_inode" ++ * instead. ++ */ ++ lower_inode->i_ino, /* hashval */ ++ sdcardfs_inode_test, /* inode comparison function */ ++ sdcardfs_inode_set, /* inode init function */ ++ &data); /* data passed to test+set fxns */ ++ if (!inode) { ++ iput(lower_inode); ++ return ERR_PTR(-ENOMEM); ++ } ++ /* if found a cached inode, then just return it (after iput) */ ++ if (!(inode->i_state & I_NEW)) { ++ iput(lower_inode); ++ return inode; ++ } ++ ++ /* initialize new inode */ ++ info = SDCARDFS_I(inode); ++ ++ inode->i_ino = lower_inode->i_ino; ++ sdcardfs_set_lower_inode(inode, lower_inode); ++ ++ inode_inc_iversion_raw(inode); ++ ++ /* use different set of inode ops for symlinks & directories */ ++ if (S_ISDIR(lower_inode->i_mode)) ++ inode->i_op = &sdcardfs_dir_iops; ++ else if (S_ISLNK(lower_inode->i_mode)) ++ inode->i_op = &sdcardfs_symlink_iops; ++ else ++ inode->i_op = &sdcardfs_main_iops; ++ ++ /* use different set of file ops for directories */ ++ if (S_ISDIR(lower_inode->i_mode)) ++ inode->i_fop = &sdcardfs_dir_fops; ++ else ++ inode->i_fop = &sdcardfs_main_fops; ++ ++ inode->i_mapping->a_ops = &sdcardfs_aops; ++ ++ inode->i_atime.tv_sec = 0; ++ inode->i_atime.tv_nsec = 0; ++ inode->i_mtime.tv_sec = 0; ++ inode->i_mtime.tv_nsec = 0; ++ inode->i_ctime.tv_sec = 0; ++ inode->i_ctime.tv_nsec = 0; ++ ++ /* properly initialize special inodes */ ++ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || ++ S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) ++ init_special_inode(inode, lower_inode->i_mode, ++ lower_inode->i_rdev); ++ ++ /* all well, copy inode attributes */ ++ sdcardfs_copy_and_fix_attrs(inode, lower_inode); ++ fsstack_copy_inode_size(inode, lower_inode); ++ ++ unlock_new_inode(inode); ++ return inode; ++} ++ ++/* ++ * Helper interpose routine, called directly by ->lookup to handle ++ * spliced dentries. ++ */ ++static struct dentry *__sdcardfs_interpose(struct dentry *dentry, ++ struct super_block *sb, ++ struct path *lower_path, ++ userid_t id) ++{ ++ struct inode *inode; ++ struct inode *lower_inode; ++ struct super_block *lower_sb; ++ struct dentry *ret_dentry; ++ ++ lower_inode = d_inode(lower_path->dentry); ++ lower_sb = sdcardfs_lower_super(sb); ++ ++ /* check that the lower file system didn't cross a mount point */ ++ if (lower_inode->i_sb != lower_sb) { ++ ret_dentry = ERR_PTR(-EXDEV); ++ goto out; ++ } ++ ++ /* ++ * We allocate our new inode below by calling sdcardfs_iget, ++ * which will initialize some of the new inode's fields ++ */ ++ ++ /* inherit lower inode number for sdcardfs's inode */ ++ inode = sdcardfs_iget(sb, lower_inode, id); ++ if (IS_ERR(inode)) { ++ ret_dentry = ERR_CAST(inode); ++ goto out; ++ } ++ ++ ret_dentry = d_splice_alias(inode, dentry); ++ dentry = ret_dentry ?: dentry; ++ if (!IS_ERR(dentry)) ++ update_derived_permission_lock(dentry); ++out: ++ return ret_dentry; ++} ++ ++/* ++ * Connect an sdcardfs inode dentry/inode with several lower ones. This is ++ * the classic stackable file system "vnode interposition" action. ++ * ++ * @dentry: sdcardfs's dentry which interposes on lower one ++ * @sb: sdcardfs's super_block ++ * @lower_path: the lower path (caller does path_get/put) ++ */ ++int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb, ++ struct path *lower_path, userid_t id) ++{ ++ struct dentry *ret_dentry; ++ ++ ret_dentry = __sdcardfs_interpose(dentry, sb, lower_path, id); ++ return PTR_ERR(ret_dentry); ++} ++ ++struct sdcardfs_name_data { ++ struct dir_context ctx; ++ const struct qstr *to_find; ++ char *name; ++ bool found; ++}; ++ ++static int sdcardfs_name_match(struct dir_context *ctx, const char *name, ++ int namelen, loff_t offset, u64 ino, unsigned int d_type) ++{ ++ struct sdcardfs_name_data *buf = container_of(ctx, struct sdcardfs_name_data, ctx); ++ struct qstr candidate = QSTR_INIT(name, namelen); ++ ++ if (qstr_case_eq(buf->to_find, &candidate)) { ++ memcpy(buf->name, name, namelen); ++ buf->name[namelen] = 0; ++ buf->found = true; ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * Main driver function for sdcardfs's lookup. ++ * ++ * Returns: NULL (ok), ERR_PTR if an error occurred. ++ * Fills in lower_parent_path with on success. ++ */ ++static struct dentry *__sdcardfs_lookup(struct dentry *dentry, ++ unsigned int flags, struct path *lower_parent_path, userid_t id) ++{ ++ int err = 0; ++ struct vfsmount *lower_dir_mnt; ++ struct dentry *lower_dir_dentry = NULL; ++ struct dentry *lower_dentry; ++ const struct qstr *name; ++ struct path lower_path; ++ struct qstr dname; ++ struct dentry *ret_dentry = NULL; ++ struct sdcardfs_sb_info *sbi; ++ ++ sbi = SDCARDFS_SB(dentry->d_sb); ++ /* must initialize dentry operations */ ++ d_set_d_op(dentry, &sdcardfs_ci_dops); ++ ++ if (IS_ROOT(dentry)) ++ goto out; ++ ++ name = &dentry->d_name; ++ ++ /* now start the actual lookup procedure */ ++ lower_dir_dentry = lower_parent_path->dentry; ++ lower_dir_mnt = lower_parent_path->mnt; ++ ++ /* Use vfs_path_lookup to check if the dentry exists or not */ ++ err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name->name, 0, ++ &lower_path); ++ /* check for other cases */ ++ if (err == -ENOENT) { ++ struct file *file; ++ const struct cred *cred = current_cred(); ++ ++ struct sdcardfs_name_data buffer = { ++ .ctx.actor = sdcardfs_name_match, ++ .to_find = name, ++ .name = __getname(), ++ .found = false, ++ }; ++ ++ if (!buffer.name) { ++ err = -ENOMEM; ++ goto out; ++ } ++ file = dentry_open(lower_parent_path, O_RDONLY, cred); ++ if (IS_ERR(file)) { ++ err = PTR_ERR(file); ++ goto put_name; ++ } ++ err = iterate_dir(file, &buffer.ctx); ++ fput(file); ++ if (err) ++ goto put_name; ++ ++ if (buffer.found) ++ err = vfs_path_lookup(lower_dir_dentry, ++ lower_dir_mnt, ++ buffer.name, 0, ++ &lower_path); ++ else ++ err = -ENOENT; ++put_name: ++ __putname(buffer.name); ++ } ++ ++ /* no error: handle positive dentries */ ++ if (!err) { ++ /* check if the dentry is an obb dentry ++ * if true, the lower_inode must be replaced with ++ * the inode of the graft path ++ */ ++ ++ if (need_graft_path(dentry)) { ++ ++ /* setup_obb_dentry() ++ * The lower_path will be stored to the dentry's orig_path ++ * and the base obbpath will be copyed to the lower_path variable. ++ * if an error returned, there's no change in the lower_path ++ * returns: -ERRNO if error (0: no error) ++ */ ++ err = setup_obb_dentry(dentry, &lower_path); ++ ++ if (err) { ++ /* if the sbi->obbpath is not available, we can optionally ++ * setup the lower_path with its orig_path. ++ * but, the current implementation just returns an error ++ * because the sdcard daemon also regards this case as ++ * a lookup fail. ++ */ ++ pr_info("sdcardfs: base obbpath is not available\n"); ++ sdcardfs_put_reset_orig_path(dentry); ++ goto out; ++ } ++ } ++ ++ sdcardfs_set_lower_path(dentry, &lower_path); ++ ret_dentry = ++ __sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id); ++ if (IS_ERR(ret_dentry)) { ++ err = PTR_ERR(ret_dentry); ++ /* path_put underlying path on error */ ++ sdcardfs_put_reset_lower_path(dentry); ++ } ++ goto out; ++ } ++ ++ /* ++ * We don't consider ENOENT an error, and we want to return a ++ * negative dentry. ++ */ ++ if (err && err != -ENOENT) ++ goto out; ++ ++ /* instatiate a new negative dentry */ ++ dname.name = name->name; ++ dname.len = name->len; ++ ++ /* See if the low-level filesystem might want ++ * to use its own hash ++ */ ++ lower_dentry = d_hash_and_lookup(lower_dir_dentry, &dname); ++ if (IS_ERR(lower_dentry)) ++ return lower_dentry; ++ ++ if (!lower_dentry) { ++ /* We called vfs_path_lookup earlier, and did not get a negative ++ * dentry then. Don't confuse the lower filesystem by forcing ++ * one on it now... ++ */ ++ err = -ENOENT; ++ goto out; ++ } ++ ++ lower_path.dentry = lower_dentry; ++ lower_path.mnt = mntget(lower_dir_mnt); ++ sdcardfs_set_lower_path(dentry, &lower_path); ++ ++ /* ++ * If the intent is to create a file, then don't return an error, so ++ * the VFS will continue the process of making this negative dentry ++ * into a positive one. ++ */ ++ if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET)) ++ err = 0; ++ ++out: ++ if (err) ++ return ERR_PTR(err); ++ return ret_dentry; ++} ++ ++/* ++ * On success: ++ * fills dentry object appropriate values and returns NULL. ++ * On fail (== error) ++ * returns error ptr ++ * ++ * @dir : Parent inode. ++ * @dentry : Target dentry to lookup. we should set each of fields. ++ * (dentry->d_name is initialized already) ++ * @nd : nameidata of parent inode ++ */ ++struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags) ++{ ++ struct dentry *ret = NULL, *parent; ++ struct path lower_parent_path; ++ int err = 0; ++ const struct cred *saved_cred = NULL; ++ ++ parent = dget_parent(dentry); ++ ++ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { ++ ret = ERR_PTR(-EACCES); ++ goto out_err; ++ } ++ ++ /* save current_cred and override it */ ++ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), ++ SDCARDFS_I(dir)->data); ++ if (!saved_cred) { ++ ret = ERR_PTR(-ENOMEM); ++ goto out_err; ++ } ++ ++ sdcardfs_get_lower_path(parent, &lower_parent_path); ++ ++ /* allocate dentry private data. We free it in ->d_release */ ++ err = new_dentry_private_data(dentry); ++ if (err) { ++ ret = ERR_PTR(err); ++ goto out; ++ } ++ ++ ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path, ++ SDCARDFS_I(dir)->data->userid); ++ if (IS_ERR(ret)) ++ goto out; ++ if (ret) ++ dentry = ret; ++ if (d_inode(dentry)) { ++ fsstack_copy_attr_times(d_inode(dentry), ++ sdcardfs_lower_inode(d_inode(dentry))); ++ /* get derived permission */ ++ get_derived_permission(parent, dentry); ++ fixup_tmp_permissions(d_inode(dentry)); ++ fixup_lower_ownership(dentry, dentry->d_name.name); ++ } ++ /* update parent directory's atime */ ++ fsstack_copy_attr_atime(d_inode(parent), ++ sdcardfs_lower_inode(d_inode(parent))); ++ ++out: ++ sdcardfs_put_lower_path(parent, &lower_parent_path); ++ revert_fsids(saved_cred); ++out_err: ++ dput(parent); ++ return ret; ++} +diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c +new file mode 100644 +index 0000000000000..b8e5cf2b9ae5b +--- /dev/null ++++ b/fs/sdcardfs/main.c +@@ -0,0 +1,454 @@ ++/* ++ * fs/sdcardfs/main.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#include ++#include ++#include ++#include ++#include ++ ++enum sdcardfs_param { ++ Opt_fsuid, ++ Opt_fsgid, ++ Opt_gid, ++ Opt_debug, ++ Opt_mask, ++ Opt_multiuser, ++ Opt_userid, ++ Opt_reserved_mb, ++ Opt_gid_derivation, ++ Opt_default_normal, ++ Opt_nocache, ++ Opt_unshared_obb, ++ Opt_err, ++}; ++ ++static const struct fs_parameter_spec sdcardfs_param_specs[] = { ++ fsparam_u32("fsuid", Opt_fsuid), ++ fsparam_u32("fsgid", Opt_fsgid), ++ fsparam_u32("gid", Opt_gid), ++ fsparam_bool("debug", Opt_debug), ++ fsparam_u32("mask", Opt_mask), ++ fsparam_u32("userid", Opt_userid), ++ fsparam_bool("multiuser", Opt_multiuser), ++ fsparam_bool("derive_gid", Opt_gid_derivation), ++ fsparam_bool("default_normal", Opt_default_normal), ++ fsparam_bool("unshared_obb", Opt_unshared_obb), ++ fsparam_u32("reserved_mb", Opt_reserved_mb), ++ fsparam_bool("nocache", Opt_nocache), ++ {} ++}; ++ ++static const struct fs_parameter_description sdcardfs_parameters = { ++ .name = "sdcardfs", ++ .specs = sdcardfs_param_specs, ++}; ++ ++static int sdcardfs_parse_param(struct fs_context *fc, struct fs_parameter *param) ++{ ++ struct sdcardfs_context_options *fc_opts = fc->fs_private; ++ struct sdcardfs_mount_options *opts = &fc_opts->opts; ++ struct sdcardfs_vfsmount_options *vfsopts = &fc_opts->vfsopts; ++ struct fs_parse_result result; ++ int opt; ++ ++ opt = fs_parse(fc, &sdcardfs_parameters, param, &result); ++ if (opt < 0) ++ return opt; ++ ++ switch (opt) { ++ case Opt_debug: ++ opts->debug = true; ++ case Opt_fsuid: ++ opts->fs_low_uid = result.uint_32; ++ break; ++ case Opt_fsgid: ++ opts->fs_low_gid = result.uint_32; ++ break; ++ case Opt_gid: ++ vfsopts->gid = result.uint_32; ++ break; ++ case Opt_userid: ++ opts->fs_user_id = result.uint_32; ++ break; ++ case Opt_mask: ++ vfsopts->mask = result.uint_32; ++ break; ++ case Opt_multiuser: ++ opts->multiuser = true; ++ break; ++ case Opt_reserved_mb: ++ opts->reserved_mb = result.uint_32; ++ break; ++ case Opt_gid_derivation: ++ opts->gid_derivation = true; ++ break; ++ case Opt_default_normal: ++ opts->default_normal = true; ++ break; ++ case Opt_nocache: ++ opts->nocache = true; ++ break; ++ case Opt_unshared_obb: ++ opts->unshared_obb = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void copy_sb_opts(struct sdcardfs_mount_options *opts, ++ struct fs_context *fc) ++{ ++ struct sdcardfs_context_options *fcopts = fc->fs_private; ++ ++ opts->debug = fcopts->opts.debug; ++ opts->default_normal = fcopts->opts.default_normal; ++ opts->fs_low_gid = fcopts->opts.fs_low_gid; ++ opts->fs_low_uid = fcopts->opts.fs_low_uid; ++ opts->fs_user_id = fcopts->opts.fs_user_id; ++ opts->gid_derivation = fcopts->opts.gid_derivation; ++ opts->multiuser = fcopts->opts.multiuser; ++ opts->nocache = fcopts->opts.nocache; ++ opts->reserved_mb = fcopts->opts.reserved_mb; ++ opts->unshared_obb = fcopts->opts.unshared_obb; ++} ++ ++#if 0 ++/* ++ * our custom d_alloc_root work-alike ++ * ++ * we can't use d_alloc_root if we want to use our own interpose function ++ * unchanged, so we simply call our own "fake" d_alloc_root ++ */ ++static struct dentry *sdcardfs_d_alloc_root(struct super_block *sb) ++{ ++ struct dentry *ret = NULL; ++ ++ if (sb) { ++ static const struct qstr name = { ++ .name = "/", ++ .len = 1 ++ }; ++ ++ ret = d_alloc(NULL, &name); ++ if (ret) { ++ d_set_d_op(ret, &sdcardfs_ci_dops); ++ ret->d_sb = sb; ++ ret->d_parent = ret; ++ } ++ } ++ return ret; ++} ++#endif ++ ++DEFINE_MUTEX(sdcardfs_super_list_lock); ++EXPORT_SYMBOL_GPL(sdcardfs_super_list_lock); ++LIST_HEAD(sdcardfs_super_list); ++EXPORT_SYMBOL_GPL(sdcardfs_super_list); ++ ++struct sdcardfs_mount_private { ++ struct vfsmount *mnt; ++ const char *dev_name; ++ void *raw_data; ++}; ++ ++static int __sdcardfs_fill_super( ++ struct super_block *sb, ++ struct fs_context *fc) ++{ ++ int err = 0; ++ struct super_block *lower_sb; ++ struct path lower_path; ++ struct sdcardfs_sb_info *sb_info; ++ struct inode *inode; ++ const char *dev_name = fc->source; ++ struct sdcardfs_context_options *fcopts = fc->fs_private; ++ struct sdcardfs_mount_options *opts = &fcopts->opts; ++ struct sdcardfs_vfsmount_options *mntopts = &fcopts->vfsopts; ++ ++ pr_info("sdcardfs version 2.0\n"); ++ ++ if (!dev_name) { ++ pr_err("sdcardfs: read_super: missing dev_name argument\n"); ++ err = -EINVAL; ++ goto out; ++ } ++ ++ pr_info("sdcardfs: dev_name -> %s\n", dev_name); ++ pr_info("sdcardfs: gid=%d,mask=%x\n", mntopts->gid, mntopts->mask); ++ ++ /* parse lower path */ ++ err = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, ++ &lower_path); ++ if (err) { ++ pr_err("sdcardfs: error accessing lower directory '%s'\n", dev_name); ++ goto out; ++ } ++ ++ /* allocate superblock private data */ ++ sb->s_fs_info = kzalloc(sizeof(struct sdcardfs_sb_info), GFP_KERNEL); ++ if (!SDCARDFS_SB(sb)) { ++ pr_crit("sdcardfs: read_super: out of memory\n"); ++ err = -ENOMEM; ++ goto out_free; ++ } ++ ++ sb_info = sb->s_fs_info; ++ copy_sb_opts(&sb_info->options, fc); ++ if (opts->debug) { ++ pr_info("sdcardfs : options - debug:%d\n", opts->debug); ++ pr_info("sdcardfs : options - gid:%d\n", mntopts->gid); ++ pr_info("sdcardfs : options - mask:%d\n", mntopts->mask); ++ } ++ ++ /* set the lower superblock field of upper superblock */ ++ lower_sb = lower_path.dentry->d_sb; ++ atomic_inc(&lower_sb->s_active); ++ sdcardfs_set_lower_super(sb, lower_sb); ++ ++ sb->s_stack_depth = lower_sb->s_stack_depth + 1; ++ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { ++ pr_err("sdcardfs: maximum fs stacking depth exceeded\n"); ++ err = -EINVAL; ++ goto out_sput; ++ } ++ ++ /* inherit maxbytes from lower file system */ ++ sb->s_maxbytes = lower_sb->s_maxbytes; ++ ++ /* ++ * Our c/m/atime granularity is 1 ns because we may stack on file ++ * systems whose granularity is as good. ++ */ ++ sb->s_time_gran = 1; ++ ++ sb->s_magic = SDCARDFS_SUPER_MAGIC; ++ sb->s_op = &sdcardfs_sops; ++ ++ /* get a new inode and allocate our root dentry */ ++ inode = sdcardfs_iget(sb, d_inode(lower_path.dentry), 0); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ goto out_sput; ++ } ++ sb->s_root = d_make_root(inode); ++ if (!sb->s_root) { ++ err = -ENOMEM; ++ goto out_sput; ++ } ++ d_set_d_op(sb->s_root, &sdcardfs_ci_dops); ++ ++ /* link the upper and lower dentries */ ++ sb->s_root->d_fsdata = NULL; ++ err = new_dentry_private_data(sb->s_root); ++ if (err) ++ goto out_freeroot; ++ ++ /* set the lower dentries for s_root */ ++ sdcardfs_set_lower_path(sb->s_root, &lower_path); ++ ++ /* ++ * No need to call interpose because we already have a positive ++ * dentry, which was instantiated by d_make_root. Just need to ++ * d_rehash it. ++ */ ++ d_rehash(sb->s_root); ++ ++ /* setup permission policy */ ++ sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL); ++ mutex_lock(&sdcardfs_super_list_lock); ++ if (sb_info->options.multiuser) { ++ setup_derived_state(d_inode(sb->s_root), PERM_PRE_ROOT, ++ sb_info->options.fs_user_id, AID_ROOT); ++ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/obb", dev_name); ++ } else { ++ setup_derived_state(d_inode(sb->s_root), PERM_ROOT, ++ sb_info->options.fs_user_id, AID_ROOT); ++ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/Android/obb", dev_name); ++ } ++ fixup_tmp_permissions(d_inode(sb->s_root)); ++ sb_info->sb = sb; ++ list_add(&sb_info->list, &sdcardfs_super_list); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ ++ if (!(fc->sb_flags & SB_SILENT)) ++ pr_info("sdcardfs: mounted on top of %s type %s\n", ++ dev_name, lower_sb->s_type->name); ++ goto out; /* all is well */ ++ ++ /* no longer needed: free_dentry_private_data(sb->s_root); */ ++out_freeroot: ++ dput(sb->s_root); ++ sb->s_root = NULL; ++out_sput: ++ /* drop refs we took earlier */ ++ atomic_dec(&lower_sb->s_active); ++ kfree(SDCARDFS_SB(sb)); ++ sb->s_fs_info = NULL; ++out_free: ++ path_put(&lower_path); ++ ++out: ++ return err; ++} ++ ++static int sdcardfs_get_tree(struct fs_context *fc) ++{ ++ return vfs_get_super(fc, vfs_get_independent_super, ++ __sdcardfs_fill_super); ++} ++ ++void *sdcardfs_alloc_mnt_data(void) ++{ ++ return kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL); ++} ++ ++void sdcardfs_kill_sb(struct super_block *sb) ++{ ++ struct sdcardfs_sb_info *sbi; ++ ++ if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) { ++ sbi = SDCARDFS_SB(sb); ++ mutex_lock(&sdcardfs_super_list_lock); ++ list_del(&sbi->list); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ } ++ kill_anon_super(sb); ++} ++ ++static void sdcardfs_free_fs_context(struct fs_context *fc) ++{ ++ struct sdcardfs_context_options *fc_opts = fc->fs_private; ++ ++ kfree(fc_opts); ++} ++ ++/* Most of the remount happens in sdcardfs_update_mnt_data */ ++static int sdcardfs_reconfigure_context(struct fs_context *fc) ++{ ++ struct sdcardfs_context_options *fc_opts = fc->fs_private; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(fc->root->d_sb); ++ ++ sbi->options.debug = fc_opts->opts.debug; ++ if (sbi->options.debug) { ++ pr_info("sdcardfs : options - debug:%d\n", sbi->options.debug); ++ pr_info("sdcardfs : options - gid:%d\n", fc_opts->vfsopts.gid); ++ pr_info("sdcardfs : options - mask:%d\n", ++ fc_opts->vfsopts.mask); ++ } ++ return 0; ++} ++ ++/* reconfigure is handled by sdcardfs_update_mnt_data */ ++static const struct fs_context_operations sdcardfs_context_options_ops = { ++ ++ .parse_param = sdcardfs_parse_param, ++ .get_tree = sdcardfs_get_tree, ++ .free = sdcardfs_free_fs_context, ++ .reconfigure = sdcardfs_reconfigure_context, ++}; ++ ++static int sdcardfs_init_fs_context(struct fs_context *fc) ++{ ++ struct sdcardfs_context_options *fc_opts = ++ kmalloc(sizeof(struct sdcardfs_context_options), GFP_KERNEL); ++ ++ /* by default, we use AID_MEDIA_RW as uid, gid */ ++ fc_opts->opts.fs_low_uid = AID_MEDIA_RW; ++ fc_opts->opts.fs_low_gid = AID_MEDIA_RW; ++ fc_opts->opts.fs_user_id = 0; ++ fc_opts->vfsopts.gid = 0; ++ fc_opts->vfsopts.mask = 0; ++ ++ /* by default, 0MB is reserved */ ++ fc_opts->opts.reserved_mb = 0; ++ /* by default, gid derivation is off */ ++ fc_opts->opts.gid_derivation = false; ++ fc_opts->opts.default_normal = false; ++ fc_opts->opts.nocache = false; ++ fc_opts->opts.multiuser = false; ++ fc_opts->opts.debug = false; ++ ++ fc->fs_private = fc_opts; ++ fc->ops = &sdcardfs_context_options_ops; ++ return 0; ++} ++ ++static struct file_system_type sdcardfs_fs_type = { ++ .owner = THIS_MODULE, ++ .name = SDCARDFS_NAME, ++ .alloc_mnt_data = sdcardfs_alloc_mnt_data, ++ .kill_sb = sdcardfs_kill_sb, ++ .init_fs_context = sdcardfs_init_fs_context, ++ .fs_flags = 0, ++}; ++MODULE_ALIAS_FS(SDCARDFS_NAME); ++ ++static int __init init_sdcardfs_fs(void) ++{ ++ int err; ++ ++ pr_info("Registering sdcardfs " SDCARDFS_VERSION "\n"); ++ ++ err = sdcardfs_init_inode_cache(); ++ if (err) ++ goto out; ++ err = sdcardfs_init_dentry_cache(); ++ if (err) ++ goto out; ++ err = packagelist_init(); ++ if (err) ++ goto out; ++ err = register_filesystem(&sdcardfs_fs_type); ++out: ++ if (err) { ++ sdcardfs_destroy_inode_cache(); ++ sdcardfs_destroy_dentry_cache(); ++ packagelist_exit(); ++ } ++ return err; ++} ++ ++static void __exit exit_sdcardfs_fs(void) ++{ ++ sdcardfs_destroy_inode_cache(); ++ sdcardfs_destroy_dentry_cache(); ++ packagelist_exit(); ++ unregister_filesystem(&sdcardfs_fs_type); ++ pr_info("Completed sdcardfs module unload\n"); ++} ++ ++/* Original wrapfs authors */ ++MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University (http://www.fsl.cs.sunysb.edu/)"); ++ ++/* Original sdcardfs authors */ ++MODULE_AUTHOR("Woojoong Lee, Daeho Jeong, Kitae Lee, Yeongjin Gil System Memory Lab., Samsung Electronics"); ++ ++/* Current maintainer */ ++MODULE_AUTHOR("Daniel Rosenberg, Google"); ++MODULE_DESCRIPTION("Sdcardfs " SDCARDFS_VERSION); ++MODULE_LICENSE("GPL"); ++ ++module_init(init_sdcardfs_fs); ++module_exit(exit_sdcardfs_fs); +diff --git a/fs/sdcardfs/mmap.c b/fs/sdcardfs/mmap.c +new file mode 100644 +index 0000000000000..0ec0950c24471 +--- /dev/null ++++ b/fs/sdcardfs/mmap.c +@@ -0,0 +1,87 @@ ++/* ++ * fs/sdcardfs/mmap.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++ ++static vm_fault_t sdcardfs_fault(struct vm_fault *vmf) ++{ ++ vm_fault_t err; ++ struct file *file; ++ const struct vm_operations_struct *lower_vm_ops; ++ ++ file = (struct file *)vmf->vma->vm_private_data; ++ lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops; ++ BUG_ON(!lower_vm_ops); ++ ++ err = lower_vm_ops->fault(vmf); ++ return err; ++} ++ ++static void sdcardfs_vm_open(struct vm_area_struct *vma) ++{ ++ struct file *file = (struct file *)vma->vm_private_data; ++ ++ get_file(file); ++} ++ ++static void sdcardfs_vm_close(struct vm_area_struct *vma) ++{ ++ struct file *file = (struct file *)vma->vm_private_data; ++ ++ fput(file); ++} ++ ++static vm_fault_t sdcardfs_page_mkwrite(struct vm_fault *vmf) ++{ ++ vm_fault_t err = 0; ++ struct file *file; ++ const struct vm_operations_struct *lower_vm_ops; ++ ++ file = (struct file *)vmf->vma->vm_private_data; ++ lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops; ++ BUG_ON(!lower_vm_ops); ++ if (!lower_vm_ops->page_mkwrite) ++ goto out; ++ ++ err = lower_vm_ops->page_mkwrite(vmf); ++out: ++ return err; ++} ++ ++static ssize_t sdcardfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) ++{ ++ /* ++ * This function should never be called directly. We need it ++ * to exist, to get past a check in open_check_o_direct(), ++ * which is called from do_last(). ++ */ ++ return -EINVAL; ++} ++ ++const struct address_space_operations sdcardfs_aops = { ++ .direct_IO = sdcardfs_direct_IO, ++}; ++ ++const struct vm_operations_struct sdcardfs_vm_ops = { ++ .fault = sdcardfs_fault, ++ .page_mkwrite = sdcardfs_page_mkwrite, ++ .open = sdcardfs_vm_open, ++ .close = sdcardfs_vm_close, ++}; +diff --git a/fs/sdcardfs/multiuser.h b/fs/sdcardfs/multiuser.h +new file mode 100644 +index 0000000000000..85341e753f8c9 +--- /dev/null ++++ b/fs/sdcardfs/multiuser.h +@@ -0,0 +1,53 @@ ++/* ++ * fs/sdcardfs/multiuser.h ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */ ++#define AID_APP_START 10000 /* first app user */ ++#define AID_APP_END 19999 /* last app user */ ++#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */ ++#define AID_EXT_GID_START 30000 /* start of gids for apps to mark external data */ ++#define AID_EXT_CACHE_GID_START 40000 /* start of gids for apps to mark external cached data */ ++#define AID_EXT_CACHE_GID_END 49999 /* end of gids for apps to mark external cached data */ ++#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */ ++ ++typedef uid_t userid_t; ++typedef uid_t appid_t; ++ ++static inline uid_t multiuser_get_uid(userid_t user_id, appid_t app_id) ++{ ++ return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET); ++} ++ ++static inline bool uid_is_app(uid_t uid) ++{ ++ appid_t appid = uid % AID_USER_OFFSET; ++ ++ return appid >= AID_APP_START && appid <= AID_APP_END; ++} ++ ++static inline gid_t multiuser_get_ext_cache_gid(uid_t uid) ++{ ++ return uid - AID_APP_START + AID_EXT_CACHE_GID_START; ++} ++ ++static inline gid_t multiuser_get_ext_gid(uid_t uid) ++{ ++ return uid - AID_APP_START + AID_EXT_GID_START; ++} +diff --git a/fs/sdcardfs/packagelist.c b/fs/sdcardfs/packagelist.c +new file mode 100644 +index 0000000000000..4b9a5635f1e04 +--- /dev/null ++++ b/fs/sdcardfs/packagelist.c +@@ -0,0 +1,882 @@ ++/* ++ * fs/sdcardfs/packagelist.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include "sdcardfs.h" ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++struct hashtable_entry { ++ struct hlist_node hlist; ++ struct hlist_node dlist; /* for deletion cleanup */ ++ struct qstr key; ++ atomic_t value; ++}; ++ ++static DEFINE_HASHTABLE(package_to_appid, 8); ++static DEFINE_HASHTABLE(package_to_userid, 8); ++static DEFINE_HASHTABLE(ext_to_groupid, 8); ++ ++ ++static struct kmem_cache *hashtable_entry_cachep; ++ ++static unsigned int full_name_case_hash(const void *salt, const unsigned char *name, unsigned int len) ++{ ++ unsigned long hash = init_name_hash(salt); ++ ++ while (len--) ++ hash = partial_name_hash(tolower(*name++), hash); ++ return end_name_hash(hash); ++} ++ ++static inline void qstr_init(struct qstr *q, const char *name) ++{ ++ q->name = name; ++ q->len = strlen(q->name); ++ q->hash = full_name_case_hash(0, q->name, q->len); ++} ++ ++static inline int qstr_copy(const struct qstr *src, struct qstr *dest) ++{ ++ dest->name = kstrdup(src->name, GFP_KERNEL); ++ dest->hash_len = src->hash_len; ++ return !!dest->name; ++} ++ ++ ++static appid_t __get_appid(const struct qstr *key) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = key->hash; ++ appid_t ret_id; ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) { ++ ret_id = atomic_read(&hash_cur->value); ++ rcu_read_unlock(); ++ return ret_id; ++ } ++ } ++ rcu_read_unlock(); ++ return 0; ++} ++ ++appid_t get_appid(const char *key) ++{ ++ struct qstr q; ++ ++ qstr_init(&q, key); ++ return __get_appid(&q); ++} ++ ++static appid_t __get_ext_gid(const struct qstr *key) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = key->hash; ++ appid_t ret_id; ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) { ++ ret_id = atomic_read(&hash_cur->value); ++ rcu_read_unlock(); ++ return ret_id; ++ } ++ } ++ rcu_read_unlock(); ++ return 0; ++} ++ ++appid_t get_ext_gid(const char *key) ++{ ++ struct qstr q; ++ ++ qstr_init(&q, key); ++ return __get_ext_gid(&q); ++} ++ ++static appid_t __is_excluded(const struct qstr *app_name, userid_t user) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = app_name->hash; ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { ++ if (atomic_read(&hash_cur->value) == user && ++ qstr_case_eq(app_name, &hash_cur->key)) { ++ rcu_read_unlock(); ++ return 1; ++ } ++ } ++ rcu_read_unlock(); ++ return 0; ++} ++ ++appid_t is_excluded(const char *key, userid_t user) ++{ ++ struct qstr q; ++ qstr_init(&q, key); ++ return __is_excluded(&q, user); ++} ++ ++/* Kernel has already enforced everything we returned through ++ * derive_permissions_locked(), so this is used to lock down access ++ * even further, such as enforcing that apps hold sdcard_rw. ++ */ ++int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name) ++{ ++ struct qstr q_autorun = QSTR_LITERAL("autorun.inf"); ++ struct qstr q__android_secure = QSTR_LITERAL(".android_secure"); ++ struct qstr q_android_secure = QSTR_LITERAL("android_secure"); ++ ++ /* Always block security-sensitive files at root */ ++ if (parent_node && SDCARDFS_I(parent_node)->data->perm == PERM_ROOT) { ++ if (qstr_case_eq(name, &q_autorun) ++ || qstr_case_eq(name, &q__android_secure) ++ || qstr_case_eq(name, &q_android_secure)) { ++ return 0; ++ } ++ } ++ ++ /* Root always has access; access for any other UIDs should always ++ * be controlled through packages.list. ++ */ ++ if (from_kuid(&init_user_ns, current_fsuid()) == 0) ++ return 1; ++ ++ /* No extra permissions to enforce */ ++ return 1; ++} ++ ++static struct hashtable_entry *alloc_hashtable_entry(const struct qstr *key, ++ appid_t value) ++{ ++ struct hashtable_entry *ret = kmem_cache_alloc(hashtable_entry_cachep, ++ GFP_KERNEL); ++ if (!ret) ++ return NULL; ++ INIT_HLIST_NODE(&ret->dlist); ++ INIT_HLIST_NODE(&ret->hlist); ++ ++ if (!qstr_copy(key, &ret->key)) { ++ kmem_cache_free(hashtable_entry_cachep, ret); ++ return NULL; ++ } ++ ++ atomic_set(&ret->value, value); ++ return ret; ++} ++ ++static int insert_packagelist_appid_entry_locked(const struct qstr *key, appid_t value) ++{ ++ struct hashtable_entry *hash_cur; ++ struct hashtable_entry *new_entry; ++ unsigned int hash = key->hash; ++ ++ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) { ++ atomic_set(&hash_cur->value, value); ++ return 0; ++ } ++ } ++ new_entry = alloc_hashtable_entry(key, value); ++ if (!new_entry) ++ return -ENOMEM; ++ hash_add_rcu(package_to_appid, &new_entry->hlist, hash); ++ return 0; ++} ++ ++static int insert_ext_gid_entry_locked(const struct qstr *key, appid_t value) ++{ ++ struct hashtable_entry *hash_cur; ++ struct hashtable_entry *new_entry; ++ unsigned int hash = key->hash; ++ ++ /* An extension can only belong to one gid */ ++ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) ++ return -EINVAL; ++ } ++ new_entry = alloc_hashtable_entry(key, value); ++ if (!new_entry) ++ return -ENOMEM; ++ hash_add_rcu(ext_to_groupid, &new_entry->hlist, hash); ++ return 0; ++} ++ ++static int insert_userid_exclude_entry_locked(const struct qstr *key, userid_t value) ++{ ++ struct hashtable_entry *hash_cur; ++ struct hashtable_entry *new_entry; ++ unsigned int hash = key->hash; ++ ++ /* Only insert if not already present */ ++ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { ++ if (atomic_read(&hash_cur->value) == value && ++ qstr_case_eq(key, &hash_cur->key)) ++ return 0; ++ } ++ new_entry = alloc_hashtable_entry(key, value); ++ if (!new_entry) ++ return -ENOMEM; ++ hash_add_rcu(package_to_userid, &new_entry->hlist, hash); ++ return 0; ++} ++ ++static void fixup_all_perms_name(const struct qstr *key) ++{ ++ struct sdcardfs_sb_info *sbinfo; ++ struct limit_search limit = { ++ .flags = BY_NAME, ++ .name = QSTR_INIT(key->name, key->len), ++ }; ++ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { ++ if (sbinfo_has_sdcard_magic(sbinfo)) ++ fixup_perms_recursive(sbinfo->sb->s_root, &limit); ++ } ++} ++ ++static void fixup_all_perms_name_userid(const struct qstr *key, userid_t userid) ++{ ++ struct sdcardfs_sb_info *sbinfo; ++ struct limit_search limit = { ++ .flags = BY_NAME | BY_USERID, ++ .name = QSTR_INIT(key->name, key->len), ++ .userid = userid, ++ }; ++ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { ++ if (sbinfo_has_sdcard_magic(sbinfo)) ++ fixup_perms_recursive(sbinfo->sb->s_root, &limit); ++ } ++} ++ ++static void fixup_all_perms_userid(userid_t userid) ++{ ++ struct sdcardfs_sb_info *sbinfo; ++ struct limit_search limit = { ++ .flags = BY_USERID, ++ .userid = userid, ++ }; ++ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { ++ if (sbinfo_has_sdcard_magic(sbinfo)) ++ fixup_perms_recursive(sbinfo->sb->s_root, &limit); ++ } ++} ++ ++static int insert_packagelist_entry(const struct qstr *key, appid_t value) ++{ ++ int err; ++ ++ mutex_lock(&sdcardfs_super_list_lock); ++ err = insert_packagelist_appid_entry_locked(key, value); ++ if (!err) ++ fixup_all_perms_name(key); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ ++ return err; ++} ++ ++static int insert_ext_gid_entry(const struct qstr *key, appid_t value) ++{ ++ int err; ++ ++ mutex_lock(&sdcardfs_super_list_lock); ++ err = insert_ext_gid_entry_locked(key, value); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ ++ return err; ++} ++ ++static int insert_userid_exclude_entry(const struct qstr *key, userid_t value) ++{ ++ int err; ++ ++ mutex_lock(&sdcardfs_super_list_lock); ++ err = insert_userid_exclude_entry_locked(key, value); ++ if (!err) ++ fixup_all_perms_name_userid(key, value); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ ++ return err; ++} ++ ++static void free_hashtable_entry(struct hashtable_entry *entry) ++{ ++ kfree(entry->key.name); ++ kmem_cache_free(hashtable_entry_cachep, entry); ++} ++ ++static void remove_packagelist_entry_locked(const struct qstr *key) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = key->hash; ++ struct hlist_node *h_t; ++ HLIST_HEAD(free_list); ++ ++ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) { ++ hash_del_rcu(&hash_cur->hlist); ++ hlist_add_head(&hash_cur->dlist, &free_list); ++ } ++ } ++ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key)) { ++ hash_del_rcu(&hash_cur->hlist); ++ hlist_add_head(&hash_cur->dlist, &free_list); ++ break; ++ } ++ } ++ synchronize_rcu(); ++ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) ++ free_hashtable_entry(hash_cur); ++} ++ ++static void remove_packagelist_entry(const struct qstr *key) ++{ ++ mutex_lock(&sdcardfs_super_list_lock); ++ remove_packagelist_entry_locked(key); ++ fixup_all_perms_name(key); ++ mutex_unlock(&sdcardfs_super_list_lock); ++} ++ ++static void remove_ext_gid_entry_locked(const struct qstr *key, gid_t group) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = key->hash; ++ ++ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key) && atomic_read(&hash_cur->value) == group) { ++ hash_del_rcu(&hash_cur->hlist); ++ synchronize_rcu(); ++ free_hashtable_entry(hash_cur); ++ break; ++ } ++ } ++} ++ ++static void remove_ext_gid_entry(const struct qstr *key, gid_t group) ++{ ++ mutex_lock(&sdcardfs_super_list_lock); ++ remove_ext_gid_entry_locked(key, group); ++ mutex_unlock(&sdcardfs_super_list_lock); ++} ++ ++static void remove_userid_all_entry_locked(userid_t userid) ++{ ++ struct hashtable_entry *hash_cur; ++ struct hlist_node *h_t; ++ HLIST_HEAD(free_list); ++ int i; ++ ++ hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) { ++ if (atomic_read(&hash_cur->value) == userid) { ++ hash_del_rcu(&hash_cur->hlist); ++ hlist_add_head(&hash_cur->dlist, &free_list); ++ } ++ } ++ synchronize_rcu(); ++ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) { ++ free_hashtable_entry(hash_cur); ++ } ++} ++ ++static void remove_userid_all_entry(userid_t userid) ++{ ++ mutex_lock(&sdcardfs_super_list_lock); ++ remove_userid_all_entry_locked(userid); ++ fixup_all_perms_userid(userid); ++ mutex_unlock(&sdcardfs_super_list_lock); ++} ++ ++static void remove_userid_exclude_entry_locked(const struct qstr *key, userid_t userid) ++{ ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = key->hash; ++ ++ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(key, &hash_cur->key) && ++ atomic_read(&hash_cur->value) == userid) { ++ hash_del_rcu(&hash_cur->hlist); ++ synchronize_rcu(); ++ free_hashtable_entry(hash_cur); ++ break; ++ } ++ } ++} ++ ++static void remove_userid_exclude_entry(const struct qstr *key, userid_t userid) ++{ ++ mutex_lock(&sdcardfs_super_list_lock); ++ remove_userid_exclude_entry_locked(key, userid); ++ fixup_all_perms_name_userid(key, userid); ++ mutex_unlock(&sdcardfs_super_list_lock); ++} ++ ++static void packagelist_destroy(void) ++{ ++ struct hashtable_entry *hash_cur; ++ struct hlist_node *h_t; ++ HLIST_HEAD(free_list); ++ int i; ++ ++ mutex_lock(&sdcardfs_super_list_lock); ++ hash_for_each_rcu(package_to_appid, i, hash_cur, hlist) { ++ hash_del_rcu(&hash_cur->hlist); ++ hlist_add_head(&hash_cur->dlist, &free_list); ++ } ++ hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) { ++ hash_del_rcu(&hash_cur->hlist); ++ hlist_add_head(&hash_cur->dlist, &free_list); ++ } ++ synchronize_rcu(); ++ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) ++ free_hashtable_entry(hash_cur); ++ mutex_unlock(&sdcardfs_super_list_lock); ++ pr_info("sdcardfs: destroyed packagelist pkgld\n"); ++} ++ ++#define SDCARDFS_CONFIGFS_ATTR(_pfx, _name) \ ++static struct configfs_attribute _pfx##attr_##_name = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IRUGO | S_IWUGO, \ ++ .ca_owner = THIS_MODULE, \ ++ .show = _pfx##_name##_show, \ ++ .store = _pfx##_name##_store, \ ++} ++ ++#define SDCARDFS_CONFIGFS_ATTR_RO(_pfx, _name) \ ++static struct configfs_attribute _pfx##attr_##_name = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IRUGO, \ ++ .ca_owner = THIS_MODULE, \ ++ .show = _pfx##_name##_show, \ ++} ++ ++#define SDCARDFS_CONFIGFS_ATTR_WO(_pfx, _name) \ ++static struct configfs_attribute _pfx##attr_##_name = { \ ++ .ca_name = __stringify(_name), \ ++ .ca_mode = S_IWUGO, \ ++ .ca_owner = THIS_MODULE, \ ++ .store = _pfx##_name##_store, \ ++} ++ ++struct package_details { ++ struct config_item item; ++ struct qstr name; ++}; ++ ++static inline struct package_details *to_package_details(struct config_item *item) ++{ ++ return item ? container_of(item, struct package_details, item) : NULL; ++} ++ ++static ssize_t package_details_appid_show(struct config_item *item, char *page) ++{ ++ return scnprintf(page, PAGE_SIZE, "%u\n", __get_appid(&to_package_details(item)->name)); ++} ++ ++static ssize_t package_details_appid_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ unsigned int tmp; ++ int ret; ++ ++ ret = kstrtouint(page, 10, &tmp); ++ if (ret) ++ return ret; ++ ++ ret = insert_packagelist_entry(&to_package_details(item)->name, tmp); ++ ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static ssize_t package_details_excluded_userids_show(struct config_item *item, ++ char *page) ++{ ++ struct package_details *package_details = to_package_details(item); ++ struct hashtable_entry *hash_cur; ++ unsigned int hash = package_details->name.hash; ++ int count = 0; ++ ++ rcu_read_lock(); ++ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { ++ if (qstr_case_eq(&package_details->name, &hash_cur->key)) ++ count += scnprintf(page + count, PAGE_SIZE - count, ++ "%d ", atomic_read(&hash_cur->value)); ++ } ++ rcu_read_unlock(); ++ if (count) ++ count--; ++ count += scnprintf(page + count, PAGE_SIZE - count, "\n"); ++ return count; ++} ++ ++static ssize_t package_details_excluded_userids_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ unsigned int tmp; ++ int ret; ++ ++ ret = kstrtouint(page, 10, &tmp); ++ if (ret) ++ return ret; ++ ++ ret = insert_userid_exclude_entry(&to_package_details(item)->name, tmp); ++ ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static ssize_t package_details_clear_userid_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ unsigned int tmp; ++ int ret; ++ ++ ret = kstrtouint(page, 10, &tmp); ++ if (ret) ++ return ret; ++ remove_userid_exclude_entry(&to_package_details(item)->name, tmp); ++ return count; ++} ++ ++static void package_details_release(struct config_item *item) ++{ ++ struct package_details *package_details = to_package_details(item); ++ ++ pr_info("sdcardfs: removing %s\n", package_details->name.name); ++ remove_packagelist_entry(&package_details->name); ++ kfree(package_details->name.name); ++ kfree(package_details); ++} ++ ++SDCARDFS_CONFIGFS_ATTR(package_details_, appid); ++SDCARDFS_CONFIGFS_ATTR(package_details_, excluded_userids); ++SDCARDFS_CONFIGFS_ATTR_WO(package_details_, clear_userid); ++ ++static struct configfs_attribute *package_details_attrs[] = { ++ &package_details_attr_appid, ++ &package_details_attr_excluded_userids, ++ &package_details_attr_clear_userid, ++ NULL, ++}; ++ ++static struct configfs_item_operations package_details_item_ops = { ++ .release = package_details_release, ++}; ++ ++static struct config_item_type package_appid_type = { ++ .ct_item_ops = &package_details_item_ops, ++ .ct_attrs = package_details_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct extensions_value { ++ struct config_group group; ++ unsigned int num; ++}; ++ ++struct extension_details { ++ struct config_item item; ++ struct qstr name; ++ unsigned int num; ++}; ++ ++static inline struct extensions_value *to_extensions_value(struct config_item *item) ++{ ++ return item ? container_of(to_config_group(item), struct extensions_value, group) : NULL; ++} ++ ++static inline struct extension_details *to_extension_details(struct config_item *item) ++{ ++ return item ? container_of(item, struct extension_details, item) : NULL; ++} ++ ++static void extension_details_release(struct config_item *item) ++{ ++ struct extension_details *extension_details = to_extension_details(item); ++ ++ pr_info("sdcardfs: No longer mapping %s files to gid %d\n", ++ extension_details->name.name, extension_details->num); ++ remove_ext_gid_entry(&extension_details->name, extension_details->num); ++ kfree(extension_details->name.name); ++ kfree(extension_details); ++} ++ ++static struct configfs_item_operations extension_details_item_ops = { ++ .release = extension_details_release, ++}; ++ ++static struct config_item_type extension_details_type = { ++ .ct_item_ops = &extension_details_item_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *extension_details_make_item(struct config_group *group, const char *name) ++{ ++ struct extensions_value *extensions_value = to_extensions_value(&group->cg_item); ++ struct extension_details *extension_details = kzalloc(sizeof(struct extension_details), GFP_KERNEL); ++ const char *tmp; ++ int ret; ++ ++ if (!extension_details) ++ return ERR_PTR(-ENOMEM); ++ ++ tmp = kstrdup(name, GFP_KERNEL); ++ if (!tmp) { ++ kfree(extension_details); ++ return ERR_PTR(-ENOMEM); ++ } ++ qstr_init(&extension_details->name, tmp); ++ extension_details->num = extensions_value->num; ++ ret = insert_ext_gid_entry(&extension_details->name, extensions_value->num); ++ ++ if (ret) { ++ kfree(extension_details->name.name); ++ kfree(extension_details); ++ return ERR_PTR(ret); ++ } ++ config_item_init_type_name(&extension_details->item, name, &extension_details_type); ++ ++ return &extension_details->item; ++} ++ ++static struct configfs_group_operations extensions_value_group_ops = { ++ .make_item = extension_details_make_item, ++}; ++ ++static struct config_item_type extensions_name_type = { ++ .ct_group_ops = &extensions_value_group_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_group *extensions_make_group(struct config_group *group, const char *name) ++{ ++ struct extensions_value *extensions_value; ++ unsigned int tmp; ++ int ret; ++ ++ extensions_value = kzalloc(sizeof(struct extensions_value), GFP_KERNEL); ++ if (!extensions_value) ++ return ERR_PTR(-ENOMEM); ++ ret = kstrtouint(name, 10, &tmp); ++ if (ret) { ++ kfree(extensions_value); ++ return ERR_PTR(ret); ++ } ++ ++ extensions_value->num = tmp; ++ config_group_init_type_name(&extensions_value->group, name, ++ &extensions_name_type); ++ return &extensions_value->group; ++} ++ ++static void extensions_drop_group(struct config_group *group, struct config_item *item) ++{ ++ struct extensions_value *value = to_extensions_value(item); ++ ++ pr_info("sdcardfs: No longer mapping any files to gid %d\n", value->num); ++ kfree(value); ++} ++ ++static struct configfs_group_operations extensions_group_ops = { ++ .make_group = extensions_make_group, ++ .drop_item = extensions_drop_group, ++}; ++ ++static struct config_item_type extensions_type = { ++ .ct_group_ops = &extensions_group_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group extension_group = { ++ .cg_item = { ++ .ci_namebuf = "extensions", ++ .ci_type = &extensions_type, ++ }, ++}; ++ ++static struct config_item *packages_make_item(struct config_group *group, const char *name) ++{ ++ struct package_details *package_details; ++ const char *tmp; ++ ++ package_details = kzalloc(sizeof(struct package_details), GFP_KERNEL); ++ if (!package_details) ++ return ERR_PTR(-ENOMEM); ++ tmp = kstrdup(name, GFP_KERNEL); ++ if (!tmp) { ++ kfree(package_details); ++ return ERR_PTR(-ENOMEM); ++ } ++ qstr_init(&package_details->name, tmp); ++ config_item_init_type_name(&package_details->item, name, ++ &package_appid_type); ++ ++ return &package_details->item; ++} ++ ++static ssize_t packages_list_show(struct config_item *item, char *page) ++{ ++ struct hashtable_entry *hash_cur_app; ++ struct hashtable_entry *hash_cur_user; ++ int i; ++ int count = 0, written = 0; ++ const char errormsg[] = "\n"; ++ unsigned int hash; ++ ++ rcu_read_lock(); ++ hash_for_each_rcu(package_to_appid, i, hash_cur_app, hlist) { ++ written = scnprintf(page + count, PAGE_SIZE - sizeof(errormsg) - count, "%s %d\n", ++ hash_cur_app->key.name, atomic_read(&hash_cur_app->value)); ++ hash = hash_cur_app->key.hash; ++ hash_for_each_possible_rcu(package_to_userid, hash_cur_user, hlist, hash) { ++ if (qstr_case_eq(&hash_cur_app->key, &hash_cur_user->key)) { ++ written += scnprintf(page + count + written - 1, ++ PAGE_SIZE - sizeof(errormsg) - count - written + 1, ++ " %d\n", atomic_read(&hash_cur_user->value)) - 1; ++ } ++ } ++ if (count + written == PAGE_SIZE - sizeof(errormsg) - 1) { ++ count += scnprintf(page + count, PAGE_SIZE - count, errormsg); ++ break; ++ } ++ count += written; ++ } ++ rcu_read_unlock(); ++ ++ return count; ++} ++ ++static ssize_t packages_remove_userid_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ unsigned int tmp; ++ int ret; ++ ++ ret = kstrtouint(page, 10, &tmp); ++ if (ret) ++ return ret; ++ remove_userid_all_entry(tmp); ++ return count; ++} ++ ++static struct configfs_attribute packages_attr_packages_gid_list = { ++ .ca_name = "packages_gid.list", ++ .ca_mode = S_IRUGO, ++ .ca_owner = THIS_MODULE, ++ .show = packages_list_show, ++}; ++ ++SDCARDFS_CONFIGFS_ATTR_WO(packages_, remove_userid); ++ ++static struct configfs_attribute *packages_attrs[] = { ++ &packages_attr_packages_gid_list, ++ &packages_attr_remove_userid, ++ NULL, ++}; ++ ++/* ++ * Note that, since no extra work is required on ->drop_item(), ++ * no ->drop_item() is provided. ++ */ ++static struct configfs_group_operations packages_group_ops = { ++ .make_item = packages_make_item, ++}; ++ ++static struct config_item_type packages_type = { ++ .ct_group_ops = &packages_group_ops, ++ .ct_attrs = packages_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group *sd_default_groups[] = { ++ &extension_group, ++ NULL, ++}; ++ ++static struct configfs_subsystem sdcardfs_packages = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "sdcardfs", ++ .ci_type = &packages_type, ++ }, ++ }, ++}; ++ ++static int configfs_sdcardfs_init(void) ++{ ++ int ret, i; ++ struct configfs_subsystem *subsys = &sdcardfs_packages; ++ ++ config_group_init(&subsys->su_group); ++ for (i = 0; sd_default_groups[i]; i++) { ++ config_group_init(sd_default_groups[i]); ++ configfs_add_default_group(sd_default_groups[i], &subsys->su_group); ++ } ++ mutex_init(&subsys->su_mutex); ++ ret = configfs_register_subsystem(subsys); ++ if (ret) { ++ pr_err("Error %d while registering subsystem %s\n", ++ ret, ++ subsys->su_group.cg_item.ci_namebuf); ++ } ++ return ret; ++} ++ ++static void configfs_sdcardfs_exit(void) ++{ ++ configfs_unregister_subsystem(&sdcardfs_packages); ++} ++ ++int packagelist_init(void) ++{ ++ hashtable_entry_cachep = ++ kmem_cache_create("packagelist_hashtable_entry", ++ sizeof(struct hashtable_entry), 0, 0, NULL); ++ if (!hashtable_entry_cachep) { ++ pr_err("sdcardfs: failed creating pkgl_hashtable entry slab cache\n"); ++ return -ENOMEM; ++ } ++ ++ configfs_sdcardfs_init(); ++ return 0; ++} ++ ++void packagelist_exit(void) ++{ ++ configfs_sdcardfs_exit(); ++ packagelist_destroy(); ++ kmem_cache_destroy(hashtable_entry_cachep); ++} +diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h +new file mode 100644 +index 0000000000000..f813d23cddcdc +--- /dev/null ++++ b/fs/sdcardfs/sdcardfs.h +@@ -0,0 +1,662 @@ ++/* ++ * fs/sdcardfs/sdcardfs.h ++ * ++ * The sdcardfs v2.0 ++ * This file system replaces the sdcard daemon on Android ++ * On version 2.0, some of the daemon functions have been ported ++ * to support the multi-user concepts of Android 4.4 ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#ifndef _SDCARDFS_H_ ++#define _SDCARDFS_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "multiuser.h" ++ ++/* the file system name */ ++#define SDCARDFS_NAME "sdcardfs" ++ ++/* sdcardfs root inode number */ ++#define SDCARDFS_ROOT_INO 1 ++ ++/* useful for tracking code reachability */ ++#define UDBG pr_default("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__) ++ ++#define SDCARDFS_DIRENT_SIZE 256 ++ ++/* temporary static uid settings for development */ ++#define AID_ROOT 0 /* uid for accessing /mnt/sdcard & extSdcard */ ++#define AID_MEDIA_RW 1023 /* internal media storage write access */ ++ ++#define AID_SDCARD_RW 1015 /* external storage write access */ ++#define AID_SDCARD_R 1028 /* external storage read access */ ++#define AID_SDCARD_PICS 1033 /* external storage photos access */ ++#define AID_SDCARD_AV 1034 /* external storage audio/video access */ ++#define AID_SDCARD_ALL 1035 /* access all users external storage */ ++#define AID_MEDIA_OBB 1059 /* obb files */ ++ ++#define AID_SDCARD_IMAGE 1057 ++ ++#define AID_PACKAGE_INFO 1027 ++ ++ ++/* ++ * Permissions are handled by our permission function. ++ * We don't want anyone who happens to look at our inode value to prematurely ++ * block access, so store more permissive values. These are probably never ++ * used. ++ */ ++#define fixup_tmp_permissions(x) \ ++ do { \ ++ (x)->i_uid = make_kuid(&init_user_ns, \ ++ SDCARDFS_I(x)->data->d_uid); \ ++ (x)->i_gid = make_kgid(&init_user_ns, AID_SDCARD_RW); \ ++ (x)->i_mode = ((x)->i_mode & S_IFMT) | 0775;\ ++ } while (0) ++ ++/* Android 5.0 support */ ++ ++/* Permission mode for a specific node. Controls how file permissions ++ * are derived for children nodes. ++ */ ++typedef enum { ++ /* Nothing special; this node should just inherit from its parent. */ ++ PERM_INHERIT, ++ /* This node is one level above a normal root; used for legacy layouts ++ * which use the first level to represent user_id. ++ */ ++ PERM_PRE_ROOT, ++ /* This node is "/" */ ++ PERM_ROOT, ++ /* This node is "/Android" */ ++ PERM_ANDROID, ++ /* This node is "/Android/data" */ ++ PERM_ANDROID_DATA, ++ /* This node is "/Android/obb" */ ++ PERM_ANDROID_OBB, ++ /* This node is "/Android/media" */ ++ PERM_ANDROID_MEDIA, ++ /* This node is "/Android/[data|media|obb]/[package]" */ ++ PERM_ANDROID_PACKAGE, ++ /* This node is "/Android/[data|media|obb]/[package]/cache" */ ++ PERM_ANDROID_PACKAGE_CACHE, ++} perm_t; ++ ++struct sdcardfs_sb_info; ++struct sdcardfs_mount_options; ++struct sdcardfs_inode_info; ++struct sdcardfs_inode_data; ++ ++/* Do not directly use this function. Use OVERRIDE_CRED() instead. */ ++const struct cred *override_fsids(struct sdcardfs_sb_info *sbi, ++ struct sdcardfs_inode_data *data); ++/* Do not directly use this function, use REVERT_CRED() instead. */ ++void revert_fsids(const struct cred *old_cred); ++ ++/* operations vectors defined in specific files */ ++extern const struct file_operations sdcardfs_main_fops; ++extern const struct file_operations sdcardfs_dir_fops; ++extern const struct inode_operations sdcardfs_main_iops; ++extern const struct inode_operations sdcardfs_dir_iops; ++extern const struct inode_operations sdcardfs_symlink_iops; ++extern const struct super_operations sdcardfs_sops; ++extern const struct dentry_operations sdcardfs_ci_dops; ++extern const struct address_space_operations sdcardfs_aops, sdcardfs_dummy_aops; ++extern const struct vm_operations_struct sdcardfs_vm_ops; ++ ++extern int sdcardfs_init_inode_cache(void); ++extern void sdcardfs_destroy_inode_cache(void); ++extern int sdcardfs_init_dentry_cache(void); ++extern void sdcardfs_destroy_dentry_cache(void); ++extern int new_dentry_private_data(struct dentry *dentry); ++extern void free_dentry_private_data(struct dentry *dentry); ++extern struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags); ++extern struct inode *sdcardfs_iget(struct super_block *sb, ++ struct inode *lower_inode, userid_t id); ++extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb, ++ struct path *lower_path, userid_t id); ++ ++/* file private data */ ++struct sdcardfs_file_info { ++ struct file *lower_file; ++ const struct vm_operations_struct *lower_vm_ops; ++}; ++ ++struct sdcardfs_inode_data { ++ struct kref refcount; ++ bool abandoned; ++ ++ perm_t perm; ++ userid_t userid; ++ uid_t d_uid; ++ bool under_android; ++ bool under_cache; ++ bool under_obb; ++}; ++ ++/* sdcardfs inode data in memory */ ++struct sdcardfs_inode_info { ++ struct inode *lower_inode; ++ /* state derived based on current position in hierarchy */ ++ struct sdcardfs_inode_data *data; ++ ++ /* top folder for ownership */ ++ spinlock_t top_lock; ++ struct sdcardfs_inode_data *top_data; ++ ++ struct inode vfs_inode; ++}; ++ ++ ++/* sdcardfs dentry data in memory */ ++struct sdcardfs_dentry_info { ++ spinlock_t lock; /* protects lower_path */ ++ struct path lower_path; ++ struct path orig_path; ++}; ++ ++struct sdcardfs_mount_options { ++ uid_t fs_low_uid; ++ gid_t fs_low_gid; ++ userid_t fs_user_id; ++ bool multiuser; ++ bool gid_derivation; ++ bool default_normal; ++ bool unshared_obb; ++ unsigned int reserved_mb; ++ bool nocache; ++ bool debug; ++}; ++ ++struct sdcardfs_vfsmount_options { ++ gid_t gid; ++ mode_t mask; ++}; ++ ++struct sdcardfs_context_options { ++ struct sdcardfs_mount_options opts; ++ struct sdcardfs_vfsmount_options vfsopts; ++}; ++ ++extern int parse_options_remount(struct super_block *sb, char *options, int silent, ++ struct sdcardfs_vfsmount_options *vfsopts); ++ ++/* sdcardfs super-block data in memory */ ++struct sdcardfs_sb_info { ++ struct super_block *sb; ++ struct super_block *lower_sb; ++ /* derived perm policy : some of options have been added ++ * to sdcardfs_mount_options (Android 4.4 support) ++ */ ++ struct sdcardfs_mount_options options; ++ spinlock_t lock; /* protects obbpath */ ++ char *obbpath_s; ++ struct path obbpath; ++ void *pkgl_id; ++ struct list_head list; ++}; ++ ++/* ++ * inode to private data ++ * ++ * Since we use containers and the struct inode is _inside_ the ++ * sdcardfs_inode_info structure, SDCARDFS_I will always (given a non-NULL ++ * inode pointer), return a valid non-NULL pointer. ++ */ ++static inline struct sdcardfs_inode_info *SDCARDFS_I(const struct inode *inode) ++{ ++ return container_of(inode, struct sdcardfs_inode_info, vfs_inode); ++} ++ ++/* dentry to private data */ ++#define SDCARDFS_D(dent) ((struct sdcardfs_dentry_info *)(dent)->d_fsdata) ++ ++/* superblock to private data */ ++#define SDCARDFS_SB(super) ((struct sdcardfs_sb_info *)(super)->s_fs_info) ++ ++/* file to private Data */ ++#define SDCARDFS_F(file) ((struct sdcardfs_file_info *)((file)->private_data)) ++ ++/* file to lower file */ ++static inline struct file *sdcardfs_lower_file(const struct file *f) ++{ ++ return SDCARDFS_F(f)->lower_file; ++} ++ ++static inline void sdcardfs_set_lower_file(struct file *f, struct file *val) ++{ ++ SDCARDFS_F(f)->lower_file = val; ++} ++ ++/* inode to lower inode. */ ++static inline struct inode *sdcardfs_lower_inode(const struct inode *i) ++{ ++ return SDCARDFS_I(i)->lower_inode; ++} ++ ++static inline void sdcardfs_set_lower_inode(struct inode *i, struct inode *val) ++{ ++ SDCARDFS_I(i)->lower_inode = val; ++} ++ ++/* superblock to lower superblock */ ++static inline struct super_block *sdcardfs_lower_super( ++ const struct super_block *sb) ++{ ++ return SDCARDFS_SB(sb)->lower_sb; ++} ++ ++static inline void sdcardfs_set_lower_super(struct super_block *sb, ++ struct super_block *val) ++{ ++ SDCARDFS_SB(sb)->lower_sb = val; ++} ++ ++/* path based (dentry/mnt) macros */ ++static inline void pathcpy(struct path *dst, const struct path *src) ++{ ++ dst->dentry = src->dentry; ++ dst->mnt = src->mnt; ++} ++ ++/* sdcardfs_get_pname functions calls path_get() ++ * therefore, the caller must call "proper" path_put functions ++ */ ++#define SDCARDFS_DENT_FUNC(pname) \ ++static inline void sdcardfs_get_##pname(const struct dentry *dent, \ ++ struct path *pname) \ ++{ \ ++ spin_lock(&SDCARDFS_D(dent)->lock); \ ++ pathcpy(pname, &SDCARDFS_D(dent)->pname); \ ++ path_get(pname); \ ++ spin_unlock(&SDCARDFS_D(dent)->lock); \ ++ return; \ ++} \ ++static inline void sdcardfs_put_##pname(const struct dentry *dent, \ ++ struct path *pname) \ ++{ \ ++ path_put(pname); \ ++ return; \ ++} \ ++static inline void sdcardfs_set_##pname(const struct dentry *dent, \ ++ struct path *pname) \ ++{ \ ++ spin_lock(&SDCARDFS_D(dent)->lock); \ ++ pathcpy(&SDCARDFS_D(dent)->pname, pname); \ ++ spin_unlock(&SDCARDFS_D(dent)->lock); \ ++ return; \ ++} \ ++static inline void sdcardfs_reset_##pname(const struct dentry *dent) \ ++{ \ ++ spin_lock(&SDCARDFS_D(dent)->lock); \ ++ SDCARDFS_D(dent)->pname.dentry = NULL; \ ++ SDCARDFS_D(dent)->pname.mnt = NULL; \ ++ spin_unlock(&SDCARDFS_D(dent)->lock); \ ++ return; \ ++} \ ++static inline void sdcardfs_put_reset_##pname(const struct dentry *dent) \ ++{ \ ++ struct path pname; \ ++ spin_lock(&SDCARDFS_D(dent)->lock); \ ++ if (SDCARDFS_D(dent)->pname.dentry) { \ ++ pathcpy(&pname, &SDCARDFS_D(dent)->pname); \ ++ SDCARDFS_D(dent)->pname.dentry = NULL; \ ++ SDCARDFS_D(dent)->pname.mnt = NULL; \ ++ spin_unlock(&SDCARDFS_D(dent)->lock); \ ++ path_put(&pname); \ ++ } else \ ++ spin_unlock(&SDCARDFS_D(dent)->lock); \ ++ return; \ ++} ++ ++SDCARDFS_DENT_FUNC(lower_path) ++SDCARDFS_DENT_FUNC(orig_path) ++ ++static inline bool sbinfo_has_sdcard_magic(struct sdcardfs_sb_info *sbinfo) ++{ ++ return sbinfo && sbinfo->sb ++ && sbinfo->sb->s_magic == SDCARDFS_SUPER_MAGIC; ++} ++ ++static inline struct sdcardfs_inode_data *data_get( ++ struct sdcardfs_inode_data *data) ++{ ++ if (data) ++ kref_get(&data->refcount); ++ return data; ++} ++ ++static inline struct sdcardfs_inode_data *top_data_get( ++ struct sdcardfs_inode_info *info) ++{ ++ struct sdcardfs_inode_data *top_data; ++ ++ spin_lock(&info->top_lock); ++ top_data = data_get(info->top_data); ++ spin_unlock(&info->top_lock); ++ return top_data; ++} ++ ++extern void data_release(struct kref *ref); ++ ++static inline void data_put(struct sdcardfs_inode_data *data) ++{ ++ kref_put(&data->refcount, data_release); ++} ++ ++static inline void release_own_data(struct sdcardfs_inode_info *info) ++{ ++ /* ++ * This happens exactly once per inode. At this point, the inode that ++ * originally held this data is about to be freed, and all references ++ * to it are held as a top value, and will likely be released soon. ++ */ ++ info->data->abandoned = true; ++ data_put(info->data); ++} ++ ++static inline void set_top(struct sdcardfs_inode_info *info, ++ struct sdcardfs_inode_info *top_owner) ++{ ++ struct sdcardfs_inode_data *old_top; ++ struct sdcardfs_inode_data *new_top = NULL; ++ ++ if (top_owner) ++ new_top = top_data_get(top_owner); ++ ++ spin_lock(&info->top_lock); ++ old_top = info->top_data; ++ info->top_data = new_top; ++ if (old_top) ++ data_put(old_top); ++ spin_unlock(&info->top_lock); ++} ++ ++static inline int get_gid(struct vfsmount *mnt, ++ struct super_block *sb, ++ struct sdcardfs_inode_data *data) ++{ ++ struct sdcardfs_vfsmount_options *vfsopts = mnt->data; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(sb); ++ ++ if (vfsopts->gid == AID_SDCARD_RW && !sbi->options.default_normal) ++ /* As an optimization, certain trusted system components only run ++ * as owner but operate across all users. Since we're now handing ++ * out the sdcard_rw GID only to trusted apps, we're okay relaxing ++ * the user boundary enforcement for the default view. The UIDs ++ * assigned to app directories are still multiuser aware. ++ */ ++ return AID_SDCARD_RW; ++ else ++ return multiuser_get_uid(data->userid, vfsopts->gid); ++} ++ ++static inline int get_mode(struct vfsmount *mnt, ++ struct sdcardfs_inode_info *info, ++ struct sdcardfs_inode_data *data) ++{ ++ int owner_mode; ++ int filtered_mode; ++ struct sdcardfs_vfsmount_options *opts = mnt->data; ++ int visible_mode = 0775 & ~opts->mask; ++ ++ ++ if (data->perm == PERM_PRE_ROOT) { ++ /* Top of multi-user view should always be visible to ensure ++ * secondary users can traverse inside. ++ */ ++ visible_mode = 0711; ++ } else if (data->under_android) { ++ /* Block "other" access to Android directories, since only apps ++ * belonging to a specific user should be in there; we still ++ * leave +x open for the default view. ++ */ ++ if (opts->gid == AID_SDCARD_RW) ++ visible_mode = visible_mode & ~0006; ++ else ++ visible_mode = visible_mode & ~0007; ++ } ++ owner_mode = info->lower_inode->i_mode & 0700; ++ filtered_mode = visible_mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); ++ return filtered_mode; ++} ++ ++static inline int has_graft_path(const struct dentry *dent) ++{ ++ int ret = 0; ++ ++ spin_lock(&SDCARDFS_D(dent)->lock); ++ if (SDCARDFS_D(dent)->orig_path.dentry != NULL) ++ ret = 1; ++ spin_unlock(&SDCARDFS_D(dent)->lock); ++ ++ return ret; ++} ++ ++static inline void sdcardfs_get_real_lower(const struct dentry *dent, ++ struct path *real_lower) ++{ ++ /* in case of a local obb dentry ++ * the orig_path should be returned ++ */ ++ if (has_graft_path(dent)) ++ sdcardfs_get_orig_path(dent, real_lower); ++ else ++ sdcardfs_get_lower_path(dent, real_lower); ++} ++ ++static inline void sdcardfs_put_real_lower(const struct dentry *dent, ++ struct path *real_lower) ++{ ++ if (has_graft_path(dent)) ++ sdcardfs_put_orig_path(dent, real_lower); ++ else ++ sdcardfs_put_lower_path(dent, real_lower); ++} ++ ++extern struct mutex sdcardfs_super_list_lock; ++extern struct list_head sdcardfs_super_list; ++ ++/* for packagelist.c */ ++extern appid_t get_appid(const char *app_name); ++extern appid_t get_ext_gid(const char *app_name); ++extern appid_t is_excluded(const char *app_name, userid_t userid); ++extern int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name); ++extern int packagelist_init(void); ++extern void packagelist_exit(void); ++ ++/* for derived_perm.c */ ++#define BY_NAME (1 << 0) ++#define BY_USERID (1 << 1) ++struct limit_search { ++ unsigned int flags; ++ struct qstr name; ++ userid_t userid; ++}; ++ ++extern void setup_derived_state(struct inode *inode, perm_t perm, ++ userid_t userid, uid_t uid); ++extern void get_derived_permission(struct dentry *parent, struct dentry *dentry); ++extern void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const struct qstr *name); ++extern void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit); ++ ++extern void update_derived_permission_lock(struct dentry *dentry); ++void fixup_lower_ownership(struct dentry *dentry, const char *name); ++extern int need_graft_path(struct dentry *dentry); ++extern int is_base_obbpath(struct dentry *dentry); ++extern int is_obbpath_invalid(struct dentry *dentry); ++extern int setup_obb_dentry(struct dentry *dentry, struct path *lower_path); ++ ++/* locking helpers */ ++static inline struct dentry *lock_parent(struct dentry *dentry) ++{ ++ struct dentry *dir = dget_parent(dentry); ++ ++ inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); ++ return dir; ++} ++ ++static inline void unlock_dir(struct dentry *dir) ++{ ++ inode_unlock(d_inode(dir)); ++ dput(dir); ++} ++ ++static inline int prepare_dir(const char *path_s, uid_t uid, gid_t gid, mode_t mode) ++{ ++ int err; ++ struct dentry *dent; ++ struct iattr attrs; ++ struct path parent; ++ ++ dent = kern_path_locked(path_s, &parent); ++ if (IS_ERR(dent)) { ++ err = PTR_ERR(dent); ++ if (err == -EEXIST) ++ err = 0; ++ goto out_unlock; ++ } ++ ++ err = vfs_mkdir2(parent.mnt, d_inode(parent.dentry), dent, mode); ++ if (err) { ++ if (err == -EEXIST) ++ err = 0; ++ goto out_dput; ++ } ++ ++ attrs.ia_uid = make_kuid(&init_user_ns, uid); ++ attrs.ia_gid = make_kgid(&init_user_ns, gid); ++ attrs.ia_valid = ATTR_UID | ATTR_GID; ++ inode_lock(d_inode(dent)); ++ notify_change2(parent.mnt, dent, &attrs, NULL); ++ inode_unlock(d_inode(dent)); ++ ++out_dput: ++ dput(dent); ++ ++out_unlock: ++ /* parent dentry locked by lookup_create */ ++ inode_unlock(d_inode(parent.dentry)); ++ path_put(&parent); ++ return err; ++} ++ ++/* ++ * Return 1, if a disk has enough free space, otherwise 0. ++ * We assume that any files can not be overwritten. ++ */ ++static inline int check_min_free_space(struct dentry *dentry, size_t size, int dir) ++{ ++ int err; ++ struct path lower_path; ++ struct kstatfs statfs; ++ u64 avail; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ ++ if (sbi->options.reserved_mb) { ++ /* Get fs stat of lower filesystem. */ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ err = vfs_statfs(&lower_path, &statfs); ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ ++ if (unlikely(err)) ++ return 0; ++ ++ /* Invalid statfs informations. */ ++ if (unlikely(statfs.f_bsize == 0)) ++ return 0; ++ ++ /* if you are checking directory, set size to f_bsize. */ ++ if (unlikely(dir)) ++ size = statfs.f_bsize; ++ ++ /* available size */ ++ avail = statfs.f_bavail * statfs.f_bsize; ++ ++ /* not enough space */ ++ if ((u64)size > avail) ++ return 0; ++ ++ /* enough space */ ++ if ((avail - size) > (sbi->options.reserved_mb * 1024 * 1024)) ++ return 1; ++ ++ return 0; ++ } else ++ return 1; ++} ++ ++/* ++ * Copies attrs and maintains sdcardfs managed attrs ++ * Since our permission check handles all special permissions, set those to be open ++ */ ++static inline void sdcardfs_copy_and_fix_attrs(struct inode *dest, const struct inode *src) ++{ ++ dest->i_mode = (src->i_mode & S_IFMT) | S_IRWXU | S_IRWXG | ++ S_IROTH | S_IXOTH; /* 0775 */ ++ dest->i_uid = make_kuid(&init_user_ns, SDCARDFS_I(dest)->data->d_uid); ++ dest->i_gid = make_kgid(&init_user_ns, AID_SDCARD_RW); ++ dest->i_rdev = src->i_rdev; ++ dest->i_atime = src->i_atime; ++ dest->i_mtime = src->i_mtime; ++ dest->i_ctime = src->i_ctime; ++ dest->i_blkbits = src->i_blkbits; ++ dest->i_flags = src->i_flags; ++ set_nlink(dest, src->i_nlink); ++} ++ ++static inline bool str_case_eq(const char *s1, const char *s2) ++{ ++ return !strcasecmp(s1, s2); ++} ++ ++static inline bool str_n_case_eq(const char *s1, const char *s2, size_t len) ++{ ++ return !strncasecmp(s1, s2, len); ++} ++ ++static inline bool qstr_case_eq(const struct qstr *q1, const struct qstr *q2) ++{ ++ return q1->len == q2->len && str_n_case_eq(q1->name, q2->name, q2->len); ++} ++ ++#define QSTR_LITERAL(string) QSTR_INIT(string, sizeof(string)-1) ++ ++#endif /* not _SDCARDFS_H_ */ +diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c +new file mode 100644 +index 0000000000000..6b1d27e5067b4 +--- /dev/null ++++ b/fs/sdcardfs/super.c +@@ -0,0 +1,297 @@ ++/* ++ * fs/sdcardfs/super.c ++ * ++ * Copyright (c) 2013 Samsung Electronics Co. Ltd ++ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, ++ * Sunghwan Yun, Sungjong Seo ++ * ++ * This program has been developed as a stackable file system based on ++ * the WrapFS which written by ++ * ++ * Copyright (c) 1998-2011 Erez Zadok ++ * Copyright (c) 2009 Shrikar Archak ++ * Copyright (c) 2003-2011 Stony Brook University ++ * Copyright (c) 2003-2011 The Research Foundation of SUNY ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#include ++ ++#include "sdcardfs.h" ++ ++/* ++ * The inode cache is used with alloc_inode for both our inode info and the ++ * vfs inode. ++ */ ++static struct kmem_cache *sdcardfs_inode_cachep; ++ ++/* ++ * To support the top references, we must track some data separately. ++ * An sdcardfs_inode_info always has a reference to its data, and once set up, ++ * also has a reference to its top. The top may be itself, in which case it ++ * holds two references to its data. When top is changed, it takes a ref to the ++ * new data and then drops the ref to the old data. ++ */ ++static struct kmem_cache *sdcardfs_inode_data_cachep; ++ ++void data_release(struct kref *ref) ++{ ++ struct sdcardfs_inode_data *data = ++ container_of(ref, struct sdcardfs_inode_data, refcount); ++ ++ kmem_cache_free(sdcardfs_inode_data_cachep, data); ++} ++ ++/* final actions when unmounting a file system */ ++static void sdcardfs_put_super(struct super_block *sb) ++{ ++ struct sdcardfs_sb_info *spd; ++ struct super_block *s; ++ ++ spd = SDCARDFS_SB(sb); ++ if (!spd) ++ return; ++ ++ if (spd->obbpath_s) { ++ kfree(spd->obbpath_s); ++ path_put(&spd->obbpath); ++ } ++ ++ /* decrement lower super references */ ++ s = sdcardfs_lower_super(sb); ++ sdcardfs_set_lower_super(sb, NULL); ++ atomic_dec(&s->s_active); ++ ++ kfree(spd); ++ sb->s_fs_info = NULL; ++} ++ ++static int sdcardfs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ int err; ++ struct path lower_path; ++ u32 min_blocks; ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); ++ ++ sdcardfs_get_lower_path(dentry, &lower_path); ++ err = vfs_statfs(&lower_path, buf); ++ sdcardfs_put_lower_path(dentry, &lower_path); ++ ++ if (sbi->options.reserved_mb) { ++ /* Invalid statfs informations. */ ++ if (buf->f_bsize == 0) { ++ pr_err("Returned block size is zero.\n"); ++ return -EINVAL; ++ } ++ ++ min_blocks = ((sbi->options.reserved_mb * 1024 * 1024)/buf->f_bsize); ++ buf->f_blocks -= min_blocks; ++ ++ if (buf->f_bavail > min_blocks) ++ buf->f_bavail -= min_blocks; ++ else ++ buf->f_bavail = 0; ++ ++ /* Make reserved blocks invisiable to media storage */ ++ buf->f_bfree = buf->f_bavail; ++ } ++ ++ /* set return buf to our f/s to avoid confusing user-level utils */ ++ buf->f_type = SDCARDFS_SUPER_MAGIC; ++ ++ return err; ++} ++ ++static void *sdcardfs_clone_mnt_data(void *data) ++{ ++ struct sdcardfs_vfsmount_options *opt = kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL); ++ struct sdcardfs_vfsmount_options *old = data; ++ ++ if (!opt) ++ return NULL; ++ opt->gid = old->gid; ++ opt->mask = old->mask; ++ return opt; ++} ++ ++static void sdcardfs_copy_mnt_data(void *data, void *newdata) ++{ ++ struct sdcardfs_vfsmount_options *old = data; ++ struct sdcardfs_vfsmount_options *new = newdata; ++ ++ old->gid = new->gid; ++ old->mask = new->mask; ++} ++ ++static void sdcardfs_update_mnt_data(void *data, struct fs_context *fc) ++{ ++ struct sdcardfs_vfsmount_options *opts = data; ++ struct sdcardfs_context_options *fcopts = fc->fs_private; ++ ++ opts->gid = fcopts->vfsopts.gid; ++ opts->mask = fcopts->vfsopts.mask; ++} ++ ++/* ++ * Called by iput() when the inode reference count reached zero ++ * and the inode is not hashed anywhere. Used to clear anything ++ * that needs to be, before the inode is completely destroyed and put ++ * on the inode free list. ++ */ ++static void sdcardfs_evict_inode(struct inode *inode) ++{ ++ struct inode *lower_inode; ++ ++ truncate_inode_pages(&inode->i_data, 0); ++ set_top(SDCARDFS_I(inode), NULL); ++ clear_inode(inode); ++ /* ++ * Decrement a reference to a lower_inode, which was incremented ++ * by our read_inode when it was created initially. ++ */ ++ lower_inode = sdcardfs_lower_inode(inode); ++ sdcardfs_set_lower_inode(inode, NULL); ++ iput(lower_inode); ++} ++ ++static struct inode *sdcardfs_alloc_inode(struct super_block *sb) ++{ ++ struct sdcardfs_inode_info *i; ++ struct sdcardfs_inode_data *d; ++ ++ i = kmem_cache_alloc(sdcardfs_inode_cachep, GFP_KERNEL); ++ if (!i) ++ return NULL; ++ ++ /* memset everything up to the inode to 0 */ ++ memset(i, 0, offsetof(struct sdcardfs_inode_info, vfs_inode)); ++ ++ d = kmem_cache_alloc(sdcardfs_inode_data_cachep, ++ GFP_KERNEL | __GFP_ZERO); ++ if (!d) { ++ kmem_cache_free(sdcardfs_inode_cachep, i); ++ return NULL; ++ } ++ ++ i->data = d; ++ kref_init(&d->refcount); ++ i->top_data = d; ++ spin_lock_init(&i->top_lock); ++ kref_get(&d->refcount); ++ ++ inode_set_iversion(&i->vfs_inode, 1); ++ return &i->vfs_inode; ++} ++ ++static void i_callback(struct rcu_head *head) ++{ ++ struct inode *inode = container_of(head, struct inode, i_rcu); ++ ++ release_own_data(SDCARDFS_I(inode)); ++ kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode)); ++} ++ ++static void sdcardfs_destroy_inode(struct inode *inode) ++{ ++ call_rcu(&inode->i_rcu, i_callback); ++} ++ ++/* sdcardfs inode cache constructor */ ++static void init_once(void *obj) ++{ ++ struct sdcardfs_inode_info *i = obj; ++ ++ inode_init_once(&i->vfs_inode); ++} ++ ++int sdcardfs_init_inode_cache(void) ++{ ++ sdcardfs_inode_cachep = ++ kmem_cache_create("sdcardfs_inode_cache", ++ sizeof(struct sdcardfs_inode_info), 0, ++ SLAB_RECLAIM_ACCOUNT, init_once); ++ ++ if (!sdcardfs_inode_cachep) ++ return -ENOMEM; ++ ++ sdcardfs_inode_data_cachep = ++ kmem_cache_create("sdcardfs_inode_data_cache", ++ sizeof(struct sdcardfs_inode_data), 0, ++ SLAB_RECLAIM_ACCOUNT, NULL); ++ if (!sdcardfs_inode_data_cachep) { ++ kmem_cache_destroy(sdcardfs_inode_cachep); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++/* sdcardfs inode cache destructor */ ++void sdcardfs_destroy_inode_cache(void) ++{ ++ kmem_cache_destroy(sdcardfs_inode_data_cachep); ++ kmem_cache_destroy(sdcardfs_inode_cachep); ++} ++ ++/* ++ * Used only in nfs, to kill any pending RPC tasks, so that subsequent ++ * code can actually succeed and won't leave tasks that need handling. ++ */ ++static void sdcardfs_umount_begin(struct super_block *sb) ++{ ++ struct super_block *lower_sb; ++ ++ lower_sb = sdcardfs_lower_super(sb); ++ if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin) ++ lower_sb->s_op->umount_begin(lower_sb); ++} ++ ++static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m, ++ struct dentry *root) ++{ ++ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(root->d_sb); ++ struct sdcardfs_mount_options *opts = &sbi->options; ++ struct sdcardfs_vfsmount_options *vfsopts = mnt->data; ++ ++ if (opts->fs_low_uid != 0) ++ seq_printf(m, ",fsuid=%u", opts->fs_low_uid); ++ if (opts->fs_low_gid != 0) ++ seq_printf(m, ",fsgid=%u", opts->fs_low_gid); ++ if (vfsopts->gid != 0) ++ seq_printf(m, ",gid=%u", vfsopts->gid); ++ if (opts->multiuser) ++ seq_puts(m, ",multiuser"); ++ if (vfsopts->mask) ++ seq_printf(m, ",mask=%u", vfsopts->mask); ++ if (opts->fs_user_id) ++ seq_printf(m, ",userid=%u", opts->fs_user_id); ++ if (opts->gid_derivation) ++ seq_puts(m, ",derive_gid"); ++ if (opts->default_normal) ++ seq_puts(m, ",default_normal"); ++ if (opts->reserved_mb != 0) ++ seq_printf(m, ",reserved=%uMB", opts->reserved_mb); ++ if (opts->nocache) ++ seq_printf(m, ",nocache"); ++ if (opts->unshared_obb) ++ seq_printf(m, ",unshared_obb"); ++ ++ return 0; ++}; ++ ++const struct super_operations sdcardfs_sops = { ++ .put_super = sdcardfs_put_super, ++ .statfs = sdcardfs_statfs, ++ .clone_mnt_data = sdcardfs_clone_mnt_data, ++ .copy_mnt_data = sdcardfs_copy_mnt_data, ++ .update_mnt_data = sdcardfs_update_mnt_data, ++ .evict_inode = sdcardfs_evict_inode, ++ .umount_begin = sdcardfs_umount_begin, ++ .show_options2 = sdcardfs_show_options, ++ .alloc_inode = sdcardfs_alloc_inode, ++ .destroy_inode = sdcardfs_destroy_inode, ++ .drop_inode = generic_delete_inode, ++}; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sdcardfs-Define-magic-value.patch b/patches/ANDROID-sdcardfs-Define-magic-value.patch new file mode 100644 index 000000000000..e58ff70a603b --- /dev/null +++ b/patches/ANDROID-sdcardfs-Define-magic-value.patch @@ -0,0 +1,36 @@ +From b582c163e09912979d1dfb9dea896472d9e4f596 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Tue, 15 Nov 2016 13:35:18 -0800 +Subject: ANDROID: sdcardfs: Define magic value + +Define a filesystem magic value to be used for sdcardfs. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Change-Id: I54daa1452aa6a3ce0401d7d923e0a897f0c26d96 +Signed-off-by: Daniel Rosenberg +Signed-off-by: Yongqin Liu +--- + include/uapi/linux/magic.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h +index 1274c692e59c5..6220070d5bd4f 100644 +--- a/include/uapi/linux/magic.h ++++ b/include/uapi/linux/magic.h +@@ -57,6 +57,8 @@ + #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" + #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs" + ++#define SDCARDFS_SUPER_MAGIC 0x5dca2df5 ++ + #define SMB_SUPER_MAGIC 0x517B + #define CGROUP_SUPER_MAGIC 0x27e0eb + #define CGROUP2_SUPER_MAGIC 0x63677270 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch b/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch new file mode 100644 index 000000000000..2ef4738cefea --- /dev/null +++ b/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch @@ -0,0 +1,102 @@ +From e25917f2ecdbd269ac8c3486cd7e0ecc5fcc04f2 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Tue, 30 Jan 2018 14:24:02 -0800 +Subject: ANDROID: sdcardfs: Enable modular sdcardfs + +Export the following symbols: + +- copy_fs_struct +- free_fs_struct +- security_path_chown +- set_fs_pwd +- vfs_read +- vfs_write + +These are needed to build sdcardfs as a module. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Bug: 35142419 +Change-Id: If6e14f0b3bdc858a9f684e6c209927a9232091f0 +Signed-off-by: Daniel Rosenberg +Signed-off-by: Guenter Roeck +[astrachan: Folded the following changes into this patch: + e19f69662df5 ("ANDROID: Revert "fs: unexport vfs_read and vfs_write"") + 17071a8e1e7d ("ANDROID: fs: Export free_fs_struct and set_fs_pwd") + 2e9a639597cd ("ANDROID: export security_path_chown")] +Signed-off-by: Alistair Strachan +Signed-off-by: Yongqin Liu +--- + fs/fs_struct.c | 3 +++ + fs/read_write.c | 3 +++ + security/security.c | 1 + + 3 files changed, 7 insertions(+) + +diff --git a/fs/fs_struct.c b/fs/fs_struct.c +index ca639ed967b7a..57f9817a98081 100644 +--- a/fs/fs_struct.c ++++ b/fs/fs_struct.c +@@ -46,6 +46,7 @@ void set_fs_pwd(struct fs_struct *fs, const struct path *path) + if (old_pwd.dentry) + path_put(&old_pwd); + } ++EXPORT_SYMBOL(set_fs_pwd); + + static inline int replace_path(struct path *p, const struct path *old, const struct path *new) + { +@@ -91,6 +92,7 @@ void free_fs_struct(struct fs_struct *fs) + path_put(&fs->pwd); + kmem_cache_free(fs_cachep, fs); + } ++EXPORT_SYMBOL(free_fs_struct); + + void exit_fs(struct task_struct *tsk) + { +@@ -129,6 +131,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) + } + return fs; + } ++EXPORT_SYMBOL_GPL(copy_fs_struct); + + int unshare_fs_struct(void) + { +diff --git a/fs/read_write.c b/fs/read_write.c +index 5bbf587f5bc13..45929fe56cfa2 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -469,6 +469,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + return ret; + } + ++EXPORT_SYMBOL(vfs_read); ++ + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { + struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; +@@ -566,6 +568,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ + + return ret; + } ++EXPORT_SYMBOL(vfs_write); + + /* file_ppos returns &file->f_pos or NULL if file is stream */ + static inline loff_t *file_ppos(struct file *file) +diff --git a/security/security.c b/security/security.c +index 250ee2d76406d..968e460dd6ef9 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -1061,6 +1061,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) + return 0; + return call_int_hook(path_chown, 0, path, uid, gid); + } ++EXPORT_SYMBOL(security_path_chown); + + int security_path_chroot(const struct path *path) + { +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch b/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch new file mode 100644 index 000000000000..e68f389482a0 --- /dev/null +++ b/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch @@ -0,0 +1,27 @@ +From 99d6627322ece074491729ce1961b19880309bb5 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Tue, 27 Aug 2019 16:20:38 -0700 +Subject: ANDROID: sdcardfs: fix fall through in param parsing + +Fixes: commit bafafd3663c2e ("ANDROID: sdcardfs: Add sdcardfs filesystem") +Change-Id: I936ac03b999095d46810c0ca55a7a29cab52d82a +Signed-off-by: Daniel Rosenberg +--- + fs/sdcardfs/main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c +index b8e5cf2b9ae5b..818122410bfe3 100644 +--- a/fs/sdcardfs/main.c ++++ b/fs/sdcardfs/main.c +@@ -77,6 +77,7 @@ static int sdcardfs_parse_param(struct fs_context *fc, struct fs_parameter *para + switch (opt) { + case Opt_debug: + opts->debug = true; ++ break; + case Opt_fsuid: + opts->fs_low_uid = result.uint_32; + break; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-security-perf-Allow-further-restriction-of-p.patch b/patches/ANDROID-security-perf-Allow-further-restriction-of-p.patch new file mode 100644 index 000000000000..2fc117bc9942 --- /dev/null +++ b/patches/ANDROID-security-perf-Allow-further-restriction-of-p.patch @@ -0,0 +1,120 @@ +From a2d28f3dda77c4ee09da11a6d93f3f103e987684 Mon Sep 17 00:00:00 2001 +From: Jeff Vander Stoep +Date: Sun, 29 May 2016 14:22:32 -0700 +Subject: ANDROID: security,perf: Allow further restriction of + perf_event_open + +When kernel.perf_event_open is set to 3 (or greater), disallow all +access to performance events by users without CAP_SYS_ADMIN. +Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that +makes this value the default. + +This is based on a similar feature in grsecurity +(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making +the variable read-only. It also allows enabling further restriction +at run-time regardless of whether the default is changed. + +https://lkml.org/lkml/2016/1/11/587 + +Bug: 29054680 +Bug: 120445712 +Change-Id: Iff5bff4fc1042e85866df9faa01bce8d04335ab8 +[jeffv: Upstream doesn't want it https://lkml.org/lkml/2016/6/17/101] +Signed-off-by: Ben Hutchings +--- + Documentation/admin-guide/sysctl/kernel.rst | 5 ++++- + include/linux/perf_event.h | 5 +++++ + kernel/events/core.c | 8 ++++++++ + security/Kconfig | 9 +++++++++ + 4 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst +index 032c7cd3cede0..172fac5c58b16 100644 +--- a/Documentation/admin-guide/sysctl/kernel.rst ++++ b/Documentation/admin-guide/sysctl/kernel.rst +@@ -720,7 +720,8 @@ perf_event_paranoid: + ==================== + + Controls use of the performance events system by unprivileged +-users (without CAP_SYS_ADMIN). The default value is 2. ++users (without CAP_SYS_ADMIN). The default value is 3 if ++CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 2 otherwise. + + === ================================================================== + -1 Allow use of (almost) all events by all users +@@ -734,6 +735,8 @@ users (without CAP_SYS_ADMIN). The default value is 2. + >=1 Disallow CPU event access by users without CAP_SYS_ADMIN + + >=2 Disallow kernel profiling by users without CAP_SYS_ADMIN ++ ++>=3: Disallow all event access by users without CAP_SYS_ADMIN + === ================================================================== + + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index e8ad3c590a231..b60d7551208cd 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1227,6 +1227,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, + int perf_event_max_stack_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_paranoid > 2; ++} ++ + static inline bool perf_paranoid_tracepoint_raw(void) + { + return sysctl_perf_event_paranoid > -1; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 0463c1151baeb..0ce922009dd0c 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -398,8 +398,13 @@ static cpumask_var_t perf_online_mask; + * 0 - disallow raw tracepoint access for unpriv + * 1 - disallow cpu events for unpriv + * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use + */ ++#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT ++int sysctl_perf_event_paranoid __read_mostly = 3; ++#else + int sysctl_perf_event_paranoid __read_mostly = 2; ++#endif + + /* Minimum for 512 kiB + 1 user control page */ + int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ +@@ -10802,6 +10807,9 @@ SYSCALL_DEFINE5(perf_event_open, + if (flags & ~PERF_FLAG_ALL) + return -EINVAL; + ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ + err = perf_copy_attr(attr_uptr, &attr); + if (err) + return err; +diff --git a/security/Kconfig b/security/Kconfig +index 0d65594b51968..8e43a409fefa4 100644 +--- a/security/Kconfig ++++ b/security/Kconfig +@@ -19,6 +19,15 @@ config SECURITY_DMESG_RESTRICT + + If you are unsure how to answer this question, answer N. + ++config SECURITY_PERF_EVENTS_RESTRICT ++ bool "Restrict unprivileged use of performance events" ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the kernel.perf_event_paranoid sysctl ++ will be set to 3 by default, and no unprivileged use of the ++ perf_event_open syscall will be permitted unless it is ++ changed. ++ + config SECURITY + bool "Enable different security models" + depends on SYSFS +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-android-ion-Decouple-ION-page-poolin.patch b/patches/ANDROID-staging-android-ion-Decouple-ION-page-poolin.patch new file mode 100644 index 000000000000..b64430e6d918 --- /dev/null +++ b/patches/ANDROID-staging-android-ion-Decouple-ION-page-poolin.patch @@ -0,0 +1,184 @@ +From fd7beb888765525db4f2e57aebc1fa9ae25b416a Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Wed, 19 Jun 2019 15:37:15 -0700 +Subject: ANDROID: staging: android: ion: Decouple ION page + pooling from ION core + +Since page pooling is compiled together with the system heap, +and it is the only user, page pooling should not be a part +of the ION core. Thus, separate it out as a library, and +give it its own interface. + +Bug: 133508579 +Test: ion-unit-tests +Change-Id: I95909d250fc37a401d9e23264cd27c78a2a74637 +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.h | 51 -------------- + drivers/staging/android/ion/ion_page_pool.c | 2 +- + drivers/staging/android/ion/ion_page_pool.h | 66 +++++++++++++++++++ + drivers/staging/android/ion/ion_system_heap.c | 1 + + 4 files changed, 68 insertions(+), 52 deletions(-) + create mode 100644 drivers/staging/android/ion/ion_page_pool.h + +diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h +index e291299fd35ff..7929acb992f19 100644 +--- a/drivers/staging/android/ion/ion.h ++++ b/drivers/staging/android/ion/ion.h +@@ -257,55 +257,4 @@ size_t ion_heap_freelist_shrink(struct ion_heap *heap, + */ + size_t ion_heap_freelist_size(struct ion_heap *heap); + +-/** +- * functions for creating and destroying a heap pool -- allows you +- * to keep a pool of pre allocated memory to use from your heap. Keeping +- * a pool of memory that is ready for dma, ie any cached mapping have been +- * invalidated from the cache, provides a significant performance benefit on +- * many systems +- */ +- +-/** +- * struct ion_page_pool - pagepool struct +- * @high_count: number of highmem items in the pool +- * @low_count: number of lowmem items in the pool +- * @high_items: list of highmem items +- * @low_items: list of lowmem items +- * @mutex: lock protecting this struct and especially the count +- * item list +- * @gfp_mask: gfp_mask to use from alloc +- * @order: order of pages in the pool +- * @list: plist node for list of pools +- * +- * Allows you to keep a pool of pre allocated pages to use from your heap. +- * Keeping a pool of pages that is ready for dma, ie any cached mapping have +- * been invalidated from the cache, provides a significant performance benefit +- * on many systems +- */ +-struct ion_page_pool { +- int high_count; +- int low_count; +- struct list_head high_items; +- struct list_head low_items; +- struct mutex mutex; +- gfp_t gfp_mask; +- unsigned int order; +- struct plist_node list; +-}; +- +-struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); +-void ion_page_pool_destroy(struct ion_page_pool *pool); +-struct page *ion_page_pool_alloc(struct ion_page_pool *pool); +-void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); +- +-/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool +- * @pool: the pool +- * @gfp_mask: the memory type to reclaim +- * @nr_to_scan: number of items to shrink in pages +- * +- * returns the number of items freed in pages +- */ +-int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, +- int nr_to_scan); +- + #endif /* _ION_H */ +diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c +index f85ec5b16b65e..f1bc165e644e8 100644 +--- a/drivers/staging/android/ion/ion_page_pool.c ++++ b/drivers/staging/android/ion/ion_page_pool.c +@@ -10,7 +10,7 @@ + #include + #include + +-#include "ion.h" ++#include "ion_page_pool.h" + + static inline struct page *ion_page_pool_alloc_pages(struct ion_page_pool *pool) + { +diff --git a/drivers/staging/android/ion/ion_page_pool.h b/drivers/staging/android/ion/ion_page_pool.h +new file mode 100644 +index 0000000000000..e205d00868330 +--- /dev/null ++++ b/drivers/staging/android/ion/ion_page_pool.h +@@ -0,0 +1,66 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * ION Page Pool kernel interface header ++ * ++ * Copyright (C) 2011 Google, Inc. ++ */ ++ ++#ifndef _ION_PAGE_POOL_H ++#define _ION_PAGE_POOL_H ++ ++#include ++#include ++#include ++#include ++ ++/** ++ * functions for creating and destroying a heap pool -- allows you ++ * to keep a pool of pre allocated memory to use from your heap. Keeping ++ * a pool of memory that is ready for dma, ie any cached mapping have been ++ * invalidated from the cache, provides a significant performance benefit on ++ * many systems ++ */ ++ ++/** ++ * struct ion_page_pool - pagepool struct ++ * @high_count: number of highmem items in the pool ++ * @low_count: number of lowmem items in the pool ++ * @high_items: list of highmem items ++ * @low_items: list of lowmem items ++ * @mutex: lock protecting this struct and especially the count ++ * item list ++ * @gfp_mask: gfp_mask to use from alloc ++ * @order: order of pages in the pool ++ * @list: plist node for list of pools ++ * ++ * Allows you to keep a pool of pre allocated pages to use from your heap. ++ * Keeping a pool of pages that is ready for dma, ie any cached mapping have ++ * been invalidated from the cache, provides a significant performance benefit ++ * on many systems ++ */ ++struct ion_page_pool { ++ int high_count; ++ int low_count; ++ struct list_head high_items; ++ struct list_head low_items; ++ struct mutex mutex; ++ gfp_t gfp_mask; ++ unsigned int order; ++ struct plist_node list; ++}; ++ ++struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); ++void ion_page_pool_destroy(struct ion_page_pool *pool); ++struct page *ion_page_pool_alloc(struct ion_page_pool *pool); ++void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); ++ ++/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool ++ * @pool: the pool ++ * @gfp_mask: the memory type to reclaim ++ * @nr_to_scan: number of items to shrink in pages ++ * ++ * returns the number of items freed in pages ++ */ ++int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, ++ int nr_to_scan); ++#endif /* _ION_PAGE_POOL_H */ +diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c +index aa8d8425be25e..fbf5f39c22dbc 100644 +--- a/drivers/staging/android/ion/ion_system_heap.c ++++ b/drivers/staging/android/ion/ion_system_heap.c +@@ -15,6 +15,7 @@ + #include + + #include "ion.h" ++#include "ion_page_pool.h" + + #define NUM_ORDERS ARRAY_SIZE(orders) + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kern.patch b/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kern.patch new file mode 100644 index 000000000000..2a89f28e4c7b --- /dev/null +++ b/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kern.patch @@ -0,0 +1,151 @@ +From 7b0d47e8e10be2798d9f2d4906a476c23c214784 Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Wed, 19 Jun 2019 15:37:14 -0700 +Subject: ANDROID: staging: android: ion: Expose ion_alloc() to + kernel space + +Expose ion_alloc() to kernel space clients. Users of this +function will receive a dma-buf structure for sharing +the ION buffer that was allocated. + +Bug: 133508579 +Test: ion-unit-tests +Change-Id: I410044127ba92a759a79c65e422b0b75b74e2159 +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.c | 40 +++++++++++++++++++++++-------- + include/linux/ion.h | 26 ++++++++++++++++++++ + 2 files changed, 56 insertions(+), 10 deletions(-) + create mode 100644 include/linux/ion.h + +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index 92c2914239e30..d5716fb7b1551 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -3,6 +3,8 @@ + * ION Memory Allocator + * + * Copyright (C) 2011 Google, Inc. ++ * Copyright (c) 2019, The Linux Foundation. All rights reserved. ++ * + */ + + #include +@@ -387,13 +389,13 @@ static const struct dma_buf_ops dma_buf_ops = { + .unmap = ion_dma_buf_kunmap, + }; + +-static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) ++static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, ++ unsigned int flags) + { + struct ion_device *dev = internal_dev; + struct ion_buffer *buffer = NULL; + struct ion_heap *heap; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); +- int fd; + struct dma_buf *dmabuf; + + pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, +@@ -407,7 +409,7 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) + len = PAGE_ALIGN(len); + + if (!len) +- return -EINVAL; ++ return ERR_PTR(-EINVAL); + + down_read(&dev->lock); + plist_for_each_entry(heap, &dev->heaps, node) { +@@ -421,10 +423,10 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) + up_read(&dev->lock); + + if (!buffer) +- return -ENODEV; ++ return ERR_PTR(-ENODEV); + + if (IS_ERR(buffer)) +- return PTR_ERR(buffer); ++ return ERR_CAST(buffer); + + exp_info.ops = &dma_buf_ops; + exp_info.size = buffer->size; +@@ -432,10 +434,28 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) + exp_info.priv = buffer; + + dmabuf = dma_buf_export(&exp_info); +- if (IS_ERR(dmabuf)) { ++ if (IS_ERR(dmabuf)) + _ion_buffer_destroy(buffer); ++ ++ return dmabuf; ++} ++ ++struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, ++ unsigned int flags) ++{ ++ return ion_alloc_dmabuf(len, heap_id_mask, flags); ++} ++EXPORT_SYMBOL_GPL(ion_alloc); ++ ++static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, ++ unsigned int flags) ++{ ++ int fd; ++ struct dma_buf *dmabuf; ++ ++ dmabuf = ion_alloc_dmabuf(len, heap_id_mask, flags); ++ if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); +- } + + fd = dma_buf_fd(dmabuf, O_CLOEXEC); + if (fd < 0) +@@ -540,9 +560,9 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + int fd; + +- fd = ion_alloc(data.allocation.len, +- data.allocation.heap_id_mask, +- data.allocation.flags); ++ fd = ion_alloc_fd(data.allocation.len, ++ data.allocation.heap_id_mask, ++ data.allocation.flags); + if (fd < 0) + return fd; + +diff --git a/include/linux/ion.h b/include/linux/ion.h +new file mode 100644 +index 0000000000000..7bec77d98224c +--- /dev/null ++++ b/include/linux/ion.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2019, The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef _ION_KERNEL_H ++#define _ION_KERNEL_H ++ ++#include ++#include ++ ++#ifdef CONFIG_ION ++/* ++ * Allocates an ION buffer. ++ */ ++struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, ++ unsigned int flags); ++ ++#else ++static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, ++ unsigned int flags) ++{ ++ return ERR_PTR(-ENOMEM); ++} ++#endif /* CONFIG_ION */ ++#endif /* _ION_KERNEL_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dm.patch b/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dm.patch new file mode 100644 index 000000000000..be3b8c065476 --- /dev/null +++ b/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dm.patch @@ -0,0 +1,335 @@ +From 48cd3547a6ca514b29487db5ade842ef8015935e Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Sun, 1 Sep 2019 22:38:52 -0700 +Subject: ANDROID: staging: ion: Add support for heap-specific + dma_buf_ops + +All dma_buf ops are registered by ion core. However, if a given heap +provides a specific dmabuf operation, that will be preferred over the +default ion core implementation + +Some dma_buf_ops like get_flags, begin_cpu_access_partial etc are +entirely not supported by ion core and will return -EOPNOTSUPP if the +heap implementation doesn't provided the necessary overrides. + +Tested with ion unit test with default system heap. + +Bug: 133508579 +Bug: 140290587 +Test: ion-unit-test + +Change-Id: Id13c5c280064b6f47de327223733c2c393f1a41a +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion_dma_buf.c | 207 +++++++++++++++++----- + include/linux/ion.h | 2 + + 2 files changed, 163 insertions(+), 46 deletions(-) + +diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c +index 0de08e6f1af53..e52db6a182ae2 100644 +--- a/drivers/staging/android/ion/ion_dma_buf.c ++++ b/drivers/staging/android/ion/ion_dma_buf.c +@@ -6,7 +6,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -96,80 +95,68 @@ static void ion_dma_buf_detatch(struct dma_buf *dmabuf, + kfree(a); + } + +-static struct sg_table *ion_dma_buf_map(struct dma_buf_attachment *attachment, ++static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) + { +- struct ion_dma_buf_attachment *a = attachment->priv; ++ struct ion_buffer *buffer = attachment->dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ struct ion_dma_buf_attachment *a; + struct sg_table *table; + ++ if (heap->buf_ops.map_dma_buf) ++ return heap->buf_ops.map_dma_buf(attachment, direction); ++ ++ a = attachment->priv; + table = a->table; + +- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, +- direction)) ++ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, direction)) + return ERR_PTR(-ENOMEM); + + return table; + } + +-static void ion_dma_buf_unmap(struct dma_buf_attachment *attachment, ++static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) + { +- dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); +-} +- +-static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- int ret = 0; ++ struct ion_buffer *buffer = attachment->dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; + +- if (!buffer->heap->ops->map_user) { +- pr_err("%s: this heap does not define a method for mapping to userspace\n", +- __func__); +- return -EINVAL; +- } +- +- if (!(buffer->flags & ION_FLAG_CACHED)) +- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++ if (heap->buf_ops.unmap_dma_buf) ++ return heap->buf_ops.unmap_dma_buf(attachment, table, ++ direction); + +- mutex_lock(&buffer->lock); +- /* now map it to userspace */ +- ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); +- mutex_unlock(&buffer->lock); +- +- if (ret) +- pr_err("%s: failure mapping buffer to userspace\n", +- __func__); +- +- return ret; ++ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); + } + + static void ion_dma_buf_release(struct dma_buf *dmabuf) + { + struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; + +- ion_free(buffer); +-} +- +-static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) +-{ +- struct ion_buffer *buffer = dmabuf->priv; ++ if (heap->buf_ops.release) ++ return heap->buf_ops.release(dmabuf); + +- return buffer->vaddr + offset * PAGE_SIZE; ++ ion_free(buffer); + } + + static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) + { + struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; + void *vaddr; + struct ion_dma_buf_attachment *a; +- int ret = 0; ++ int ret; ++ ++ if (heap->buf_ops.begin_cpu_access) ++ return heap->buf_ops.begin_cpu_access(dmabuf, direction); + + /* + * TODO: Move this elsewhere because we don't always need a vaddr + */ +- if (buffer->heap->ops->map_kernel) { ++ ret = 0; ++ if (heap->ops->map_kernel) { + mutex_lock(&buffer->lock); + vaddr = ion_buffer_kmap_get(buffer); + if (IS_ERR(vaddr)) { +@@ -190,13 +177,36 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + return ret; + } + ++static int ++ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, ++ enum dma_data_direction direction, ++ unsigned int offset, unsigned int len) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ /* This is done to make sure partial buffer cache flush / invalidate is ++ * allowed. The implementation may be vendor specific in this case, so ++ * ion core does not provide a default implementation ++ */ ++ if (!heap->buf_ops.begin_cpu_access_partial) ++ return -EOPNOTSUPP; ++ ++ return heap->buf_ops.begin_cpu_access_partial(dmabuf, direction, offset, ++ len); ++} ++ + static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) + { + struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; + struct ion_dma_buf_attachment *a; + +- if (buffer->heap->ops->map_kernel) { ++ if (heap->buf_ops.end_cpu_access) ++ return heap->buf_ops.end_cpu_access(dmabuf, direction); ++ ++ if (heap->ops->map_kernel) { + mutex_lock(&buffer->lock); + ion_buffer_kmap_put(buffer); + mutex_unlock(&buffer->lock); +@@ -212,16 +222,121 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + return 0; + } + ++static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, ++ enum dma_data_direction direction, ++ unsigned int offset, ++ unsigned int len) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ /* This is done to make sure partial buffer cache flush / invalidate is ++ * allowed. The implementation may be vendor specific in this case, so ++ * ion core does not provide a default implementation ++ */ ++ if (!heap->buf_ops.end_cpu_access_partial) ++ return -EOPNOTSUPP; ++ ++ return heap->buf_ops.end_cpu_access_partial(dmabuf, direction, offset, ++ len); ++} ++ ++static void *ion_dma_buf_map(struct dma_buf *dmabuf, unsigned long offset) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ if (heap->buf_ops.map) ++ return heap->buf_ops.map(dmabuf, offset); ++ ++ return buffer->vaddr + offset * PAGE_SIZE; ++} ++ ++static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ int ret; ++ ++ /* now map it to userspace */ ++ if (heap->buf_ops.mmap) { ++ ret = heap->buf_ops.mmap(dmabuf, vma); ++ } else { ++ mutex_lock(&buffer->lock); ++ if (!(buffer->flags & ION_FLAG_CACHED)) ++ vma->vm_page_prot = ++ pgprot_writecombine(vma->vm_page_prot); ++ ++ ret = ion_heap_map_user(heap, buffer, vma); ++ mutex_unlock(&buffer->lock); ++ } ++ ++ if (ret) ++ pr_err("%s: failure mapping buffer to userspace\n", __func__); ++ ++ return ret; ++} ++ ++static void ion_dma_buf_unmap(struct dma_buf *dmabuf, unsigned long offset, ++ void *addr) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ if (!heap->buf_ops.unmap) ++ return; ++ heap->buf_ops.unmap(dmabuf, offset, addr); ++} ++ ++static void *ion_dma_buf_vmap(struct dma_buf *dmabuf) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ if (!heap->buf_ops.vmap) ++ return ERR_PTR(-EOPNOTSUPP); ++ ++ return heap->buf_ops.vmap(dmabuf); ++} ++ ++static void ion_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ if (!heap->buf_ops.vunmap) ++ return; ++ ++ return heap->buf_ops.vunmap(dmabuf, vaddr); ++} ++ ++static int ion_dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_heap *heap = buffer->heap; ++ ++ if (!heap->buf_ops.get_flags) ++ return -EOPNOTSUPP; ++ ++ return heap->buf_ops.get_flags(dmabuf, flags); ++} ++ + static const struct dma_buf_ops dma_buf_ops = { +- .map_dma_buf = ion_dma_buf_map, +- .unmap_dma_buf = ion_dma_buf_unmap, +- .mmap = ion_dma_buf_mmap, +- .release = ion_dma_buf_release, + .attach = ion_dma_buf_attach, + .detach = ion_dma_buf_detatch, ++ .map_dma_buf = ion_map_dma_buf, ++ .unmap_dma_buf = ion_unmap_dma_buf, ++ .release = ion_dma_buf_release, + .begin_cpu_access = ion_dma_buf_begin_cpu_access, ++ .begin_cpu_access_partial = ion_dma_buf_begin_cpu_access_partial, + .end_cpu_access = ion_dma_buf_end_cpu_access, +- .map = ion_dma_buf_kmap, ++ .end_cpu_access_partial = ion_dma_buf_end_cpu_access_partial, ++ .mmap = ion_dma_buf_mmap, ++ .map = ion_dma_buf_map, ++ .unmap = ion_dma_buf_unmap, ++ .vmap = ion_dma_buf_vmap, ++ .vunmap = ion_dma_buf_vunmap, ++ .get_flags = ion_dma_buf_get_flags, + }; + + struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, +diff --git a/include/linux/ion.h b/include/linux/ion.h +index 5d68674b015a9..1e4846db0c6d4 100644 +--- a/include/linux/ion.h ++++ b/include/linux/ion.h +@@ -101,6 +101,7 @@ struct ion_heap_ops { + * @node: rb node to put the heap on the device's tree of heaps + * @type: type of heap + * @ops: ops struct as above ++ * @buf_ops: dma_buf ops specific to the heap implementation. + * @flags: flags + * @id: id of heap, also indicates priority of this heap when + * allocating. These are specified by platform data and +@@ -126,6 +127,7 @@ struct ion_heap { + struct plist_node node; + enum ion_heap_type type; + struct ion_heap_ops *ops; ++ struct dma_buf_ops buf_ops; + unsigned long flags; + unsigned int id; + const char *name; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-Build-fix-for-mips.patch b/patches/ANDROID-staging-ion-Build-fix-for-mips.patch new file mode 100644 index 000000000000..702c5ae74f63 --- /dev/null +++ b/patches/ANDROID-staging-ion-Build-fix-for-mips.patch @@ -0,0 +1,27 @@ +From 9c52f16472a6ea98c17a2e54714f355043c565d4 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Mon, 19 Aug 2019 18:27:29 -0700 +Subject: ANDROID: staging: ion: Build fix for mips + +Bug: 133508579 +Change-Id: Ie795483ace50537029921d86347f38bd1e5ee58a +Signed-off-by: Alistair Delva +--- + drivers/staging/android/ion/ion_buffer.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c +index 879b3ddb08c0f..961605a35c595 100644 +--- a/drivers/staging/android/ion/ion_buffer.c ++++ b/drivers/staging/android/ion/ion_buffer.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include "ion_private.h" + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warni.patch b/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warni.patch new file mode 100644 index 000000000000..588d74755f76 --- /dev/null +++ b/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warni.patch @@ -0,0 +1,51 @@ +From cb1974a4adab06f310cd400c3f8cf397bb91bdc1 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Fri, 30 Aug 2019 14:46:57 -0700 +Subject: ANDROID: staging: ion: Fix uninitialized variable + warning + +Warning: + In file included from include/linux/bitops.h:19:0, + from include/linux/bitmap.h:8, + from drivers/staging/android/ion/ion.c:10: + drivers/staging/android/ion/ion.c: In function '__ion_device_add_heap': +>> arch/m68k/include/asm/bitops.h:371:28: warning: 'end_bit' may be used uninitialized in this function [-Wmaybe-uninitialized] + #define find_next_zero_bit find_next_zero_bit + ^~~~~~~~~~~~~~~~~~ + drivers/staging/android/ion/ion.c:228:17: note: 'end_bit' was declared here + int start_bit, end_bit; + ^~~~~~~ + In file included from include/linux/bitops.h:19:0, + from include/linux/bitmap.h:8, + from drivers/staging/android/ion/ion.c:10: +>> arch/m68k/include/asm/bitops.h:354:10: warning: 'start_bit' may be used uninitialized in this function [-Wmaybe-uninitialized] + offset -= bit; + ~~~~~~~^~~~~~ + drivers/staging/android/ion/ion.c:228:6: note: 'start_bit' was declared here + int start_bit, end_bit; + ^~~~~~~~~ + +Change-Id: I2df4a5b36f457aca5f19c03976ae7229c35ecdb3 +Reported-by: kbuild test robot +Fixes: acbfdf321afb ("ANDROID: staging: ion: add support for consistent heap ids") +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index 948b37f74f2b2..4631953b9c964 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -225,7 +225,7 @@ DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, + static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) + { + int id_bit; +- int start_bit, end_bit; ++ int start_bit, end_bit = -1; + + switch (heap->type) { + case ION_HEAP_TYPE_SYSTEM: +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch b/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch new file mode 100644 index 000000000000..6ed8af3b402b --- /dev/null +++ b/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch @@ -0,0 +1,180 @@ +From 5be53e77c4d1c55856291f2c4de1648a0d9cbe73 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Sun, 1 Sep 2019 23:02:37 -0700 +Subject: ANDROID: staging: ion: Remove unnecessary ion heap + ops + +The heap operations are redundant now that we have default +dma_buf operations. So, remove them. + +Bug: 133508579 +Bug: 140290587 +Test: ion-unit-tests + +Change-Id: I8f87c22896e128f48ed222421cabc23ab238ff69 +Signed-off-by: Sandeep Patil +--- + .../staging/android/ion/heaps/ion_cma_heap.c | 3 --- + .../ion/heaps/ion_system_contig_heap.c | 3 --- + .../android/ion/heaps/ion_system_heap.c | 3 --- + drivers/staging/android/ion/ion_buffer.c | 6 ++--- + drivers/staging/android/ion/ion_dma_buf.c | 25 +++++++------------ + include/linux/ion.h | 9 +------ + 6 files changed, 13 insertions(+), 36 deletions(-) + +Index: common/drivers/staging/android/ion/heaps/ion_cma_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/heaps/ion_cma_heap.c ++++ common/drivers/staging/android/ion/heaps/ion_cma_heap.c +@@ -95,9 +95,6 @@ static void ion_cma_free(struct ion_buff + static struct ion_heap_ops ion_cma_ops = { + .allocate = ion_cma_allocate, + .free = ion_cma_free, +- .map_user = ion_heap_map_user, +- .map_kernel = ion_heap_map_kernel, +- .unmap_kernel = ion_heap_unmap_kernel, + }; + + static struct ion_heap *__ion_cma_heap_create(struct cma *cma) +Index: common/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/heaps/ion_system_contig_heap.c ++++ common/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +@@ -77,9 +77,6 @@ static void ion_system_contig_heap_free( + static struct ion_heap_ops kmalloc_ops = { + .allocate = ion_system_contig_heap_allocate, + .free = ion_system_contig_heap_free, +- .map_kernel = ion_heap_map_kernel, +- .unmap_kernel = ion_heap_unmap_kernel, +- .map_user = ion_heap_map_user, + }; + + static struct ion_heap contig_heap = { +Index: common/drivers/staging/android/ion/heaps/ion_system_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/heaps/ion_system_heap.c ++++ common/drivers/staging/android/ion/heaps/ion_system_heap.c +@@ -241,9 +241,6 @@ err_create_pool: + static struct ion_heap_ops system_heap_ops = { + .allocate = ion_system_heap_allocate, + .free = ion_system_heap_free, +- .map_kernel = ion_heap_map_kernel, +- .unmap_kernel = ion_heap_unmap_kernel, +- .map_user = ion_heap_map_user, + .shrink = ion_system_heap_shrink, + }; + +Index: common/drivers/staging/android/ion/ion_buffer.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_buffer.c ++++ common/drivers/staging/android/ion/ion_buffer.c +@@ -201,7 +201,7 @@ void ion_buffer_release(struct ion_buffe + if (buffer->kmap_cnt > 0) { + pr_warn_once("%s: buffer still mapped in the kernel\n", + __func__); +- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); ++ ion_heap_unmap_kernel(buffer->heap, buffer); + } + buffer->heap->ops->free(buffer); + spin_lock(&buffer->heap->stat_lock); +@@ -245,7 +245,7 @@ void *ion_buffer_kmap_get(struct ion_buf + buffer->kmap_cnt++; + return buffer->vaddr; + } +- vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); ++ vaddr = ion_heap_map_kernel(buffer->heap, buffer); + if (WARN_ONCE(!vaddr, + "heap->ops->map_kernel should return ERR_PTR on error")) + return ERR_PTR(-EINVAL); +@@ -260,7 +260,7 @@ void ion_buffer_kmap_put(struct ion_buff + { + buffer->kmap_cnt--; + if (!buffer->kmap_cnt) { +- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); ++ ion_heap_unmap_kernel(buffer->heap, buffer); + buffer->vaddr = NULL; + } + } +Index: common/drivers/staging/android/ion/ion_dma_buf.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_dma_buf.c ++++ common/drivers/staging/android/ion/ion_dma_buf.c +@@ -154,19 +154,16 @@ static int ion_dma_buf_begin_cpu_access( + + /* + * TODO: Move this elsewhere because we don't always need a vaddr ++ * FIXME: Why do we need a vaddr here? + */ + ret = 0; +- if (heap->ops->map_kernel) { +- mutex_lock(&buffer->lock); +- vaddr = ion_buffer_kmap_get(buffer); +- if (IS_ERR(vaddr)) { +- ret = PTR_ERR(vaddr); +- goto unlock; +- } +- mutex_unlock(&buffer->lock); ++ mutex_lock(&buffer->lock); ++ vaddr = ion_buffer_kmap_get(buffer); ++ if (IS_ERR(vaddr)) { ++ ret = PTR_ERR(vaddr); ++ goto unlock; + } + +- mutex_lock(&buffer->lock); + list_for_each_entry(a, &buffer->attachments, list) { + dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, + direction); +@@ -206,13 +203,9 @@ static int ion_dma_buf_end_cpu_access(st + if (heap->buf_ops.end_cpu_access) + return heap->buf_ops.end_cpu_access(dmabuf, direction); + +- if (heap->ops->map_kernel) { +- mutex_lock(&buffer->lock); +- ion_buffer_kmap_put(buffer); +- mutex_unlock(&buffer->lock); +- } +- + mutex_lock(&buffer->lock); ++ ++ ion_buffer_kmap_put(buffer); + list_for_each_entry(a, &buffer->attachments, list) { + dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, + direction); +@@ -249,7 +242,7 @@ static void *ion_dma_buf_map(struct dma_ + if (heap->buf_ops.map) + return heap->buf_ops.map(dmabuf, offset); + +- return buffer->vaddr + offset * PAGE_SIZE; ++ return ion_buffer_kmap_get(buffer) + offset * PAGE_SIZE; + } + + static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +Index: common/include/linux/ion.h +=================================================================== +--- common.orig/include/linux/ion.h ++++ common/include/linux/ion.h +@@ -57,11 +57,8 @@ struct ion_buffer { + * struct ion_heap_ops - ops to operate on a given heap + * @allocate: allocate memory + * @free: free memory +- * @map_kernel map memory to the kernel +- * @unmap_kernel unmap memory to the kernel +- * @map_user map memory to userspace + * +- * allocate, phys, and map_user return 0 on success, -errno on error. ++ * allocate returns 0 on success, -errno on error. + * map_dma and map_kernel return pointer on success, ERR_PTR on + * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in + * the buffer's private_flags when called from a shrinker. In that +@@ -73,10 +70,6 @@ struct ion_heap_ops { + struct ion_buffer *buffer, unsigned long len, + unsigned long flags); + void (*free)(struct ion_buffer *buffer); +- void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); +- void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); +- int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, +- struct vm_area_struct *vma); + int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); + }; + diff --git a/patches/ANDROID-staging-ion-add-support-for-consistent-heap-.patch b/patches/ANDROID-staging-ion-add-support-for-consistent-heap-.patch new file mode 100644 index 000000000000..65381ded6e70 --- /dev/null +++ b/patches/ANDROID-staging-ion-add-support-for-consistent-heap-.patch @@ -0,0 +1,180 @@ +From 949253620b7bbede9397b7f799e276a1d420ed14 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 26 Aug 2019 22:46:07 -0700 +Subject: ANDROID: staging: ion: add support for consistent + heap ids + +heap id is part of ION's UAPI. Since the heaps are now kernel modules, +the current scheme of incrementing the heap id for the next heap doesn't +work. For example, if one insert->remove->insert the system heap module, +the heap id associated with the system heap changes. This immediately +breaks all of userspace. + +So, in order to fix this, we reserve first 16 heap ids for GKI heaps +and leave 16 more heap ids for any custom heap type that may exist. + +Bug: 133508579 +Test: ion-unit-test +Test: ion-unit-test (after removal and insertion of system heap module) + +Change-Id: I8412e590263869e029151a017b072399f54206f0 +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.c | 79 ++++++++++++++++++++++- + drivers/staging/android/ion/ion_private.h | 5 +- + 2 files changed, 80 insertions(+), 4 deletions(-) + +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index e4586eb6cae34..948b37f74f2b2 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -7,6 +7,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -27,7 +28,6 @@ + #include "ion_private.h" + + static struct ion_device *internal_dev; +-static int heap_id; + + /* Entry into ION allocator for rest of the kernel */ + struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, +@@ -222,6 +222,69 @@ static int debug_shrink_get(void *data, u64 *val) + DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, + debug_shrink_set, "%llu\n"); + ++static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) ++{ ++ int id_bit; ++ int start_bit, end_bit; ++ ++ switch (heap->type) { ++ case ION_HEAP_TYPE_SYSTEM: ++ id_bit = ffs(ION_HEAP_SYSTEM); ++ break; ++ case ION_HEAP_TYPE_SYSTEM_CONTIG: ++ id_bit = ffs(ION_HEAP_SYSTEM_CONTIG); ++ break; ++ case ION_HEAP_TYPE_CHUNK: ++ id_bit = ffs(ION_HEAP_CHUNK); ++ break; ++ case ION_HEAP_TYPE_CARVEOUT: ++ id_bit = 0; ++ start_bit = ffs(ION_HEAP_CARVEOUT_START); ++ end_bit = ffs(ION_HEAP_CARVEOUT_END); ++ break; ++ case ION_HEAP_TYPE_DMA: ++ id_bit = 0; ++ start_bit = ffs(ION_HEAP_DMA_START); ++ end_bit = ffs(ION_HEAP_DMA_END); ++ break; ++ case ION_HEAP_TYPE_CUSTOM ... ION_HEAP_TYPE_MAX: ++ id_bit = 0; ++ start_bit = ffs(ION_HEAP_CUSTOM_START); ++ end_bit = ffs(ION_HEAP_CUSTOM_END); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* For carveout, dma & custom heaps, we first let the heaps choose their ++ * own IDs. This allows the old behaviour of knowing the heap ids ++ * of these type of heaps in advance in user space. If a heap with ++ * that ID already exists, it is an error. ++ * ++ * If the heap hasn't picked an id by itself, then we assign it ++ * one. ++ */ ++ if (!id_bit) { ++ if (heap->id) { ++ id_bit = ffs(heap->id); ++ if (id_bit < start_bit || id_bit > end_bit) ++ return -EINVAL; ++ } else { ++ id_bit = find_next_zero_bit(dev->heap_ids, end_bit + 1, ++ start_bit); ++ if (id_bit > end_bit) ++ return -ENOSPC; ++ } ++ } ++ ++ if (test_and_set_bit(id_bit - 1, dev->heap_ids)) ++ return -EEXIST; ++ heap->id = id_bit; ++ dev->heap_cnt++; ++ ++ return 0; ++} ++ + int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) + { + struct ion_device *dev = internal_dev; +@@ -283,7 +346,14 @@ int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) + + heap->debugfs_dir = heap_root; + down_write(&dev->lock); +- heap->id = heap_id++; ++ ret = ion_assign_heap_id(heap, dev); ++ if (ret) { ++ pr_err("%s: Failed to assign heap id for heap type %x\n", ++ __func__, heap->type); ++ up_write(&dev->lock); ++ goto out_debugfs_cleanup; ++ } ++ + /* + * use negative heap->id to reverse the priority -- when traversing + * the list later attempt higher id numbers first +@@ -291,11 +361,12 @@ int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) + plist_node_init(&heap->node, -heap->id); + plist_add(&heap->node, &dev->heaps); + +- dev->heap_cnt++; + up_write(&dev->lock); + + return 0; + ++out_debugfs_cleanup: ++ debugfs_remove_recursive(heap->debugfs_dir); + out_heap_cleanup: + ion_heap_cleanup(heap); + out: +@@ -321,6 +392,8 @@ void ion_device_remove_heap(struct ion_heap *heap) + __func__, heap->name); + } + debugfs_remove_recursive(heap->debugfs_dir); ++ clear_bit(heap->id - 1, dev->heap_ids); ++ dev->heap_cnt--; + up_write(&dev->lock); + } + EXPORT_SYMBOL(ion_device_remove_heap); +diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h +index 5cc09fbfbefe2..2f5376e131c34 100644 +--- a/drivers/staging/android/ion/ion_private.h ++++ b/drivers/staging/android/ion/ion_private.h +@@ -23,13 +23,16 @@ + * @dev: the actual misc device + * @buffers: an rb tree of all the existing buffers + * @buffer_lock: lock protecting the tree of buffers +- * @lock: rwsem protecting the tree of heaps and clients ++ * @lock: rwsem protecting the tree of heaps, heap_bitmap and ++ * clients ++ * @heap_ids: bitmap of register heap ids + */ + struct ion_device { + struct miscdevice dev; + struct rb_root buffers; + struct mutex buffer_lock; + struct rw_semaphore lock; ++ DECLARE_BITMAP(heap_ids, ION_NUM_MAX_HEAPS); + struct plist_head heaps; + struct dentry *debug_root; + int heap_cnt; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch b/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch new file mode 100644 index 000000000000..dbd1f1c19ec6 --- /dev/null +++ b/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch @@ -0,0 +1,119 @@ +From a3d87671564a9cfc4dc3dc30036f50ea8541b109 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Fri, 13 Sep 2019 14:52:14 -0700 +Subject: ANDROID: staging: ion: make cma heap a module + +Add all cma areas that we can find as cma heaps. + +Bug: 133508579 +Test: build and insmod ion_cma_heap + +Change-Id: I3cf1884c8d8914ae31d55e2f2770104347844036 +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/heaps/Kconfig | 2 +- + .../staging/android/ion/heaps/ion_cma_heap.c | 56 ++++++++++++------- + 2 files changed, 36 insertions(+), 22 deletions(-) + +diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig +index af6fce69e61a..617d6e7ea583 100644 +--- a/drivers/staging/android/ion/heaps/Kconfig ++++ b/drivers/staging/android/ion/heaps/Kconfig +@@ -15,7 +15,7 @@ config ION_SYSTEM_CONTIG_HEAP + contiguous. If in doubt, say Y. + + config ION_CMA_HEAP +- bool "Ion CMA heap support" ++ tristate "Ion CMA heap support" + depends on ION && DMA_CMA + help + Choose this option to enable CMA heaps with Ion. This heap is backed +diff --git a/drivers/staging/android/ion/heaps/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c +index 236b6c576cdb..9584972b5005 100644 +--- a/drivers/staging/android/ion/heaps/ion_cma_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c +@@ -18,7 +18,7 @@ + struct ion_cma_heap { + struct ion_heap heap; + struct cma *cma; +-}; ++} cma_heaps[MAX_CMA_AREAS]; + + #define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap) + +@@ -97,38 +97,52 @@ static struct ion_heap_ops ion_cma_ops = { + .free = ion_cma_free, + }; + +-static struct ion_heap *__ion_cma_heap_create(struct cma *cma) ++static int __ion_add_cma_heap(struct cma *cma, void *data) + { ++ int *cma_nr = data; + struct ion_cma_heap *cma_heap; ++ int ret; + +- cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL); +- +- if (!cma_heap) +- return ERR_PTR(-ENOMEM); ++ if (*cma_nr >= MAX_CMA_AREAS) ++ return -EINVAL; + ++ cma_heap = &cma_heaps[*cma_nr]; + cma_heap->heap.ops = &ion_cma_ops; +- cma_heap->cma = cma; + cma_heap->heap.type = ION_HEAP_TYPE_DMA; +- return &cma_heap->heap; ++ cma_heap->heap.name = cma_get_name(cma); ++ ++ ret = ion_device_add_heap(&cma_heap->heap); ++ if (ret) ++ goto out; ++ ++ cma_heap->cma = cma; ++ *cma_nr += 1; ++out: ++ return 0; + } + +-static int __ion_add_cma_heaps(struct cma *cma, void *data) ++static int __init ion_cma_heap_init(void) + { +- struct ion_heap *heap; +- +- heap = __ion_cma_heap_create(cma); +- if (IS_ERR(heap)) +- return PTR_ERR(heap); ++ int ret; ++ int nr = 0; + +- heap->name = cma_get_name(cma); ++ ret = cma_for_each_area(__ion_add_cma_heap, &nr); ++ if (ret) { ++ for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) ++ ion_device_remove_heap(&cma_heaps[nr].heap); ++ } + +- ion_device_add_heap(heap); +- return 0; ++ return ret; + } + +-static int ion_add_cma_heaps(void) ++static void __exit ion_cma_heap_exit(void) + { +- cma_for_each_area(__ion_add_cma_heaps, NULL); +- return 0; ++ int nr; ++ ++ for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) ++ ion_device_remove_heap(&cma_heaps[nr].heap); + } +-device_initcall(ion_add_cma_heaps); ++ ++module_init(ion_cma_heap_init); ++module_exit(ion_cma_heap_exit); ++MODULE_LICENSE("GPL v2"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-io.patch b/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-io.patch new file mode 100644 index 000000000000..39cb171421d2 --- /dev/null +++ b/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-io.patch @@ -0,0 +1,37 @@ +From 8bee2c5265c0798f00a8fae3b873d3a62a8e4c66 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 26 Aug 2019 12:39:52 -0700 +Subject: ANDROID: staging: ion: move uapi/ion.h to + uapi/linux/ion.h + +Bug: 133508579 +Test: builds + +Change-Id: I599a78e1acd2eed909f40e5a5b6a62813610990c +Signed-off-by: Sandeep Patil +--- + include/linux/ion.h | 2 +- + include/uapi/{ => linux}/ion.h | 0 + 2 files changed, 1 insertion(+), 1 deletion(-) + rename include/uapi/{ => linux}/ion.h (100%) + +diff --git a/include/linux/ion.h b/include/linux/ion.h +index fe0d2cb1ef252..5d68674b015a9 100644 +--- a/include/linux/ion.h ++++ b/include/linux/ion.h +@@ -18,7 +18,7 @@ + #include + #include + #include +-#include ++#include + + /** + * struct ion_buffer - metadata for a particular buffer +diff --git a/include/uapi/ion.h b/include/uapi/linux/ion.h +similarity index 100% +rename from include/uapi/ion.h +rename to include/uapi/linux/ion.h +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-kn.patch b/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-kn.patch new file mode 100644 index 000000000000..8931cfb0c4dc --- /dev/null +++ b/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-kn.patch @@ -0,0 +1,132 @@ +From dc81f746efcc1360c896e24435e9a5d3f48d24e0 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 26 Aug 2019 13:14:43 -0700 +Subject: ANDROID: staging: ion: reserve specific heap ids for + known heap types. + +Since its inception, ion used heap types and heap ids interchangeably. +The 'heap type' is not part of the UAPI but 'heap ids' are. The sad part +is that heap ids are dynamically generated and heap types aren't. This +causes all sorts of problems trying to support following things + 1. No UAPI breakage for ION in GKI + 2. Support multiple CMA heaps (i.e. heap with same type but + different ids) + 3. Allow Android system code to reliably talk to any ION + driver using the standard / reserved heap types. etc. + 4. Allow someone to override standard heap implementation. + 5. Allow for new heap types to register to ion core. + +With this change, we start the process of reserving heap ids for +long known heap types like system, carveout etc. In order to not +break ABI and UAPI, we continue to use 32-bits with following caveats + + 1. BIT(0)-BIT(15) are reserved for standard / GKI heap ids + that Android platform can use from now on reliably. + 2. BIT(16)-BIT(31) are reserved for custom heap types that + only vendor specific processes can rely upon. + 3. BIT(3)-BIT(7) are reserved for CARVEOUT heaps. + 4. BIT(8)-BIT(15) are reserved for CMA / DMA heaps that manage + different CMA regions. The heap ids will be allocated in ascending + order and are first come first served. + +Bug: 133508579 +Test:ion-unit-tests + +Change-Id: I53af694113b62d29e0d2933fbcf7079d845099e9 +Signed-off-by: Sandeep Patil +--- + include/uapi/linux/ion.h | 74 +++++++++++++++++++++++++++++----------- + 1 file changed, 55 insertions(+), 19 deletions(-) + +diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h +index bfcbc0e70921b..09dbbfaf37185 100644 +--- a/include/uapi/linux/ion.h ++++ b/include/uapi/linux/ion.h +@@ -12,29 +12,65 @@ + #include + + /** +- * enum ion_heap_types - list of all possible types of heaps +- * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc +- * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc +- * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved +- * carveout heap, allocations are physically +- * contiguous +- * @ION_HEAP_TYPE_DMA: memory allocated via DMA API +- * @ION_HEAP_TYPE_MAX: helper for iterating over standard +- * (not device specific) heaps +- * @ION_NUM_HEAPS_IDS: helper for iterating over heaps, a bit mask +- * is used to identify the heaps, so only 32 +- * total heap types are supported ++ * ion_heap_types - list of all possible types of heaps that Android can use ++ * ++ * @ION_HEAP_TYPE_SYSTEM: Reserved heap id for ion heap that allocates ++ * memory using alloc_page(). Also, supports ++ * deferred free and allocation pools. ++ * @ION_HEAP_TYPE_SYSTEM_CONTIG: Reserved heap id for ion heap that is the same ++ * as SYSTEM_HEAP, except doesn't support ++ * allocation pools. ++ * @ION_HEAP_TYPE_CARVEOUT: Reserved heap id for ion heap that allocates ++ * memory from a pre-reserved memory region ++ * aka 'carveout'. ++ * @ION_HEAP_TYPE_DMA: Reserved heap id for ion heap that manages ++ * single CMA (contiguous memory allocator) ++ * region. Uses standard DMA APIs for ++ * managing memory within the CMA region. + */ + enum ion_heap_type { +- ION_HEAP_TYPE_SYSTEM = (1 << 0), +- ION_HEAP_TYPE_SYSTEM_CONTIG = (1 << 1), +- ION_HEAP_TYPE_CARVEOUT = (1 << 2), +- ION_HEAP_TYPE_CHUNK = (1 << 3), +- ION_HEAP_TYPE_DMA = (1 << 4), +- ION_HEAP_TYPE_MAX = (1 << 15), ++ ION_HEAP_TYPE_SYSTEM = 0, ++ ION_HEAP_TYPE_SYSTEM_CONTIG = 1, ++ ION_HEAP_TYPE_CHUNK = 2, ++ ION_HEAP_TYPE_CARVEOUT = 3, ++ ION_HEAP_TYPE_DMA = 4, ++ /* reserved range for future standard heap types */ ++ ION_HEAP_TYPE_CUSTOM = 16, ++ ION_HEAP_TYPE_MAX = 31, ++}; ++ ++/** ++ * ion_heap_id - list of standard heap ids that Android can use ++ * ++ * @ION_HEAP_SYSTEM Id for the ION_HEAP_TYPE_SYSTEM ++ * @ION_HEAP_SYSTEM_CONTIG Id for the ION_HEAP_TYPE_SYSTEM_CONTIG ++ * @ION_HEAP_CHUNK Id for the ION_HEAP_TYPE_CHUNK ++ * @ION_HEAP_CARVEOUT_START Start of reserved id range for heaps of type ++ * ION_HEAP_TYPE_CARVEOUT ++ * @ION_HEAP_CARVEOUT_END End of reserved id range for heaps of type ++ * ION_HEAP_TYPE_CARVEOUT ++ * @ION_HEAP_DMA_START Start of reserved id range for heaps of type ++ * ION_HEAP_TYPE_DMA ++ * @ION_HEAP_DMA_END End of reserved id range for heaps of type ++ * ION_HEAP_TYPE_DMA ++ * @ION_HEAP_CUSTOM_START Start of reserved id range for heaps of custom ++ * type ++ * @ION_HEAP_CUSTOM_END End of reserved id range for heaps of custom ++ * type ++ */ ++enum ion_heap_id { ++ ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM), ++ ION_HEAP_SYSTEM_CONTIG = (ION_HEAP_SYSTEM << 1), ++ ION_HEAP_CHUNK = (ION_HEAP_SYSTEM_CONTIG << 1), ++ ION_HEAP_CARVEOUT_START = (ION_HEAP_CHUNK << 1), ++ ION_HEAP_CARVEOUT_END = (ION_HEAP_CARVEOUT_START << 4), ++ ION_HEAP_DMA_START = (ION_HEAP_CARVEOUT_END << 1), ++ ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7), ++ ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1), ++ ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 15), + }; + +-#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) ++#define ION_NUM_MAX_HEAPS (32) + + /** + * allocation flags - the lower 16 bits are used by core ion, the upper 16 +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch b/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch new file mode 100644 index 000000000000..8e412dcc8040 --- /dev/null +++ b/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch @@ -0,0 +1,104 @@ +From c1642f5b434b35dbd0578a92f1900332a0d5f9f8 Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Mon, 20 May 2019 11:54:22 -0700 +Subject: ANDROID: sync defconfigs with savedefconfig + +Test: boot gki_defconfig and cuttlefish_defconfig on arm64 cuttlefish +Signed-off-by: Tri Vo +Change-Id: Ie0b518c0fd5100a39312069fe3b193684feb634d +--- + arch/arm64/configs/cuttlefish_defconfig | 7 ++----- + arch/arm64/configs/gki_defconfig | 5 +---- + 2 files changed, 3 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 5f7157425a316..41502bd397dd5 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -38,14 +38,14 @@ CONFIG_SCHED_MC=y + CONFIG_HZ_100=y + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y ++CONFIG_ARM64_SW_TTBR0_PAN=y ++CONFIG_COMPAT=y + CONFIG_ARMV8_DEPRECATED=y + CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y +-CONFIG_ARM64_SW_TTBR0_PAN=y + CONFIG_RANDOMIZE_BASE=y + # CONFIG_EFI is not set +-CONFIG_COMPAT=y + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +@@ -66,7 +66,6 @@ CONFIG_ARM_SCMI_PROTOCOL=y + CONFIG_ARM_SCPI_PROTOCOL=y + # CONFIG_ARM_SCPI_POWER_DOMAIN is not set + CONFIG_KPROBES=y +-CONFIG_JUMP_LABEL=y + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y +@@ -89,7 +88,6 @@ CONFIG_IP_MULTIPLE_TABLES=y + CONFIG_NET_IPGRE_DEMUX=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +-# CONFIG_INET_XFRM_MODE_BEET is not set + CONFIG_INET_UDP_DIAG=y + CONFIG_INET_DIAG_DESTROY=y + CONFIG_TCP_CONG_ADVANCED=y +@@ -193,7 +191,6 @@ CONFIG_MAC80211=y + CONFIG_RFKILL=y + CONFIG_PCI=y + CONFIG_PCI_HOST_GENERIC=y +-# CONFIG_UEVENT_HELPER is not set + CONFIG_DEVTMPFS=y + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 04f531ef25117..c9720858fd9a1 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -35,13 +35,13 @@ CONFIG_PROFILING=y + CONFIG_SCHED_MC=y + CONFIG_SECCOMP=y + CONFIG_PARAVIRT=y ++CONFIG_COMPAT=y + CONFIG_ARMV8_DEPRECATED=y + CONFIG_SWP_EMULATION=y + CONFIG_CP15_BARRIER_EMULATION=y + CONFIG_SETEND_EMULATION=y + CONFIG_RANDOMIZE_BASE=y + # CONFIG_EFI is not set +-CONFIG_COMPAT=y + CONFIG_PM_WAKELOCKS=y + CONFIG_PM_WAKELOCKS_LIMIT=0 + # CONFIG_PM_WAKELOCKS_GC is not set +@@ -81,7 +81,6 @@ CONFIG_IP_MULTIPLE_TABLES=y + CONFIG_NET_IPGRE_DEMUX=y + CONFIG_NET_IPVTI=y + CONFIG_INET_ESP=y +-# CONFIG_INET_XFRM_MODE_BEET is not set + CONFIG_INET_UDP_DIAG=y + CONFIG_INET_DIAG_DESTROY=y + CONFIG_IPV6_ROUTER_PREF=y +@@ -180,7 +179,6 @@ CONFIG_MAC80211=y + CONFIG_RFKILL=y + CONFIG_PCI=y + CONFIG_PCI_HOST_GENERIC=y +-# CONFIG_UEVENT_HELPER is not set + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y + CONFIG_ZRAM=y +@@ -282,7 +280,6 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=y +-CONFIG_BACKLIGHT_LCD_SUPPORT=y + # CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-taskstats-track-fsync-syscalls.patch b/patches/ANDROID-taskstats-track-fsync-syscalls.patch new file mode 100644 index 000000000000..86340ada57b3 --- /dev/null +++ b/patches/ANDROID-taskstats-track-fsync-syscalls.patch @@ -0,0 +1,138 @@ +From ef67599cfe471b7667faaa670a5e2f744e2f4087 Mon Sep 17 00:00:00 2001 +From: Jin Qian +Date: Thu, 2 Mar 2017 13:32:59 -0800 +Subject: ANDROID: taskstats: track fsync syscalls + +This adds a counter to the taskstats extended accounting fields, which +tracks the number of times fsync is called, and then plumbs it through +to the uid_sys_stats driver. + +Bug: 120442023 +Change-Id: I6c138de5b2332eea70f57e098134d1d141247b3f +Signed-off-by: Jin Qian +[AmitP: Refactored changes to align with changes from upstream commit + 9a07000400c8 ("sched/headers: Move CONFIG_TASK_XACCT bits from to ")] +Signed-off-by: Amit Pundir +[tkjos: Needed for storaged fsync accounting ("storaged --uid" and + "storaged --task").] +[astrachan: This is modifying a userspace interface and should probably + be reworked] +Signed-off-by: Alistair Strachan +--- + drivers/misc/Kconfig | 2 +- + drivers/misc/uid_sys_stats.c | 2 ++ + fs/sync.c | 3 ++- + include/linux/sched/xacct.h | 9 +++++++++ + include/linux/task_io_accounting.h | 2 ++ + include/linux/task_io_accounting_ops.h | 1 + + 6 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 304440a9db151..0523c740a4656 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -482,7 +482,7 @@ config MISC_RTSX + + config UID_SYS_STATS + bool "Per-UID statistics" +- depends on PROFILING && TASK_IO_ACCOUNTING ++ depends on PROFILING && TASK_XACCT && TASK_IO_ACCOUNTING + help + Per UID based cpu time statistics exported to /proc/uid_cputime + Per UID based io statistics exported to /proc/uid_io +diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c +index ea23f5d0af439..36b5f37fca2f8 100644 +--- a/drivers/misc/uid_sys_stats.c ++++ b/drivers/misc/uid_sys_stats.c +@@ -249,6 +249,7 @@ static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, + task_io_slot->write_bytes += compute_write_bytes(task); + task_io_slot->rchar += task->ioac.rchar; + task_io_slot->wchar += task->ioac.wchar; ++ task_io_slot->fsync += task->ioac.syscfs; + } + + static void compute_io_uid_tasks(struct uid_entry *uid_entry) +@@ -452,6 +453,7 @@ static void add_uid_io_stats(struct uid_entry *uid_entry, + io_slot->write_bytes += compute_write_bytes(task); + io_slot->rchar += task->ioac.rchar; + io_slot->wchar += task->ioac.wchar; ++ io_slot->fsync += task->ioac.syscfs; + + add_uid_tasks_io_stats(uid_entry, task, slot); + } +diff --git a/fs/sync.c b/fs/sync.c +index 4d1ff010bc5af..cc475d8be0c12 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -9,7 +9,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -220,6 +220,7 @@ static int do_fsync(unsigned int fd, int datasync) + if (f.file) { + ret = vfs_fsync(f.file, datasync); + fdput(f); ++ inc_syscfs(current); + } + return ret; + } +diff --git a/include/linux/sched/xacct.h b/include/linux/sched/xacct.h +index c078f0a94ceca..9544c9d9d5346 100644 +--- a/include/linux/sched/xacct.h ++++ b/include/linux/sched/xacct.h +@@ -28,6 +28,11 @@ static inline void inc_syscw(struct task_struct *tsk) + { + tsk->ioac.syscw++; + } ++ ++static inline void inc_syscfs(struct task_struct *tsk) ++{ ++ tsk->ioac.syscfs++; ++} + #else + static inline void add_rchar(struct task_struct *tsk, ssize_t amt) + { +@@ -44,6 +49,10 @@ static inline void inc_syscr(struct task_struct *tsk) + static inline void inc_syscw(struct task_struct *tsk) + { + } ++ ++static inline void inc_syscfs(struct task_struct *tsk) ++{ ++} + #endif + + #endif /* _LINUX_SCHED_XACCT_H */ +diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h +index 6f6acce064dea..bb26108ca23c0 100644 +--- a/include/linux/task_io_accounting.h ++++ b/include/linux/task_io_accounting.h +@@ -19,6 +19,8 @@ struct task_io_accounting { + u64 syscr; + /* # of write syscalls */ + u64 syscw; ++ /* # of fsync syscalls */ ++ u64 syscfs; + #endif /* CONFIG_TASK_XACCT */ + + #ifdef CONFIG_TASK_IO_ACCOUNTING +diff --git a/include/linux/task_io_accounting_ops.h b/include/linux/task_io_accounting_ops.h +index bb5498bcdd961..733ab62ae1413 100644 +--- a/include/linux/task_io_accounting_ops.h ++++ b/include/linux/task_io_accounting_ops.h +@@ -97,6 +97,7 @@ static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, + dst->wchar += src->wchar; + dst->syscr += src->syscr; + dst->syscw += src->syscw; ++ dst->syscfs += src->syscfs; + } + #else + static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes.patch b/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes.patch new file mode 100644 index 000000000000..e5ed8ab65257 --- /dev/null +++ b/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes.patch @@ -0,0 +1,318 @@ +From c0f85c2aef8823a02ea3cbe1ec1a837b1acc22f0 Mon Sep 17 00:00:00 2001 +From: Jin Qian +Date: Wed, 11 Mar 2015 10:44:50 -0700 +Subject: ANDROID: uid_cputime: Adds accounting for the + cputimes per uid. + +Adds proc files /proc/uid_cputime/show_uid_stat and +/proc/uid_cputime/remove_uid_range. + +show_uid_stat lists the total utime and stime for the active as well as +terminated processes for each of the uids. + +Writing a range of uids to remove_uid_range will delete the accounting +for all the uids within that range. + +Bug: 120442023 +Change-Id: I21d9210379da730b33ddc1a0ea663c8c9d2ac15b +Signed-off-by: Jin Qian +[AmitP: Refactored the original patch because upstream commit + 605dc2b31a2a ("tsacct: Convert obsolete cputime type to nsecs") + made cputime_t type obsolete, so use u64 nanoseconds directly instead. + Also folded following android-4.9 changes into this patch + 48a9906c0fd8 ("ANDROID: proc: uid_cputime: create uids from kuids") + 453ac31cab34 ("ANDROID: proc: uid_cputime: fix show_uid_stat permission")] +Signed-off-by: Amit Pundir +[connoro: Used by batterystats.] +[astrachan: Folded in the file/kconfig rename and the following changes: + da3687fbc393 ("ANDROID: uid_cputime: fix cputime overflow") + 71e3eb512d00 ("ANDROID: uid_cputime: Iterates over all the threads instead of processes.") + c65f0080c300 ("ANDROID: uid_cputime: Check for the range while removing range of UIDs.") + c8212458e3a5 ("ANDROID: uid_sys_stats: fix access of task_uid(task)") + bb5ee21cc4dd ("ANDROID: uid_sys_stats: change to use rt_mutex") + 6dc5d8173a8c ("ANDROID: uid_sys_stats: check previous uid_entry before call find_or_register_uid") + 82b9872b3894 ("ANDROID: uid_sys_stats: Replace tasklist lock with RCU in uid_cputime_show")] +Signed-off-by: Alistair Strachan +--- + drivers/misc/Kconfig | 6 + + drivers/misc/Makefile | 1 + + drivers/misc/uid_sys_stats.c | 241 +++++++++++++++++++++++++++++++++++ + 3 files changed, 248 insertions(+) + create mode 100644 drivers/misc/uid_sys_stats.c + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 16900357afc25..9e1b835d83c8e 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -480,6 +480,12 @@ config MISC_RTSX + tristate + default MISC_RTSX_PCI || MISC_RTSX_USB + ++config UID_SYS_STATS ++ bool "Per-UID statistics" ++ depends on PROFILING ++ help ++ Per UID based cpu time statistics exported to /proc/uid_cputime ++ + config PVPANIC + tristate "pvpanic device support" + depends on HAS_IOMEM && (ACPI || OF) +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index abd8ae2497461..2c250b1fe1d1e 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -59,3 +59,4 @@ obj-y += cardreader/ + obj-$(CONFIG_PVPANIC) += pvpanic.o + obj-$(CONFIG_HABANA_AI) += habanalabs/ + obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o ++obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o +diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c +new file mode 100644 +index 0000000000000..e1a9ef29468fb +--- /dev/null ++++ b/drivers/misc/uid_sys_stats.c +@@ -0,0 +1,241 @@ ++/* drivers/misc/uid_sys_stats.c ++ * ++ * Copyright (C) 2014 - 2015 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define UID_HASH_BITS 10 ++DECLARE_HASHTABLE(hash_table, UID_HASH_BITS); ++ ++static DEFINE_RT_MUTEX(uid_lock); ++static struct proc_dir_entry *parent; ++ ++struct uid_entry { ++ uid_t uid; ++ u64 utime; ++ u64 stime; ++ u64 active_utime; ++ u64 active_stime; ++ struct hlist_node hash; ++}; ++ ++static struct uid_entry *find_uid_entry(uid_t uid) ++{ ++ struct uid_entry *uid_entry; ++ hash_for_each_possible(hash_table, uid_entry, hash, uid) { ++ if (uid_entry->uid == uid) ++ return uid_entry; ++ } ++ return NULL; ++} ++ ++static struct uid_entry *find_or_register_uid(uid_t uid) ++{ ++ struct uid_entry *uid_entry; ++ ++ uid_entry = find_uid_entry(uid); ++ if (uid_entry) ++ return uid_entry; ++ ++ uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC); ++ if (!uid_entry) ++ return NULL; ++ ++ uid_entry->uid = uid; ++ ++ hash_add(hash_table, &uid_entry->hash, uid); ++ ++ return uid_entry; ++} ++ ++static int uid_stat_show(struct seq_file *m, void *v) ++{ ++ struct uid_entry *uid_entry = NULL; ++ struct task_struct *task, *temp; ++ struct user_namespace *user_ns = current_user_ns(); ++ u64 utime; ++ u64 stime; ++ unsigned long bkt; ++ uid_t uid; ++ ++ rt_mutex_lock(&uid_lock); ++ ++ hash_for_each(hash_table, bkt, uid_entry, hash) { ++ uid_entry->active_stime = 0; ++ uid_entry->active_utime = 0; ++ } ++ ++ rcu_read_lock(); ++ do_each_thread(temp, task) { ++ uid = from_kuid_munged(user_ns, task_uid(task)); ++ if (!uid_entry || uid_entry->uid != uid) ++ uid_entry = find_or_register_uid(uid); ++ if (!uid_entry) { ++ rcu_read_unlock(); ++ rt_mutex_unlock(&uid_lock); ++ pr_err("%s: failed to find the uid_entry for uid %d\n", ++ __func__, uid); ++ return -ENOMEM; ++ } ++ task_cputime_adjusted(task, &utime, &stime); ++ uid_entry->active_utime += utime; ++ uid_entry->active_stime += stime; ++ } while_each_thread(temp, task); ++ rcu_read_unlock(); ++ ++ hash_for_each(hash_table, bkt, uid_entry, hash) { ++ u64 total_utime = uid_entry->utime + ++ uid_entry->active_utime; ++ u64 total_stime = uid_entry->stime + ++ uid_entry->active_stime; ++ seq_printf(m, "%d: %llu %llu\n", uid_entry->uid, ++ ktime_to_ms(total_utime), ktime_to_ms(total_stime)); ++ } ++ ++ rt_mutex_unlock(&uid_lock); ++ return 0; ++} ++ ++static int uid_stat_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, uid_stat_show, PDE_DATA(inode)); ++} ++ ++static const struct file_operations uid_stat_fops = { ++ .open = uid_stat_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int uid_remove_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, NULL, NULL); ++} ++ ++static ssize_t uid_remove_write(struct file *file, ++ const char __user *buffer, size_t count, loff_t *ppos) ++{ ++ struct uid_entry *uid_entry; ++ struct hlist_node *tmp; ++ char uids[128]; ++ char *start_uid, *end_uid = NULL; ++ long int uid_start = 0, uid_end = 0; ++ ++ if (count >= sizeof(uids)) ++ count = sizeof(uids) - 1; ++ ++ if (copy_from_user(uids, buffer, count)) ++ return -EFAULT; ++ ++ uids[count] = '\0'; ++ end_uid = uids; ++ start_uid = strsep(&end_uid, "-"); ++ ++ if (!start_uid || !end_uid) ++ return -EINVAL; ++ ++ if (kstrtol(start_uid, 10, &uid_start) != 0 || ++ kstrtol(end_uid, 10, &uid_end) != 0) { ++ return -EINVAL; ++ } ++ rt_mutex_lock(&uid_lock); ++ ++ for (; uid_start <= uid_end; uid_start++) { ++ hash_for_each_possible_safe(hash_table, uid_entry, tmp, ++ hash, (uid_t)uid_start) { ++ if (uid_start == uid_entry->uid) { ++ hash_del(&uid_entry->hash); ++ kfree(uid_entry); ++ } ++ } ++ } ++ ++ rt_mutex_unlock(&uid_lock); ++ return count; ++} ++ ++static const struct file_operations uid_remove_fops = { ++ .open = uid_remove_open, ++ .release = single_release, ++ .write = uid_remove_write, ++}; ++ ++static int process_notifier(struct notifier_block *self, ++ unsigned long cmd, void *v) ++{ ++ struct task_struct *task = v; ++ struct uid_entry *uid_entry; ++ u64 utime, stime; ++ uid_t uid; ++ ++ if (!task) ++ return NOTIFY_OK; ++ ++ rt_mutex_lock(&uid_lock); ++ uid = from_kuid_munged(current_user_ns(), task_uid(task)); ++ uid_entry = find_or_register_uid(uid); ++ if (!uid_entry) { ++ pr_err("%s: failed to find uid %d\n", __func__, uid); ++ goto exit; ++ } ++ ++ task_cputime_adjusted(task, &utime, &stime); ++ uid_entry->utime += utime; ++ uid_entry->stime += stime; ++ ++exit: ++ rt_mutex_unlock(&uid_lock); ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block process_notifier_block = { ++ .notifier_call = process_notifier, ++}; ++ ++static int __init proc_uid_cputime_init(void) ++{ ++ hash_init(hash_table); ++ ++ parent = proc_mkdir("uid_cputime", NULL); ++ if (!parent) { ++ pr_err("%s: failed to create proc entry\n", __func__); ++ return -ENOMEM; ++ } ++ ++ proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops, ++ NULL); ++ ++ proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops, ++ NULL); ++ ++ profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block); ++ ++ return 0; ++} ++ ++early_initcall(proc_uid_cputime_init); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch b/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch new file mode 100644 index 000000000000..d65bc5e2cf38 --- /dev/null +++ b/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch @@ -0,0 +1,650 @@ +From d3b5be86eeb02a38f8bbcc3efb22e62e02d543fa Mon Sep 17 00:00:00 2001 +From: Jin Qian +Date: Tue, 10 Jan 2017 16:10:35 -0800 +Subject: ANDROID: uid_cputime: add per-uid IO usage accounting + +IO usages are accounted in foreground and background buckets. +For each uid, io usage is calculated in two steps. + +delta = current total of all uid tasks - previus total +current bucket += delta + +Bucket is determined by current uid stat. Userspace writes to +/proc/uid_procstat/set when uid stat is updated. + +/proc/uid_io/stats shows IO usage in this format. + + +Bug: 34198239 +Bug: 120442023 +Change-Id: Ib8bebda53e7a56f45ea3eb0ec9a3153d44188102 +Signed-off-by: Jin Qian +[connoro: Used by storaged.] +[astrachan: Note: this version does not track fsync syscalls; this is + implemented in a follow up due to the fact it depends on + modifications to the task_xacct feature.] +[astrachan: Folded in the following changes: + e003a91d8f42 ("ANDROID: uid_sys_stats: allow writing same state") + 89b984bf2efd ("ANDROID: uid_sys_stats: fix negative write bytes.") + bb5ee21cc4dd ("ANDROID: uid_sys_stats: change to use rt_mutex") + 9297d5a160c7 ("ANDROID: uid_sys_stats: reduce update_io_stats overhead") + 89402d07fe91 ("ANDROID: uid_sys_stats: defer io stats calulation for dead tasks") + 6dc5d8173a8c ("ANDROID: uid_sys_stats: check previous uid_entry before call find_or_register_uid") + 0ca2ece8f7ec ("ANDROID: uid_sys_stats: log task io with a debug flag") + c9c096ef0e67 ("ANDROID: uid_sys_stats: Copy task_struct comm field to bigger buffer")] +Signed-off-by: Alistair Strachan +--- + drivers/misc/Kconfig | 11 +- + drivers/misc/uid_sys_stats.c | 490 +++++++++++++++++++++++++++++++++-- + 2 files changed, 483 insertions(+), 18 deletions(-) + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 9e1b835d83c8e..304440a9db151 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -482,9 +482,18 @@ config MISC_RTSX + + config UID_SYS_STATS + bool "Per-UID statistics" +- depends on PROFILING ++ depends on PROFILING && TASK_IO_ACCOUNTING + help + Per UID based cpu time statistics exported to /proc/uid_cputime ++ Per UID based io statistics exported to /proc/uid_io ++ Per UID based procstat control in /proc/uid_procstat ++ ++config UID_SYS_STATS_DEBUG ++ bool "Per-TASK statistics" ++ depends on UID_SYS_STATS ++ default n ++ help ++ Per TASK based io statistics exported to /proc/uid_io + + config PVPANIC + tristate "pvpanic device support" +diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c +index e1a9ef29468fb..ea23f5d0af439 100644 +--- a/drivers/misc/uid_sys_stats.c ++++ b/drivers/misc/uid_sys_stats.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -32,7 +33,35 @@ + DECLARE_HASHTABLE(hash_table, UID_HASH_BITS); + + static DEFINE_RT_MUTEX(uid_lock); +-static struct proc_dir_entry *parent; ++static struct proc_dir_entry *cpu_parent; ++static struct proc_dir_entry *io_parent; ++static struct proc_dir_entry *proc_parent; ++ ++struct io_stats { ++ u64 read_bytes; ++ u64 write_bytes; ++ u64 rchar; ++ u64 wchar; ++ u64 fsync; ++}; ++ ++#define UID_STATE_FOREGROUND 0 ++#define UID_STATE_BACKGROUND 1 ++#define UID_STATE_BUCKET_SIZE 2 ++ ++#define UID_STATE_TOTAL_CURR 2 ++#define UID_STATE_TOTAL_LAST 3 ++#define UID_STATE_DEAD_TASKS 4 ++#define UID_STATE_SIZE 5 ++ ++#define MAX_TASK_COMM_LEN 256 ++ ++struct task_entry { ++ char comm[MAX_TASK_COMM_LEN]; ++ pid_t pid; ++ struct io_stats io[UID_STATE_SIZE]; ++ struct hlist_node hash; ++}; + + struct uid_entry { + uid_t uid; +@@ -40,9 +69,233 @@ struct uid_entry { + u64 stime; + u64 active_utime; + u64 active_stime; ++ int state; ++ struct io_stats io[UID_STATE_SIZE]; + struct hlist_node hash; ++#ifdef CONFIG_UID_SYS_STATS_DEBUG ++ DECLARE_HASHTABLE(task_entries, UID_HASH_BITS); ++#endif + }; + ++static u64 compute_write_bytes(struct task_struct *task) ++{ ++ if (task->ioac.write_bytes <= task->ioac.cancelled_write_bytes) ++ return 0; ++ ++ return task->ioac.write_bytes - task->ioac.cancelled_write_bytes; ++} ++ ++static void compute_io_bucket_stats(struct io_stats *io_bucket, ++ struct io_stats *io_curr, ++ struct io_stats *io_last, ++ struct io_stats *io_dead) ++{ ++ /* tasks could switch to another uid group, but its io_last in the ++ * previous uid group could still be positive. ++ * therefore before each update, do an overflow check first ++ */ ++ int64_t delta; ++ ++ delta = io_curr->read_bytes + io_dead->read_bytes - ++ io_last->read_bytes; ++ io_bucket->read_bytes += delta > 0 ? delta : 0; ++ delta = io_curr->write_bytes + io_dead->write_bytes - ++ io_last->write_bytes; ++ io_bucket->write_bytes += delta > 0 ? delta : 0; ++ delta = io_curr->rchar + io_dead->rchar - io_last->rchar; ++ io_bucket->rchar += delta > 0 ? delta : 0; ++ delta = io_curr->wchar + io_dead->wchar - io_last->wchar; ++ io_bucket->wchar += delta > 0 ? delta : 0; ++ delta = io_curr->fsync + io_dead->fsync - io_last->fsync; ++ io_bucket->fsync += delta > 0 ? delta : 0; ++ ++ io_last->read_bytes = io_curr->read_bytes; ++ io_last->write_bytes = io_curr->write_bytes; ++ io_last->rchar = io_curr->rchar; ++ io_last->wchar = io_curr->wchar; ++ io_last->fsync = io_curr->fsync; ++ ++ memset(io_dead, 0, sizeof(struct io_stats)); ++} ++ ++#ifdef CONFIG_UID_SYS_STATS_DEBUG ++static void get_full_task_comm(struct task_entry *task_entry, ++ struct task_struct *task) ++{ ++ int i = 0, offset = 0, len = 0; ++ /* save one byte for terminating null character */ ++ int unused_len = MAX_TASK_COMM_LEN - TASK_COMM_LEN - 1; ++ char buf[unused_len]; ++ struct mm_struct *mm = task->mm; ++ ++ /* fill the first TASK_COMM_LEN bytes with thread name */ ++ __get_task_comm(task_entry->comm, TASK_COMM_LEN, task); ++ i = strlen(task_entry->comm); ++ while (i < TASK_COMM_LEN) ++ task_entry->comm[i++] = ' '; ++ ++ /* next the executable file name */ ++ if (mm) { ++ down_read(&mm->mmap_sem); ++ if (mm->exe_file) { ++ char *pathname = d_path(&mm->exe_file->f_path, buf, ++ unused_len); ++ ++ if (!IS_ERR(pathname)) { ++ len = strlcpy(task_entry->comm + i, pathname, ++ unused_len); ++ i += len; ++ task_entry->comm[i++] = ' '; ++ unused_len--; ++ } ++ } ++ up_read(&mm->mmap_sem); ++ } ++ unused_len -= len; ++ ++ /* fill the rest with command line argument ++ * replace each null or new line character ++ * between args in argv with whitespace */ ++ len = get_cmdline(task, buf, unused_len); ++ while (offset < len) { ++ if (buf[offset] != '\0' && buf[offset] != '\n') ++ task_entry->comm[i++] = buf[offset]; ++ else ++ task_entry->comm[i++] = ' '; ++ offset++; ++ } ++ ++ /* get rid of trailing whitespaces in case when arg is memset to ++ * zero before being reset in userspace ++ */ ++ while (task_entry->comm[i-1] == ' ') ++ i--; ++ task_entry->comm[i] = '\0'; ++} ++ ++static struct task_entry *find_task_entry(struct uid_entry *uid_entry, ++ struct task_struct *task) ++{ ++ struct task_entry *task_entry; ++ ++ hash_for_each_possible(uid_entry->task_entries, task_entry, hash, ++ task->pid) { ++ if (task->pid == task_entry->pid) { ++ /* if thread name changed, update the entire command */ ++ int len = strnchr(task_entry->comm, ' ', TASK_COMM_LEN) ++ - task_entry->comm; ++ ++ if (strncmp(task_entry->comm, task->comm, len)) ++ get_full_task_comm(task_entry, task); ++ return task_entry; ++ } ++ } ++ return NULL; ++} ++ ++static struct task_entry *find_or_register_task(struct uid_entry *uid_entry, ++ struct task_struct *task) ++{ ++ struct task_entry *task_entry; ++ pid_t pid = task->pid; ++ ++ task_entry = find_task_entry(uid_entry, task); ++ if (task_entry) ++ return task_entry; ++ ++ task_entry = kzalloc(sizeof(struct task_entry), GFP_ATOMIC); ++ if (!task_entry) ++ return NULL; ++ ++ get_full_task_comm(task_entry, task); ++ ++ task_entry->pid = pid; ++ hash_add(uid_entry->task_entries, &task_entry->hash, (unsigned int)pid); ++ ++ return task_entry; ++} ++ ++static void remove_uid_tasks(struct uid_entry *uid_entry) ++{ ++ struct task_entry *task_entry; ++ unsigned long bkt_task; ++ struct hlist_node *tmp_task; ++ ++ hash_for_each_safe(uid_entry->task_entries, bkt_task, ++ tmp_task, task_entry, hash) { ++ hash_del(&task_entry->hash); ++ kfree(task_entry); ++ } ++} ++ ++static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) ++{ ++ struct task_entry *task_entry; ++ unsigned long bkt_task; ++ ++ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { ++ memset(&task_entry->io[UID_STATE_TOTAL_CURR], 0, ++ sizeof(struct io_stats)); ++ } ++} ++ ++static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, ++ struct task_struct *task, int slot) ++{ ++ struct task_entry *task_entry = find_or_register_task(uid_entry, task); ++ struct io_stats *task_io_slot = &task_entry->io[slot]; ++ ++ task_io_slot->read_bytes += task->ioac.read_bytes; ++ task_io_slot->write_bytes += compute_write_bytes(task); ++ task_io_slot->rchar += task->ioac.rchar; ++ task_io_slot->wchar += task->ioac.wchar; ++} ++ ++static void compute_io_uid_tasks(struct uid_entry *uid_entry) ++{ ++ struct task_entry *task_entry; ++ unsigned long bkt_task; ++ ++ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { ++ compute_io_bucket_stats(&task_entry->io[uid_entry->state], ++ &task_entry->io[UID_STATE_TOTAL_CURR], ++ &task_entry->io[UID_STATE_TOTAL_LAST], ++ &task_entry->io[UID_STATE_DEAD_TASKS]); ++ } ++} ++ ++static void show_io_uid_tasks(struct seq_file *m, struct uid_entry *uid_entry) ++{ ++ struct task_entry *task_entry; ++ unsigned long bkt_task; ++ ++ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { ++ /* Separated by comma because space exists in task comm */ ++ seq_printf(m, "task,%s,%lu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n", ++ task_entry->comm, ++ (unsigned long)task_entry->pid, ++ task_entry->io[UID_STATE_FOREGROUND].rchar, ++ task_entry->io[UID_STATE_FOREGROUND].wchar, ++ task_entry->io[UID_STATE_FOREGROUND].read_bytes, ++ task_entry->io[UID_STATE_FOREGROUND].write_bytes, ++ task_entry->io[UID_STATE_BACKGROUND].rchar, ++ task_entry->io[UID_STATE_BACKGROUND].wchar, ++ task_entry->io[UID_STATE_BACKGROUND].read_bytes, ++ task_entry->io[UID_STATE_BACKGROUND].write_bytes, ++ task_entry->io[UID_STATE_FOREGROUND].fsync, ++ task_entry->io[UID_STATE_BACKGROUND].fsync); ++ } ++} ++#else ++static void remove_uid_tasks(struct uid_entry *uid_entry) {}; ++static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) {}; ++static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, ++ struct task_struct *task, int slot) {}; ++static void compute_io_uid_tasks(struct uid_entry *uid_entry) {}; ++static void show_io_uid_tasks(struct seq_file *m, ++ struct uid_entry *uid_entry) {} ++#endif ++ + static struct uid_entry *find_uid_entry(uid_t uid) + { + struct uid_entry *uid_entry; +@@ -66,13 +319,15 @@ static struct uid_entry *find_or_register_uid(uid_t uid) + return NULL; + + uid_entry->uid = uid; +- ++#ifdef CONFIG_UID_SYS_STATS_DEBUG ++ hash_init(uid_entry->task_entries); ++#endif + hash_add(hash_table, &uid_entry->hash, uid); + + return uid_entry; + } + +-static int uid_stat_show(struct seq_file *m, void *v) ++static int uid_cputime_show(struct seq_file *m, void *v) + { + struct uid_entry *uid_entry = NULL; + struct task_struct *task, *temp; +@@ -120,13 +375,13 @@ static int uid_stat_show(struct seq_file *m, void *v) + return 0; + } + +-static int uid_stat_open(struct inode *inode, struct file *file) ++static int uid_cputime_open(struct inode *inode, struct file *file) + { +- return single_open(file, uid_stat_show, PDE_DATA(inode)); ++ return single_open(file, uid_cputime_show, PDE_DATA(inode)); + } + +-static const struct file_operations uid_stat_fops = { +- .open = uid_stat_open, ++static const struct file_operations uid_cputime_fops = { ++ .open = uid_cputime_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +@@ -163,12 +418,14 @@ static ssize_t uid_remove_write(struct file *file, + kstrtol(end_uid, 10, &uid_end) != 0) { + return -EINVAL; + } ++ + rt_mutex_lock(&uid_lock); + + for (; uid_start <= uid_end; uid_start++) { + hash_for_each_possible_safe(hash_table, uid_entry, tmp, + hash, (uid_t)uid_start) { + if (uid_start == uid_entry->uid) { ++ remove_uid_tasks(uid_entry); + hash_del(&uid_entry->hash); + kfree(uid_entry); + } +@@ -185,6 +442,177 @@ static const struct file_operations uid_remove_fops = { + .write = uid_remove_write, + }; + ++ ++static void add_uid_io_stats(struct uid_entry *uid_entry, ++ struct task_struct *task, int slot) ++{ ++ struct io_stats *io_slot = &uid_entry->io[slot]; ++ ++ io_slot->read_bytes += task->ioac.read_bytes; ++ io_slot->write_bytes += compute_write_bytes(task); ++ io_slot->rchar += task->ioac.rchar; ++ io_slot->wchar += task->ioac.wchar; ++ ++ add_uid_tasks_io_stats(uid_entry, task, slot); ++} ++ ++static void update_io_stats_all_locked(void) ++{ ++ struct uid_entry *uid_entry = NULL; ++ struct task_struct *task, *temp; ++ struct user_namespace *user_ns = current_user_ns(); ++ unsigned long bkt; ++ uid_t uid; ++ ++ hash_for_each(hash_table, bkt, uid_entry, hash) { ++ memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, ++ sizeof(struct io_stats)); ++ set_io_uid_tasks_zero(uid_entry); ++ } ++ ++ rcu_read_lock(); ++ do_each_thread(temp, task) { ++ uid = from_kuid_munged(user_ns, task_uid(task)); ++ if (!uid_entry || uid_entry->uid != uid) ++ uid_entry = find_or_register_uid(uid); ++ if (!uid_entry) ++ continue; ++ add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); ++ } while_each_thread(temp, task); ++ rcu_read_unlock(); ++ ++ hash_for_each(hash_table, bkt, uid_entry, hash) { ++ compute_io_bucket_stats(&uid_entry->io[uid_entry->state], ++ &uid_entry->io[UID_STATE_TOTAL_CURR], ++ &uid_entry->io[UID_STATE_TOTAL_LAST], ++ &uid_entry->io[UID_STATE_DEAD_TASKS]); ++ compute_io_uid_tasks(uid_entry); ++ } ++} ++ ++static void update_io_stats_uid_locked(struct uid_entry *uid_entry) ++{ ++ struct task_struct *task, *temp; ++ struct user_namespace *user_ns = current_user_ns(); ++ ++ memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, ++ sizeof(struct io_stats)); ++ set_io_uid_tasks_zero(uid_entry); ++ ++ rcu_read_lock(); ++ do_each_thread(temp, task) { ++ if (from_kuid_munged(user_ns, task_uid(task)) != uid_entry->uid) ++ continue; ++ add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); ++ } while_each_thread(temp, task); ++ rcu_read_unlock(); ++ ++ compute_io_bucket_stats(&uid_entry->io[uid_entry->state], ++ &uid_entry->io[UID_STATE_TOTAL_CURR], ++ &uid_entry->io[UID_STATE_TOTAL_LAST], ++ &uid_entry->io[UID_STATE_DEAD_TASKS]); ++ compute_io_uid_tasks(uid_entry); ++} ++ ++ ++static int uid_io_show(struct seq_file *m, void *v) ++{ ++ struct uid_entry *uid_entry; ++ unsigned long bkt; ++ ++ rt_mutex_lock(&uid_lock); ++ ++ update_io_stats_all_locked(); ++ ++ hash_for_each(hash_table, bkt, uid_entry, hash) { ++ seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", ++ uid_entry->uid, ++ uid_entry->io[UID_STATE_FOREGROUND].rchar, ++ uid_entry->io[UID_STATE_FOREGROUND].wchar, ++ uid_entry->io[UID_STATE_FOREGROUND].read_bytes, ++ uid_entry->io[UID_STATE_FOREGROUND].write_bytes, ++ uid_entry->io[UID_STATE_BACKGROUND].rchar, ++ uid_entry->io[UID_STATE_BACKGROUND].wchar, ++ uid_entry->io[UID_STATE_BACKGROUND].read_bytes, ++ uid_entry->io[UID_STATE_BACKGROUND].write_bytes, ++ uid_entry->io[UID_STATE_FOREGROUND].fsync, ++ uid_entry->io[UID_STATE_BACKGROUND].fsync); ++ ++ show_io_uid_tasks(m, uid_entry); ++ } ++ ++ rt_mutex_unlock(&uid_lock); ++ return 0; ++} ++ ++static int uid_io_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, uid_io_show, PDE_DATA(inode)); ++} ++ ++static const struct file_operations uid_io_fops = { ++ .open = uid_io_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int uid_procstat_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, NULL, NULL); ++} ++ ++static ssize_t uid_procstat_write(struct file *file, ++ const char __user *buffer, size_t count, loff_t *ppos) ++{ ++ struct uid_entry *uid_entry; ++ uid_t uid; ++ int argc, state; ++ char input[128]; ++ ++ if (count >= sizeof(input)) ++ return -EINVAL; ++ ++ if (copy_from_user(input, buffer, count)) ++ return -EFAULT; ++ ++ input[count] = '\0'; ++ ++ argc = sscanf(input, "%u %d", &uid, &state); ++ if (argc != 2) ++ return -EINVAL; ++ ++ if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND) ++ return -EINVAL; ++ ++ rt_mutex_lock(&uid_lock); ++ ++ uid_entry = find_or_register_uid(uid); ++ if (!uid_entry) { ++ rt_mutex_unlock(&uid_lock); ++ return -EINVAL; ++ } ++ ++ if (uid_entry->state == state) { ++ rt_mutex_unlock(&uid_lock); ++ return count; ++ } ++ ++ update_io_stats_uid_locked(uid_entry); ++ ++ uid_entry->state = state; ++ ++ rt_mutex_unlock(&uid_lock); ++ ++ return count; ++} ++ ++static const struct file_operations uid_procstat_fops = { ++ .open = uid_procstat_open, ++ .release = single_release, ++ .write = uid_procstat_write, ++}; ++ + static int process_notifier(struct notifier_block *self, + unsigned long cmd, void *v) + { +@@ -208,6 +636,8 @@ static int process_notifier(struct notifier_block *self, + uid_entry->utime += utime; + uid_entry->stime += stime; + ++ add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS); ++ + exit: + rt_mutex_unlock(&uid_lock); + return NOTIFY_OK; +@@ -217,25 +647,51 @@ static struct notifier_block process_notifier_block = { + .notifier_call = process_notifier, + }; + +-static int __init proc_uid_cputime_init(void) ++static int __init proc_uid_sys_stats_init(void) + { + hash_init(hash_table); + +- parent = proc_mkdir("uid_cputime", NULL); +- if (!parent) { +- pr_err("%s: failed to create proc entry\n", __func__); +- return -ENOMEM; ++ cpu_parent = proc_mkdir("uid_cputime", NULL); ++ if (!cpu_parent) { ++ pr_err("%s: failed to create uid_cputime proc entry\n", ++ __func__); ++ goto err; ++ } ++ ++ proc_create_data("remove_uid_range", 0222, cpu_parent, ++ &uid_remove_fops, NULL); ++ proc_create_data("show_uid_stat", 0444, cpu_parent, ++ &uid_cputime_fops, NULL); ++ ++ io_parent = proc_mkdir("uid_io", NULL); ++ if (!io_parent) { ++ pr_err("%s: failed to create uid_io proc entry\n", ++ __func__); ++ goto err; + } + +- proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops, +- NULL); ++ proc_create_data("stats", 0444, io_parent, ++ &uid_io_fops, NULL); + +- proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops, +- NULL); ++ proc_parent = proc_mkdir("uid_procstat", NULL); ++ if (!proc_parent) { ++ pr_err("%s: failed to create uid_procstat proc entry\n", ++ __func__); ++ goto err; ++ } ++ ++ proc_create_data("set", 0222, proc_parent, ++ &uid_procstat_fops, NULL); + + profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block); + + return 0; ++ ++err: ++ remove_proc_subtree("uid_cputime", NULL); ++ remove_proc_subtree("uid_io", NULL); ++ remove_proc_subtree("uid_procstat", NULL); ++ return -ENOMEM; + } + +-early_initcall(proc_uid_cputime_init); ++early_initcall(proc_uid_sys_stats_init); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-update-arm64-gki_defconfig.patch b/patches/ANDROID-update-arm64-gki_defconfig.patch new file mode 100644 index 000000000000..8334650703b5 --- /dev/null +++ b/patches/ANDROID-update-arm64-gki_defconfig.patch @@ -0,0 +1,29 @@ +From f1aa35a164021c6213541492f420e926b2a01c73 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 23 Sep 2019 14:43:39 +0200 +Subject: ANDROID: update arm64 gki_defconfig + +Update the arm64 gki_defconfig for changes made during the merge of +upstream + +Signed-off-by: Greg Kroah-Hartman +Change-Id: I50d96aa097866a43f305c59954f1242e02d0dac6 +--- + arch/arm64/configs/gki_defconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index ab1dd6d01ec8..01be7843c646 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -384,7 +384,6 @@ CONFIG_FUSE_FS=y + CONFIG_OVERLAY_FS=y + CONFIG_MSDOS_FS=y + CONFIG_VFAT_FS=y +-CONFIG_TMPFS_POSIX_ACL=y + # CONFIG_EFIVAR_FS is not set + CONFIG_SDCARD_FS=y + CONFIG_PSTORE=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-update-gki_defconfig-1.patch b/patches/ANDROID-update-gki_defconfig-1.patch new file mode 100644 index 000000000000..1c654d08a2c6 --- /dev/null +++ b/patches/ANDROID-update-gki_defconfig-1.patch @@ -0,0 +1,42 @@ +From 0cd627b5a33ec3bdbcd427db70d142e49fde2a81 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 19 Sep 2019 23:21:24 +0200 +Subject: ANDROID: update gki_defconfig + +The 5.4-rc1-prerelease merge changed a few config options, so update +gki_defconfig so that the build will run properly. + +Signed-off-by: Greg Kroah-Hartman +Change-Id: I8feb0a501d60005a7973b1fa2f9d34bb87b64259 +--- + arch/arm64/configs/gki_defconfig | 1 - + arch/x86/configs/gki_defconfig | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index f964b81a1e4b..ab1dd6d01ec8 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -397,7 +397,6 @@ CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y + CONFIG_CRYPTO_ADIANTUM=y + CONFIG_CRYPTO_MD4=y +-CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_ANSI_CPRNG=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 642729662b04..73d513715ce7 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -328,7 +328,6 @@ CONFIG_SECURITY_NETWORK=y + CONFIG_HARDENED_USERCOPY=y + CONFIG_SECURITY_SELINUX=y + CONFIG_CRYPTO_ADIANTUM=y +-CONFIG_CRYPTO_SHA512=y + CONFIG_CRYPTO_LZ4=y + CONFIG_CRYPTO_ZSTD=y + CONFIG_CRYPTO_ANSI_CPRNG=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-update-gki_defconfig-2.patch b/patches/ANDROID-update-gki_defconfig-2.patch new file mode 100644 index 000000000000..cea2c07ac7e7 --- /dev/null +++ b/patches/ANDROID-update-gki_defconfig-2.patch @@ -0,0 +1,42 @@ +From 00620c7e94daca29a99d1be644017e85e0bbb3e2 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 30 Sep 2019 13:31:19 +0200 +Subject: ANDROID: update gki_defconfig + +Update the default gki_defconfig now that there were some config changes +in mainline. + +Signed-off-by: Greg Kroah-Hartman +Change-Id: Iafb8e2fa2d8027b2848e93d2d39b0ea42028289b +--- + arch/arm64/configs/gki_defconfig | 1 - + arch/x86/configs/gki_defconfig | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 01be7843c646..97e0e47767e2 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -298,7 +298,6 @@ CONFIG_MEDIA_CONTROLLER=y + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=y +-# CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y + CONFIG_SND=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 73d513715ce7..7890c249bca9 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -255,7 +255,6 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_DRM=y + # CONFIG_DRM_FBDEV_EMULATION is not set + CONFIG_DRM_VIRTIO_GPU=m +-# CONFIG_LCD_CLASS_DEVICE is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y + CONFIG_SOUND=y + CONFIG_SND=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch b/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch new file mode 100644 index 000000000000..ac93768b4ab0 --- /dev/null +++ b/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch @@ -0,0 +1,52 @@ +From f4f6f40ebc621bc31bee7e5160abda908b798f23 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Mon, 30 Sep 2019 15:27:24 +0100 +Subject: ANDROID: usb: gadget: Fix dependency for + f_accessory + +The Android Accessory USB gadget functions use core HID functions. As +such, compiling with CONFIG_HID=m and CONFIG_USB_GADGET=y fails to link: + + drivers/usb/gadget/function/f_accessory.o: In function `acc_complete_send_hid_event': + f_accessory.c:(.text+0xd54): undefined reference to `hid_report_raw_event' + drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_work': + f_accessory.c:(.text+0x2a98): undefined reference to `hid_destroy_device' + f_accessory.c:(.text+0x2ad4): undefined reference to `hid_allocate_device' + f_accessory.c:(.text+0x2b64): undefined reference to `hid_add_device' + f_accessory.c:(.text+0x2d04): undefined reference to `hid_destroy_device' + drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_parse': + f_accessory.c:(.text+0x2e24): undefined reference to `hid_parse_report' + drivers/usb/gadget/function/f_accessory.o: In function `acc_function_bind_configfs': + f_accessory.c:(.text+0x2f8c): undefined reference to `__hid_register_driver' + drivers/usb/gadget/function/f_accessory.o: In function `acc_function_unbind': + f_accessory.c:(.text+0x3bc8): undefined reference to `hid_unregister_driver' + drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_probe': + f_accessory.c:(.text+0x3ef4): undefined reference to `hid_open_report' + f_accessory.c:(.text+0x3f18): undefined reference to `hid_hw_start' + +Fix this by making the dependency on HID explicit. + +Bug: 140224784 +Fixes: 483cb5629ea7 ("ANDROID: usb: gadget: f_accessory: Add Android +Accessory function") +Signed-off-by: Quentin Perret +Change-Id: Ibd8640d7766cc7802d8275bfe3adfa007f3318fe +--- + drivers/usb/gadget/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 920ff2d2c557..bcd7f83c9ba0 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -386,6 +386,7 @@ config USB_CONFIGFS_F_FS + config USB_CONFIGFS_F_ACC + bool "Accessory gadget" + depends on USB_CONFIGFS ++ depends on HID=y + select USB_F_ACC + help + USB gadget Accessory support +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-use.patch b/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-use.patch new file mode 100644 index 000000000000..5e7168bddaf6 --- /dev/null +++ b/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-use.patch @@ -0,0 +1,279 @@ +From 9c9771efc4e69331cd11c6debffd57f8fc9e9684 Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Mon, 15 Dec 2014 10:44:47 -0800 +Subject: ANDROID: usb: gadget: configfs: Add Uevent to notify + userspace + +Android userspace UsbDeviceManager relies on the +uevents generated by the composition driver to +generate user notifications. This CL adds uevents +to be generated whenever USB changes its state +i.e. connected, disconnected, configured. + +This CL also intercepts the setup requests from +the usb_core anb routes it to the specific +usb function if required. + +Bug: 68755607 +Bug: 120441124 +Change-Id: Ib3d3a78255a532f7449dac286f776c2966caf8c1 +[badhri: Migrate to using udc uevents from upstream sysfs.] +Signed-off-by: Badhri Jagan Sridharan +[AmitP: Folded following android-4.9 commit changes into this patch + 9214c899f730 ("ANDROID: usb: gadget: configfs: handle gadget reset request for android")] +Signed-off-by: Amit Pundir +[astrachan: Folded change 5c899c9fd75d ("ANDROID: usb: gadget: configfs: + fix null ptr in android_disconnect") into this patch] +Signed-off-by: Alistair Strachan +--- + drivers/usb/gadget/Kconfig | 8 ++ + drivers/usb/gadget/configfs.c | 166 +++++++++++++++++++++++++++++++++- + 2 files changed, 171 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 02ff850278b17..f5e82dcac5835 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -230,6 +230,14 @@ config USB_CONFIGFS + appropriate symbolic links. + For more information see Documentation/usb/gadget_configfs.rst. + ++config USB_CONFIGFS_UEVENT ++ bool "Uevent notification of Gadget state" ++ depends on USB_CONFIGFS ++ help ++ Enable uevent notifications to userspace when the gadget ++ state changes. The gadget can be in any of the following ++ three states: "CONNECTED/DISCONNECTED/CONFIGURED" ++ + config USB_CONFIGFS_SERIAL + bool "Generic serial bulk in/out" + depends on USB_CONFIGFS +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 0251299428946..bbc166f998930 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -10,6 +10,19 @@ + #include "u_f.h" + #include "u_os_desc.h" + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++#include ++#include ++#include ++ ++#ifdef CONFIG_USB_CONFIGFS_F_ACC ++extern int acc_ctrlrequest(struct usb_composite_dev *cdev, ++ const struct usb_ctrlrequest *ctrl); ++void acc_disconnect(void); ++#endif ++static struct class *android_class; ++#endif ++ + int check_user_usb_string(const char *name, + struct usb_gadget_strings *stringtab_dev) + { +@@ -61,6 +74,12 @@ struct gadget_info { + bool use_os_desc; + char b_vendor_code; + char qw_sign[OS_STRING_QW_SIGN_LEN]; ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ bool connected; ++ bool sw_connected; ++ struct work_struct work; ++ struct device *dev; ++#endif + }; + + static inline struct gadget_info *to_gadget_info(struct config_item *item) +@@ -266,7 +285,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, + + mutex_lock(&gi->lock); + +- if (!strlen(name)) { ++ if (!strlen(name) || strcmp(name, "none") == 0) { + ret = unregister_gadget(gi); + if (ret) + goto err; +@@ -1372,6 +1391,57 @@ static int configfs_composite_bind(struct usb_gadget *gadget, + return ret; + } + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++static void android_work(struct work_struct *data) ++{ ++ struct gadget_info *gi = container_of(data, struct gadget_info, work); ++ struct usb_composite_dev *cdev = &gi->cdev; ++ char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; ++ char *connected[2] = { "USB_STATE=CONNECTED", NULL }; ++ char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; ++ /* 0-connected 1-configured 2-disconnected*/ ++ bool status[3] = { false, false, false }; ++ unsigned long flags; ++ bool uevent_sent = false; ++ ++ spin_lock_irqsave(&cdev->lock, flags); ++ if (cdev->config) ++ status[1] = true; ++ ++ if (gi->connected != gi->sw_connected) { ++ if (gi->connected) ++ status[0] = true; ++ else ++ status[2] = true; ++ gi->sw_connected = gi->connected; ++ } ++ spin_unlock_irqrestore(&cdev->lock, flags); ++ ++ if (status[0]) { ++ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); ++ pr_info("%s: sent uevent %s\n", __func__, connected[0]); ++ uevent_sent = true; ++ } ++ ++ if (status[1]) { ++ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); ++ pr_info("%s: sent uevent %s\n", __func__, configured[0]); ++ uevent_sent = true; ++ } ++ ++ if (status[2]) { ++ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); ++ pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); ++ uevent_sent = true; ++ } ++ ++ if (!uevent_sent) { ++ pr_info("%s: did not send uevent (%d %d %p)\n", __func__, ++ gi->connected, gi->sw_connected, cdev->config); ++ } ++} ++#endif ++ + static void configfs_composite_unbind(struct usb_gadget *gadget) + { + struct usb_composite_dev *cdev; +@@ -1391,14 +1461,91 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) + set_gadget_data(gadget, NULL); + } + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++static int android_setup(struct usb_gadget *gadget, ++ const struct usb_ctrlrequest *c) ++{ ++ struct usb_composite_dev *cdev = get_gadget_data(gadget); ++ unsigned long flags; ++ struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); ++ int value = -EOPNOTSUPP; ++ struct usb_function_instance *fi; ++ ++ spin_lock_irqsave(&cdev->lock, flags); ++ if (!gi->connected) { ++ gi->connected = 1; ++ schedule_work(&gi->work); ++ } ++ spin_unlock_irqrestore(&cdev->lock, flags); ++ list_for_each_entry(fi, &gi->available_func, cfs_list) { ++ if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) { ++ value = fi->f->setup(fi->f, c); ++ if (value >= 0) ++ break; ++ } ++ } ++ ++#ifdef CONFIG_USB_CONFIGFS_F_ACC ++ if (value < 0) ++ value = acc_ctrlrequest(cdev, c); ++#endif ++ ++ if (value < 0) ++ value = composite_setup(gadget, c); ++ ++ spin_lock_irqsave(&cdev->lock, flags); ++ if (c->bRequest == USB_REQ_SET_CONFIGURATION && ++ cdev->config) { ++ schedule_work(&gi->work); ++ } ++ spin_unlock_irqrestore(&cdev->lock, flags); ++ ++ return value; ++} ++ ++static void android_disconnect(struct usb_gadget *gadget) ++{ ++ struct usb_composite_dev *cdev = get_gadget_data(gadget); ++ struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); ++ ++ /* FIXME: There's a race between usb_gadget_udc_stop() which is likely ++ * to set the gadget driver to NULL in the udc driver and this drivers ++ * gadget disconnect fn which likely checks for the gadget driver to ++ * be a null ptr. It happens that unbind (doing set_gadget_data(NULL)) ++ * is called before the gadget driver is set to NULL and the udc driver ++ * calls disconnect fn which results in cdev being a null ptr. ++ */ ++ if (cdev == NULL) { ++ WARN(1, "%s: gadget driver already disconnected\n", __func__); ++ return; ++ } ++ ++ /* accessory HID support can be active while the ++ accessory function is not actually enabled, ++ so we need to inform it when we are disconnected. ++ */ ++ ++#ifdef CONFIG_USB_CONFIGFS_F_ACC ++ acc_disconnect(); ++#endif ++ gi->connected = 0; ++ schedule_work(&gi->work); ++ composite_disconnect(gadget); ++} ++#endif ++ + static const struct usb_gadget_driver configfs_driver_template = { + .bind = configfs_composite_bind, + .unbind = configfs_composite_unbind, +- ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ .setup = android_setup, ++ .reset = android_disconnect, ++ .disconnect = android_disconnect, ++#else + .setup = composite_setup, + .reset = composite_disconnect, + .disconnect = composite_disconnect, +- ++#endif + .suspend = composite_suspend, + .resume = composite_resume, + +@@ -1458,6 +1605,12 @@ static struct config_group *gadgets_make( + gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); + gi->composite.name = gi->composite.gadget_driver.function; + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ INIT_WORK(&gi->work, android_work); ++ gi->dev = device_create(android_class, NULL, ++ MKDEV(0, 0), NULL, "android0"); ++#endif ++ + if (!gi->composite.gadget_driver.function) + goto err; + +@@ -1509,6 +1662,13 @@ static int __init gadget_cfs_init(void) + config_group_init(&gadget_subsys.su_group); + + ret = configfs_register_subsystem(&gadget_subsys); ++ ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ android_class = class_create(THIS_MODULE, "android_usb"); ++ if (IS_ERR(android_class)) ++ return PTR_ERR(android_class); ++#endif ++ + return ret; + } + module_init(gadget_cfs_init); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-.patch b/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-.patch new file mode 100644 index 000000000000..ccb0f29c61c4 --- /dev/null +++ b/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-.patch @@ -0,0 +1,154 @@ +From cc526fef95a54106669a0547ff687232cd7fbcc7 Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Sun, 9 Aug 2015 15:12:50 -0700 +Subject: ANDROID: usb: gadget: configfs: Add device attribute + to determine gadget state + +Android frameworks (UsbDeviceManager) relies on gadget state exported +through device attributes. This CL adds the device attribute to export +USB gadget state. + +Bug: 68755607 +Bug: 120441124 +Change-Id: Id0391810d75b58c579610fbec6e37ab22f28886d +[badhri: Migrate to using udc uevents from upstream sysfs.] +Signed-off-by: Badhri Jagan Sridharan +[AmitP: Folded following android-4.9 commit changes into this patch + Parts of e45c769fa7af ("ANDROID: usb: gadget: cleanup: fix unused variable and function warnings") +Signed-off-by: Amit Pundir +--- + drivers/usb/gadget/configfs.c | 91 ++++++++++++++++++++--------------- + 1 file changed, 52 insertions(+), 39 deletions(-) + +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index da151de74e1dc..b0148a4493065 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -1605,6 +1605,54 @@ static struct device_attribute *android_usb_attributes[] = { + &dev_attr_state, + NULL + }; ++ ++static int android_device_create(struct gadget_info *gi) ++{ ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ ++ INIT_WORK(&gi->work, android_work); ++ android_device = device_create(android_class, NULL, ++ MKDEV(0, 0), NULL, "android0"); ++ if (IS_ERR(android_device)) ++ return PTR_ERR(android_device); ++ ++ dev_set_drvdata(android_device, gi); ++ ++ attrs = android_usb_attributes; ++ while ((attr = *attrs++)) { ++ int err; ++ ++ err = device_create_file(android_device, attr); ++ if (err) { ++ device_destroy(android_device->class, ++ android_device->devt); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ ++static void android_device_destroy(void) ++{ ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ ++ attrs = android_usb_attributes; ++ while ((attr = *attrs++)) ++ device_remove_file(android_device, attr); ++ device_destroy(android_device->class, android_device->devt); ++} ++#else ++static inline int android_device_create(struct gadget_info *gi) ++{ ++ return 0; ++} ++ ++static inline void android_device_destroy(void) ++{ ++} + #endif + + static struct config_group *gadgets_make( +@@ -1612,9 +1660,6 @@ static struct config_group *gadgets_make( + const char *name) + { + struct gadget_info *gi; +- struct device_attribute **attrs; +- struct device_attribute *attr; +- int err; + + gi = kzalloc(sizeof(*gi), GFP_KERNEL); + if (!gi) +@@ -1658,37 +1703,14 @@ static struct config_group *gadgets_make( + gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); + gi->composite.name = gi->composite.gadget_driver.function; + +-#ifdef CONFIG_USB_CONFIGFS_UEVENT +- INIT_WORK(&gi->work, android_work); +- android_device = device_create(android_class, NULL, +- MKDEV(0, 0), NULL, "android0"); +- if (IS_ERR(android_device)) ++ if (!gi->composite.gadget_driver.function) + goto err; + +- dev_set_drvdata(android_device, gi); +- +- attrs = android_usb_attributes; +- while ((attr = *attrs++)) { +- err = device_create_file(android_device, attr); +- if (err) +- goto err1; +- } +-#endif +- +- if (!gi->composite.gadget_driver.function) +- goto err1; ++ if (android_device_create(gi) < 0) ++ goto err; + + return &gi->group; + +-err1: +-#ifdef CONFIG_USB_CONFIGFS_UEVENT +- attrs = android_usb_attributes; +- while ((attr = *attrs++)) +- device_remove_file(android_device, attr); +- +- device_destroy(android_device->class, +- android_device->devt); +-#endif + err: + kfree(gi); + return ERR_PTR(-ENOMEM); +@@ -1696,17 +1718,8 @@ static struct config_group *gadgets_make( + + static void gadgets_drop(struct config_group *group, struct config_item *item) + { +- struct device_attribute **attrs; +- struct device_attribute *attr; +- + config_item_put(item); +- +-#ifdef CONFIG_USB_CONFIGFS_UEVENT +- attrs = android_usb_attributes; +- while ((attr = *attrs++)) +- device_remove_file(android_device, attr); +- device_destroy(android_device->class, android_device->devt); +-#endif ++ android_device_destroy(); + } + + static struct configfs_group_operations gadgets_ops = { +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-.patch b/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-.patch new file mode 100644 index 000000000000..e1902062a8a0 --- /dev/null +++ b/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-.patch @@ -0,0 +1,110 @@ +From 01a2200f07d91b9c71b92ceab8e2b23a7d4e6084 Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Fri, 27 Mar 2015 14:15:19 -0700 +Subject: ANDROID: usb: gadget: configfs: Add function devices + to the parent + +Added create_function_device to create child +function devices for USB gadget functions. +Android UsbDeviceManager relies on communicating +to the devices created by the gadget functions +to implement functions such as audio_source. + +Bug: 63740241 +Bug: 68755607 +Bug: 78114713 +Bug: 120441124 +Change-Id: I0df9ad86ac32d8cdacdea164e9fed49891b45fc2 +[badhri: This is a supporting patch for other patches which have + replacements pipelined. It can be dropped when those + implementations land.] +Signed-off-by: Badhri Jagan Sridharan +--- + drivers/usb/gadget/configfs.c | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index bbc166f998930..3237f450d4ab5 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -21,6 +21,18 @@ extern int acc_ctrlrequest(struct usb_composite_dev *cdev, + void acc_disconnect(void); + #endif + static struct class *android_class; ++static struct device *android_device; ++static int index; ++ ++struct device *create_function_device(char *name) ++{ ++ if (android_device && !IS_ERR(android_device)) ++ return device_create(android_class, android_device, ++ MKDEV(0, index++), NULL, name); ++ else ++ return ERR_PTR(-EINVAL); ++} ++EXPORT_SYMBOL_GPL(create_function_device); + #endif + + int check_user_usb_string(const char *name, +@@ -1418,19 +1430,22 @@ static void android_work(struct work_struct *data) + spin_unlock_irqrestore(&cdev->lock, flags); + + if (status[0]) { +- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); ++ kobject_uevent_env(&android_device->kobj, ++ KOBJ_CHANGE, connected); + pr_info("%s: sent uevent %s\n", __func__, connected[0]); + uevent_sent = true; + } + + if (status[1]) { +- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); ++ kobject_uevent_env(&android_device->kobj, ++ KOBJ_CHANGE, configured); + pr_info("%s: sent uevent %s\n", __func__, configured[0]); + uevent_sent = true; + } + + if (status[2]) { +- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); ++ kobject_uevent_env(&android_device->kobj, ++ KOBJ_CHANGE, disconnected); + pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); + uevent_sent = true; + } +@@ -1607,8 +1622,10 @@ static struct config_group *gadgets_make( + + #ifdef CONFIG_USB_CONFIGFS_UEVENT + INIT_WORK(&gi->work, android_work); +- gi->dev = device_create(android_class, NULL, ++ android_device = device_create(android_class, NULL, + MKDEV(0, 0), NULL, "android0"); ++ if (IS_ERR(android_device)) ++ goto err; + #endif + + if (!gi->composite.gadget_driver.function) +@@ -1623,6 +1640,9 @@ static struct config_group *gadgets_make( + static void gadgets_drop(struct config_group *group, struct config_item *item) + { + config_item_put(item); ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ device_destroy(android_device->class, android_device->devt); ++#endif + } + + static struct configfs_group_operations gadgets_ops = { +@@ -1676,5 +1696,10 @@ module_init(gadget_cfs_init); + static void __exit gadget_cfs_exit(void) + { + configfs_unregister_subsystem(&gadget_subsys); ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ if (!IS_ERR(android_class)) ++ class_destroy(android_class); ++#endif ++ + } + module_exit(gadget_cfs_exit); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-a.patch b/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-a.patch new file mode 100644 index 000000000000..65f69f63777a --- /dev/null +++ b/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-a.patch @@ -0,0 +1,124 @@ +From 31becf77b35259a09c54843c1b4fae314cd7a5fd Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Tue, 14 Jul 2015 15:46:11 -0700 +Subject: ANDROID: usb: gadget: configfs: Add "state" attribute + to android_device + +Added a device attribute to android_device to +determine USB_GADGET's state + +Bug: 68755607 +Bug: 120441124 +Change-Id: I17f8903120df96bf2f4bf441940b53a87b818230 +[badhri: Migrate to using udc uevents from upstream sysfs.] +Signed-off-by: Badhri Jagan Sridharan +--- + drivers/usb/gadget/configfs.c | 66 ++++++++++++++++++++++++++++++++++- + 1 file changed, 65 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 3237f450d4ab5..da151de74e1dc 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -1572,11 +1572,49 @@ static const struct usb_gadget_driver configfs_driver_template = { + .match_existing_only = 1, + }; + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++static ssize_t state_show(struct device *pdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct gadget_info *dev = dev_get_drvdata(pdev); ++ struct usb_composite_dev *cdev; ++ char *state = "DISCONNECTED"; ++ unsigned long flags; ++ ++ if (!dev) ++ goto out; ++ ++ cdev = &dev->cdev; ++ ++ if (!cdev) ++ goto out; ++ ++ spin_lock_irqsave(&cdev->lock, flags); ++ if (cdev->config) ++ state = "CONFIGURED"; ++ else if (dev->connected) ++ state = "CONNECTED"; ++ spin_unlock_irqrestore(&cdev->lock, flags); ++out: ++ return sprintf(buf, "%s\n", state); ++} ++ ++static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); ++ ++static struct device_attribute *android_usb_attributes[] = { ++ &dev_attr_state, ++ NULL ++}; ++#endif ++ + static struct config_group *gadgets_make( + struct config_group *group, + const char *name) + { + struct gadget_info *gi; ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ int err; + + gi = kzalloc(sizeof(*gi), GFP_KERNEL); + if (!gi) +@@ -1626,12 +1664,31 @@ static struct config_group *gadgets_make( + MKDEV(0, 0), NULL, "android0"); + if (IS_ERR(android_device)) + goto err; ++ ++ dev_set_drvdata(android_device, gi); ++ ++ attrs = android_usb_attributes; ++ while ((attr = *attrs++)) { ++ err = device_create_file(android_device, attr); ++ if (err) ++ goto err1; ++ } + #endif + + if (!gi->composite.gadget_driver.function) +- goto err; ++ goto err1; + + return &gi->group; ++ ++err1: ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++ attrs = android_usb_attributes; ++ while ((attr = *attrs++)) ++ device_remove_file(android_device, attr); ++ ++ device_destroy(android_device->class, ++ android_device->devt); ++#endif + err: + kfree(gi); + return ERR_PTR(-ENOMEM); +@@ -1639,8 +1696,15 @@ static struct config_group *gadgets_make( + + static void gadgets_drop(struct config_group *group, struct config_item *item) + { ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ + config_item_put(item); ++ + #ifdef CONFIG_USB_CONFIGFS_UEVENT ++ attrs = android_usb_attributes; ++ while ((attr = *attrs++)) ++ device_remove_file(android_device, attr); + device_destroy(android_device->class, android_device->devt); + #endif + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-.patch b/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-.patch new file mode 100644 index 000000000000..b590d6b6facb --- /dev/null +++ b/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-.patch @@ -0,0 +1,39 @@ +From 219a8a80b5603ddfd2ade974d94c2f349d25d1d0 Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Mon, 15 Dec 2014 16:42:27 -0800 +Subject: ANDROID: usb: gadget: configfs: Add usb_function ptr + to fi struct + +Add a pointer to the usb_function inside the +usb_function_instance structure to service +functions specific setup requests even before +the function gets added to the usb_gadget + +Bug: 63740241 +Bug: 68755607 +Bug: 78114713 +Bug: 120441124 +Change-Id: I6f457006f6c5516cc6986ec2acdf5b1ecf259d0c +[badhri: This is a supporting patch for other patches which have + replacements pipelined. It can be dropped when those + implementations land.] +Signed-off-by: Badhri Jagan Sridharan +--- + include/linux/usb/composite.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h +index 8675e145ea8b3..af4396cc4ea86 100644 +--- a/include/linux/usb/composite.h ++++ b/include/linux/usb/composite.h +@@ -587,6 +587,7 @@ struct usb_function_instance { + struct config_group group; + struct list_head cfs_list; + struct usb_function_driver *fd; ++ struct usb_function *f; + int (*set_inst_name)(struct usb_function_instance *inst, + const char *name); + void (*free_func_inst)(struct usb_function_instance *inst); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory.patch b/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory.patch new file mode 100644 index 000000000000..cd56699ac4db --- /dev/null +++ b/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory.patch @@ -0,0 +1,1629 @@ +From 71388f725739922343b759e3e5056b0232b49d15 Mon Sep 17 00:00:00 2001 +From: Benoit Goby +Date: Mon, 19 Dec 2011 14:39:37 -0800 +Subject: ANDROID: usb: gadget: f_accessory: Add Android + Accessory function + +USB accessory mode allows users to connect USB host hardware +specifically designed for Android-powered devices. The accessories +must adhere to the Android accessory protocol outlined in the +http://accessories.android.com documentation. This allows +Android devices that cannot act as a USB host to still interact with +USB hardware. When an Android device is in USB accessory mode, the +attached Android USB accessory acts as the host, provides power +to the USB bus, and enumerates connected devices. + +Bug: 63740241 +Bug: 120441124 +Change-Id: I67964b50d278f3c0471d47efbb7b0973a3502681 +[badhri: f_accessory is being migrated to userspace.] +Signed-off-by: Mike Lockwood +[AmitP: Folded following android-4.9 commit changes into this patch + ceb2f0aac624 ("ANDROID: usb: gadget: accessory: Fix section mismatch") + Parts of e27543931009 ("ANDROID: usb: gadget: Fixes and hacks to make android usb gadget compile on 3.8") + 1b07ec751563 ("ANDROID: drivers: usb: gadget: 64-bit related type fixes")] +Signed-off-by: Amit Pundir +[astrachan: Folded the following changes into this patch: + 9d5891d516e2 ("ANDROID: usb: gadget: f_accessory: Add ACCESSORY_SET_AUDIO_MODE control request and ioctl") + dc66cfce9622 ("ANDROID: usb: gadget: f_accessory: Add support for HID input devices") + 5f1ac9c2871b ("ANDROID: usb: gadget: f_accessory: move userspace interface to uapi") + 9a6241722cd8 ("ANDROID: usb: gadget: f_accessory: Enabled Zero Length Packet (ZLP) for acc_write") + 31a0ecd5a825 ("ANDROID: usb: gadget: f_accessory: check for accessory device before disconnecting HIDs") + 580721fa6cbc ("ANDROID: usb: gadget: f_accessory: Migrate to USB_FUNCTION API") + 7f407172fb28 ("ANDROID: usb: gadget: f_accessory: Fix for UsbAccessory clean unbind.") + ebc98ac5a22f ("ANDROID: usb: gadget: f_accessory: fix false disconnect due to a signal sent to the reading process") + 71c6dc5ffdab ("ANDROID: usb: gadget: f_accessory: assign no-op request complete callbacks") + 675047ee68e9 ("ANDROID: usb: gadget: f_accessory: Move gadget functions code") + b2bedaa5c7df ("CHROMIUM: usb: gadget: f_accessory: add .raw_request callback")] +Signed-off-by: Alistair Strachan +--- + drivers/usb/gadget/Kconfig | 10 + + drivers/usb/gadget/function/Makefile | 2 + + drivers/usb/gadget/function/f_accessory.c | 1352 +++++++++++++++++++++ + include/linux/usb/f_accessory.h | 23 + + include/uapi/linux/usb/f_accessory.h | 146 +++ + 5 files changed, 1533 insertions(+) + create mode 100644 drivers/usb/gadget/function/f_accessory.c + create mode 100644 include/linux/usb/f_accessory.h + create mode 100644 include/uapi/linux/usb/f_accessory.h + +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index f5e82dcac5835..7749fb1decb01 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -216,6 +216,9 @@ config USB_F_PRINTER + config USB_F_TCM + tristate + ++config USB_F_ACC ++ tristate ++ + # this first set of drivers all depend on bulk-capable hardware. + + config USB_CONFIGFS +@@ -377,6 +380,13 @@ config USB_CONFIGFS_F_FS + implemented in kernel space (for instance Ethernet, serial or + mass storage) and other are implemented in user space. + ++config USB_CONFIGFS_F_ACC ++ bool "Accessory gadget" ++ depends on USB_CONFIGFS ++ select USB_F_ACC ++ help ++ USB gadget Accessory support ++ + config USB_CONFIGFS_F_UAC1 + bool "Audio Class 1.0" + depends on USB_CONFIGFS +diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile +index 5d3a6cf022185..2305360e5f22d 100644 +--- a/drivers/usb/gadget/function/Makefile ++++ b/drivers/usb/gadget/function/Makefile +@@ -50,3 +50,5 @@ usb_f_printer-y := f_printer.o + obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o + usb_f_tcm-y := f_tcm.o + obj-$(CONFIG_USB_F_TCM) += usb_f_tcm.o ++usb_f_accessory-y := f_accessory.o ++obj-$(CONFIG_USB_F_ACC) += usb_f_accessory.o +diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c +new file mode 100644 +index 0000000000000..7aa2656a2328b +--- /dev/null ++++ b/drivers/usb/gadget/function/f_accessory.c +@@ -0,0 +1,1352 @@ ++/* ++ * Gadget Function Driver for Android USB accessories ++ * ++ * Copyright (C) 2011 Google, Inc. ++ * Author: Mike Lockwood ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++/* #define DEBUG */ ++/* #define VERBOSE_DEBUG */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define MAX_INST_NAME_LEN 40 ++#define BULK_BUFFER_SIZE 16384 ++#define ACC_STRING_SIZE 256 ++ ++#define PROTOCOL_VERSION 2 ++ ++/* String IDs */ ++#define INTERFACE_STRING_INDEX 0 ++ ++/* number of tx and rx requests to allocate */ ++#define TX_REQ_MAX 4 ++#define RX_REQ_MAX 2 ++ ++struct acc_hid_dev { ++ struct list_head list; ++ struct hid_device *hid; ++ struct acc_dev *dev; ++ /* accessory defined ID */ ++ int id; ++ /* HID report descriptor */ ++ u8 *report_desc; ++ /* length of HID report descriptor */ ++ int report_desc_len; ++ /* number of bytes of report_desc we have received so far */ ++ int report_desc_offset; ++}; ++ ++struct acc_dev { ++ struct usb_function function; ++ struct usb_composite_dev *cdev; ++ spinlock_t lock; ++ ++ struct usb_ep *ep_in; ++ struct usb_ep *ep_out; ++ ++ /* online indicates state of function_set_alt & function_unbind ++ * set to 1 when we connect ++ */ ++ int online:1; ++ ++ /* disconnected indicates state of open & release ++ * Set to 1 when we disconnect. ++ * Not cleared until our file is closed. ++ */ ++ int disconnected:1; ++ ++ /* strings sent by the host */ ++ char manufacturer[ACC_STRING_SIZE]; ++ char model[ACC_STRING_SIZE]; ++ char description[ACC_STRING_SIZE]; ++ char version[ACC_STRING_SIZE]; ++ char uri[ACC_STRING_SIZE]; ++ char serial[ACC_STRING_SIZE]; ++ ++ /* for acc_complete_set_string */ ++ int string_index; ++ ++ /* set to 1 if we have a pending start request */ ++ int start_requested; ++ ++ int audio_mode; ++ ++ /* synchronize access to our device file */ ++ atomic_t open_excl; ++ ++ struct list_head tx_idle; ++ ++ wait_queue_head_t read_wq; ++ wait_queue_head_t write_wq; ++ struct usb_request *rx_req[RX_REQ_MAX]; ++ int rx_done; ++ ++ /* delayed work for handling ACCESSORY_START */ ++ struct delayed_work start_work; ++ ++ /* worker for registering and unregistering hid devices */ ++ struct work_struct hid_work; ++ ++ /* list of active HID devices */ ++ struct list_head hid_list; ++ ++ /* list of new HID devices to register */ ++ struct list_head new_hid_list; ++ ++ /* list of dead HID devices to unregister */ ++ struct list_head dead_hid_list; ++}; ++ ++static struct usb_interface_descriptor acc_interface_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bInterfaceNumber = 0, ++ .bNumEndpoints = 2, ++ .bInterfaceClass = USB_CLASS_VENDOR_SPEC, ++ .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, ++ .bInterfaceProtocol = 0, ++}; ++ ++static struct usb_endpoint_descriptor acc_highspeed_in_desc = { ++ .bLength = USB_DT_ENDPOINT_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_IN, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ .wMaxPacketSize = __constant_cpu_to_le16(512), ++}; ++ ++static struct usb_endpoint_descriptor acc_highspeed_out_desc = { ++ .bLength = USB_DT_ENDPOINT_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_OUT, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ .wMaxPacketSize = __constant_cpu_to_le16(512), ++}; ++ ++static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { ++ .bLength = USB_DT_ENDPOINT_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_IN, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++}; ++ ++static struct usb_endpoint_descriptor acc_fullspeed_out_desc = { ++ .bLength = USB_DT_ENDPOINT_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_OUT, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++}; ++ ++static struct usb_descriptor_header *fs_acc_descs[] = { ++ (struct usb_descriptor_header *) &acc_interface_desc, ++ (struct usb_descriptor_header *) &acc_fullspeed_in_desc, ++ (struct usb_descriptor_header *) &acc_fullspeed_out_desc, ++ NULL, ++}; ++ ++static struct usb_descriptor_header *hs_acc_descs[] = { ++ (struct usb_descriptor_header *) &acc_interface_desc, ++ (struct usb_descriptor_header *) &acc_highspeed_in_desc, ++ (struct usb_descriptor_header *) &acc_highspeed_out_desc, ++ NULL, ++}; ++ ++static struct usb_string acc_string_defs[] = { ++ [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", ++ { }, /* end of list */ ++}; ++ ++static struct usb_gadget_strings acc_string_table = { ++ .language = 0x0409, /* en-US */ ++ .strings = acc_string_defs, ++}; ++ ++static struct usb_gadget_strings *acc_strings[] = { ++ &acc_string_table, ++ NULL, ++}; ++ ++/* temporary variable used between acc_open() and acc_gadget_bind() */ ++static struct acc_dev *_acc_dev; ++ ++struct acc_instance { ++ struct usb_function_instance func_inst; ++ const char *name; ++}; ++ ++static inline struct acc_dev *func_to_dev(struct usb_function *f) ++{ ++ return container_of(f, struct acc_dev, function); ++} ++ ++static struct usb_request *acc_request_new(struct usb_ep *ep, int buffer_size) ++{ ++ struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); ++ ++ if (!req) ++ return NULL; ++ ++ /* now allocate buffers for the requests */ ++ req->buf = kmalloc(buffer_size, GFP_KERNEL); ++ if (!req->buf) { ++ usb_ep_free_request(ep, req); ++ return NULL; ++ } ++ ++ return req; ++} ++ ++static void acc_request_free(struct usb_request *req, struct usb_ep *ep) ++{ ++ if (req) { ++ kfree(req->buf); ++ usb_ep_free_request(ep, req); ++ } ++} ++ ++/* add a request to the tail of a list */ ++static void req_put(struct acc_dev *dev, struct list_head *head, ++ struct usb_request *req) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ list_add_tail(&req->list, head); ++ spin_unlock_irqrestore(&dev->lock, flags); ++} ++ ++/* remove a request from the head of a list */ ++static struct usb_request *req_get(struct acc_dev *dev, struct list_head *head) ++{ ++ unsigned long flags; ++ struct usb_request *req; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ if (list_empty(head)) { ++ req = 0; ++ } else { ++ req = list_first_entry(head, struct usb_request, list); ++ list_del(&req->list); ++ } ++ spin_unlock_irqrestore(&dev->lock, flags); ++ return req; ++} ++ ++static void acc_set_disconnected(struct acc_dev *dev) ++{ ++ dev->disconnected = 1; ++} ++ ++static void acc_complete_in(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct acc_dev *dev = _acc_dev; ++ ++ if (req->status == -ESHUTDOWN) { ++ pr_debug("acc_complete_in set disconnected"); ++ acc_set_disconnected(dev); ++ } ++ ++ req_put(dev, &dev->tx_idle, req); ++ ++ wake_up(&dev->write_wq); ++} ++ ++static void acc_complete_out(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct acc_dev *dev = _acc_dev; ++ ++ dev->rx_done = 1; ++ if (req->status == -ESHUTDOWN) { ++ pr_debug("acc_complete_out set disconnected"); ++ acc_set_disconnected(dev); ++ } ++ ++ wake_up(&dev->read_wq); ++} ++ ++static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct acc_dev *dev = ep->driver_data; ++ char *string_dest = NULL; ++ int length = req->actual; ++ ++ if (req->status != 0) { ++ pr_err("acc_complete_set_string, err %d\n", req->status); ++ return; ++ } ++ ++ switch (dev->string_index) { ++ case ACCESSORY_STRING_MANUFACTURER: ++ string_dest = dev->manufacturer; ++ break; ++ case ACCESSORY_STRING_MODEL: ++ string_dest = dev->model; ++ break; ++ case ACCESSORY_STRING_DESCRIPTION: ++ string_dest = dev->description; ++ break; ++ case ACCESSORY_STRING_VERSION: ++ string_dest = dev->version; ++ break; ++ case ACCESSORY_STRING_URI: ++ string_dest = dev->uri; ++ break; ++ case ACCESSORY_STRING_SERIAL: ++ string_dest = dev->serial; ++ break; ++ } ++ if (string_dest) { ++ unsigned long flags; ++ ++ if (length >= ACC_STRING_SIZE) ++ length = ACC_STRING_SIZE - 1; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ memcpy(string_dest, req->buf, length); ++ /* ensure zero termination */ ++ string_dest[length] = 0; ++ spin_unlock_irqrestore(&dev->lock, flags); ++ } else { ++ pr_err("unknown accessory string index %d\n", ++ dev->string_index); ++ } ++} ++ ++static void acc_complete_set_hid_report_desc(struct usb_ep *ep, ++ struct usb_request *req) ++{ ++ struct acc_hid_dev *hid = req->context; ++ struct acc_dev *dev = hid->dev; ++ int length = req->actual; ++ ++ if (req->status != 0) { ++ pr_err("acc_complete_set_hid_report_desc, err %d\n", ++ req->status); ++ return; ++ } ++ ++ memcpy(hid->report_desc + hid->report_desc_offset, req->buf, length); ++ hid->report_desc_offset += length; ++ if (hid->report_desc_offset == hid->report_desc_len) { ++ /* After we have received the entire report descriptor ++ * we schedule work to initialize the HID device ++ */ ++ schedule_work(&dev->hid_work); ++ } ++} ++ ++static void acc_complete_send_hid_event(struct usb_ep *ep, ++ struct usb_request *req) ++{ ++ struct acc_hid_dev *hid = req->context; ++ int length = req->actual; ++ ++ if (req->status != 0) { ++ pr_err("acc_complete_send_hid_event, err %d\n", req->status); ++ return; ++ } ++ ++ hid_report_raw_event(hid->hid, HID_INPUT_REPORT, req->buf, length, 1); ++} ++ ++static int acc_hid_parse(struct hid_device *hid) ++{ ++ struct acc_hid_dev *hdev = hid->driver_data; ++ ++ hid_parse_report(hid, hdev->report_desc, hdev->report_desc_len); ++ return 0; ++} ++ ++static int acc_hid_start(struct hid_device *hid) ++{ ++ return 0; ++} ++ ++static void acc_hid_stop(struct hid_device *hid) ++{ ++} ++ ++static int acc_hid_open(struct hid_device *hid) ++{ ++ return 0; ++} ++ ++static void acc_hid_close(struct hid_device *hid) ++{ ++} ++ ++static int acc_hid_raw_request(struct hid_device *hid, unsigned char reportnum, ++ __u8 *buf, size_t len, unsigned char rtype, int reqtype) ++{ ++ return 0; ++} ++ ++static struct hid_ll_driver acc_hid_ll_driver = { ++ .parse = acc_hid_parse, ++ .start = acc_hid_start, ++ .stop = acc_hid_stop, ++ .open = acc_hid_open, ++ .close = acc_hid_close, ++ .raw_request = acc_hid_raw_request, ++}; ++ ++static struct acc_hid_dev *acc_hid_new(struct acc_dev *dev, ++ int id, int desc_len) ++{ ++ struct acc_hid_dev *hdev; ++ ++ hdev = kzalloc(sizeof(*hdev), GFP_ATOMIC); ++ if (!hdev) ++ return NULL; ++ hdev->report_desc = kzalloc(desc_len, GFP_ATOMIC); ++ if (!hdev->report_desc) { ++ kfree(hdev); ++ return NULL; ++ } ++ hdev->dev = dev; ++ hdev->id = id; ++ hdev->report_desc_len = desc_len; ++ ++ return hdev; ++} ++ ++static struct acc_hid_dev *acc_hid_get(struct list_head *list, int id) ++{ ++ struct acc_hid_dev *hid; ++ ++ list_for_each_entry(hid, list, list) { ++ if (hid->id == id) ++ return hid; ++ } ++ return NULL; ++} ++ ++static int acc_register_hid(struct acc_dev *dev, int id, int desc_length) ++{ ++ struct acc_hid_dev *hid; ++ unsigned long flags; ++ ++ /* report descriptor length must be > 0 */ ++ if (desc_length <= 0) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ /* replace HID if one already exists with this ID */ ++ hid = acc_hid_get(&dev->hid_list, id); ++ if (!hid) ++ hid = acc_hid_get(&dev->new_hid_list, id); ++ if (hid) ++ list_move(&hid->list, &dev->dead_hid_list); ++ ++ hid = acc_hid_new(dev, id, desc_length); ++ if (!hid) { ++ spin_unlock_irqrestore(&dev->lock, flags); ++ return -ENOMEM; ++ } ++ ++ list_add(&hid->list, &dev->new_hid_list); ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ /* schedule work to register the HID device */ ++ schedule_work(&dev->hid_work); ++ return 0; ++} ++ ++static int acc_unregister_hid(struct acc_dev *dev, int id) ++{ ++ struct acc_hid_dev *hid; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ hid = acc_hid_get(&dev->hid_list, id); ++ if (!hid) ++ hid = acc_hid_get(&dev->new_hid_list, id); ++ if (!hid) { ++ spin_unlock_irqrestore(&dev->lock, flags); ++ return -EINVAL; ++ } ++ ++ list_move(&hid->list, &dev->dead_hid_list); ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ schedule_work(&dev->hid_work); ++ return 0; ++} ++ ++static int create_bulk_endpoints(struct acc_dev *dev, ++ struct usb_endpoint_descriptor *in_desc, ++ struct usb_endpoint_descriptor *out_desc) ++{ ++ struct usb_composite_dev *cdev = dev->cdev; ++ struct usb_request *req; ++ struct usb_ep *ep; ++ int i; ++ ++ DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); ++ ++ ep = usb_ep_autoconfig(cdev->gadget, in_desc); ++ if (!ep) { ++ DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); ++ return -ENODEV; ++ } ++ DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); ++ ep->driver_data = dev; /* claim the endpoint */ ++ dev->ep_in = ep; ++ ++ ep = usb_ep_autoconfig(cdev->gadget, out_desc); ++ if (!ep) { ++ DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); ++ return -ENODEV; ++ } ++ DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); ++ ep->driver_data = dev; /* claim the endpoint */ ++ dev->ep_out = ep; ++ ++ /* now allocate requests for our endpoints */ ++ for (i = 0; i < TX_REQ_MAX; i++) { ++ req = acc_request_new(dev->ep_in, BULK_BUFFER_SIZE); ++ if (!req) ++ goto fail; ++ req->complete = acc_complete_in; ++ req_put(dev, &dev->tx_idle, req); ++ } ++ for (i = 0; i < RX_REQ_MAX; i++) { ++ req = acc_request_new(dev->ep_out, BULK_BUFFER_SIZE); ++ if (!req) ++ goto fail; ++ req->complete = acc_complete_out; ++ dev->rx_req[i] = req; ++ } ++ ++ return 0; ++ ++fail: ++ pr_err("acc_bind() could not allocate requests\n"); ++ while ((req = req_get(dev, &dev->tx_idle))) ++ acc_request_free(req, dev->ep_in); ++ for (i = 0; i < RX_REQ_MAX; i++) ++ acc_request_free(dev->rx_req[i], dev->ep_out); ++ return -1; ++} ++ ++static ssize_t acc_read(struct file *fp, char __user *buf, ++ size_t count, loff_t *pos) ++{ ++ struct acc_dev *dev = fp->private_data; ++ struct usb_request *req; ++ ssize_t r = count; ++ unsigned xfer; ++ int ret = 0; ++ ++ pr_debug("acc_read(%zu)\n", count); ++ ++ if (dev->disconnected) { ++ pr_debug("acc_read disconnected"); ++ return -ENODEV; ++ } ++ ++ if (count > BULK_BUFFER_SIZE) ++ count = BULK_BUFFER_SIZE; ++ ++ /* we will block until we're online */ ++ pr_debug("acc_read: waiting for online\n"); ++ ret = wait_event_interruptible(dev->read_wq, dev->online); ++ if (ret < 0) { ++ r = ret; ++ goto done; ++ } ++ ++ if (dev->rx_done) { ++ // last req cancelled. try to get it. ++ req = dev->rx_req[0]; ++ goto copy_data; ++ } ++ ++requeue_req: ++ /* queue a request */ ++ req = dev->rx_req[0]; ++ req->length = count; ++ dev->rx_done = 0; ++ ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); ++ if (ret < 0) { ++ r = -EIO; ++ goto done; ++ } else { ++ pr_debug("rx %p queue\n", req); ++ } ++ ++ /* wait for a request to complete */ ++ ret = wait_event_interruptible(dev->read_wq, dev->rx_done); ++ if (ret < 0) { ++ r = ret; ++ ret = usb_ep_dequeue(dev->ep_out, req); ++ if (ret != 0) { ++ // cancel failed. There can be a data already received. ++ // it will be retrieved in the next read. ++ pr_debug("acc_read: cancelling failed %d", ret); ++ } ++ goto done; ++ } ++ ++copy_data: ++ dev->rx_done = 0; ++ if (dev->online) { ++ /* If we got a 0-len packet, throw it back and try again. */ ++ if (req->actual == 0) ++ goto requeue_req; ++ ++ pr_debug("rx %p %u\n", req, req->actual); ++ xfer = (req->actual < count) ? req->actual : count; ++ r = xfer; ++ if (copy_to_user(buf, req->buf, xfer)) ++ r = -EFAULT; ++ } else ++ r = -EIO; ++ ++done: ++ pr_debug("acc_read returning %zd\n", r); ++ return r; ++} ++ ++static ssize_t acc_write(struct file *fp, const char __user *buf, ++ size_t count, loff_t *pos) ++{ ++ struct acc_dev *dev = fp->private_data; ++ struct usb_request *req = 0; ++ ssize_t r = count; ++ unsigned xfer; ++ int ret; ++ ++ pr_debug("acc_write(%zu)\n", count); ++ ++ if (!dev->online || dev->disconnected) { ++ pr_debug("acc_write disconnected or not online"); ++ return -ENODEV; ++ } ++ ++ while (count > 0) { ++ if (!dev->online) { ++ pr_debug("acc_write dev->error\n"); ++ r = -EIO; ++ break; ++ } ++ ++ /* get an idle tx request to use */ ++ req = 0; ++ ret = wait_event_interruptible(dev->write_wq, ++ ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); ++ if (!req) { ++ r = ret; ++ break; ++ } ++ ++ if (count > BULK_BUFFER_SIZE) { ++ xfer = BULK_BUFFER_SIZE; ++ /* ZLP, They will be more TX requests so not yet. */ ++ req->zero = 0; ++ } else { ++ xfer = count; ++ /* If the data length is a multple of the ++ * maxpacket size then send a zero length packet(ZLP). ++ */ ++ req->zero = ((xfer % dev->ep_in->maxpacket) == 0); ++ } ++ if (copy_from_user(req->buf, buf, xfer)) { ++ r = -EFAULT; ++ break; ++ } ++ ++ req->length = xfer; ++ ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); ++ if (ret < 0) { ++ pr_debug("acc_write: xfer error %d\n", ret); ++ r = -EIO; ++ break; ++ } ++ ++ buf += xfer; ++ count -= xfer; ++ ++ /* zero this so we don't try to free it on error exit */ ++ req = 0; ++ } ++ ++ if (req) ++ req_put(dev, &dev->tx_idle, req); ++ ++ pr_debug("acc_write returning %zd\n", r); ++ return r; ++} ++ ++static long acc_ioctl(struct file *fp, unsigned code, unsigned long value) ++{ ++ struct acc_dev *dev = fp->private_data; ++ char *src = NULL; ++ int ret; ++ ++ switch (code) { ++ case ACCESSORY_GET_STRING_MANUFACTURER: ++ src = dev->manufacturer; ++ break; ++ case ACCESSORY_GET_STRING_MODEL: ++ src = dev->model; ++ break; ++ case ACCESSORY_GET_STRING_DESCRIPTION: ++ src = dev->description; ++ break; ++ case ACCESSORY_GET_STRING_VERSION: ++ src = dev->version; ++ break; ++ case ACCESSORY_GET_STRING_URI: ++ src = dev->uri; ++ break; ++ case ACCESSORY_GET_STRING_SERIAL: ++ src = dev->serial; ++ break; ++ case ACCESSORY_IS_START_REQUESTED: ++ return dev->start_requested; ++ case ACCESSORY_GET_AUDIO_MODE: ++ return dev->audio_mode; ++ } ++ if (!src) ++ return -EINVAL; ++ ++ ret = strlen(src) + 1; ++ if (copy_to_user((void __user *)value, src, ret)) ++ ret = -EFAULT; ++ return ret; ++} ++ ++static int acc_open(struct inode *ip, struct file *fp) ++{ ++ printk(KERN_INFO "acc_open\n"); ++ if (atomic_xchg(&_acc_dev->open_excl, 1)) ++ return -EBUSY; ++ ++ _acc_dev->disconnected = 0; ++ fp->private_data = _acc_dev; ++ return 0; ++} ++ ++static int acc_release(struct inode *ip, struct file *fp) ++{ ++ printk(KERN_INFO "acc_release\n"); ++ ++ WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0)); ++ /* indicate that we are disconnected ++ * still could be online so don't touch online flag ++ */ ++ _acc_dev->disconnected = 1; ++ return 0; ++} ++ ++/* file operations for /dev/usb_accessory */ ++static const struct file_operations acc_fops = { ++ .owner = THIS_MODULE, ++ .read = acc_read, ++ .write = acc_write, ++ .unlocked_ioctl = acc_ioctl, ++ .open = acc_open, ++ .release = acc_release, ++}; ++ ++static int acc_hid_probe(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ int ret; ++ ++ ret = hid_parse(hdev); ++ if (ret) ++ return ret; ++ return hid_hw_start(hdev, HID_CONNECT_DEFAULT); ++} ++ ++static struct miscdevice acc_device = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "usb_accessory", ++ .fops = &acc_fops, ++}; ++ ++static const struct hid_device_id acc_hid_table[] = { ++ { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, ++ { } ++}; ++ ++static struct hid_driver acc_hid_driver = { ++ .name = "USB accessory", ++ .id_table = acc_hid_table, ++ .probe = acc_hid_probe, ++}; ++ ++static void acc_complete_setup_noop(struct usb_ep *ep, struct usb_request *req) ++{ ++ /* ++ * Default no-op function when nothing needs to be done for the ++ * setup request ++ */ ++} ++ ++int acc_ctrlrequest(struct usb_composite_dev *cdev, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct acc_dev *dev = _acc_dev; ++ int value = -EOPNOTSUPP; ++ struct acc_hid_dev *hid; ++ int offset; ++ u8 b_requestType = ctrl->bRequestType; ++ u8 b_request = ctrl->bRequest; ++ u16 w_index = le16_to_cpu(ctrl->wIndex); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u16 w_length = le16_to_cpu(ctrl->wLength); ++ unsigned long flags; ++ ++/* ++ printk(KERN_INFO "acc_ctrlrequest " ++ "%02x.%02x v%04x i%04x l%u\n", ++ b_requestType, b_request, ++ w_value, w_index, w_length); ++*/ ++ ++ if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { ++ if (b_request == ACCESSORY_START) { ++ dev->start_requested = 1; ++ schedule_delayed_work( ++ &dev->start_work, msecs_to_jiffies(10)); ++ value = 0; ++ cdev->req->complete = acc_complete_setup_noop; ++ } else if (b_request == ACCESSORY_SEND_STRING) { ++ dev->string_index = w_index; ++ cdev->gadget->ep0->driver_data = dev; ++ cdev->req->complete = acc_complete_set_string; ++ value = w_length; ++ } else if (b_request == ACCESSORY_SET_AUDIO_MODE && ++ w_index == 0 && w_length == 0) { ++ dev->audio_mode = w_value; ++ cdev->req->complete = acc_complete_setup_noop; ++ value = 0; ++ } else if (b_request == ACCESSORY_REGISTER_HID) { ++ cdev->req->complete = acc_complete_setup_noop; ++ value = acc_register_hid(dev, w_value, w_index); ++ } else if (b_request == ACCESSORY_UNREGISTER_HID) { ++ cdev->req->complete = acc_complete_setup_noop; ++ value = acc_unregister_hid(dev, w_value); ++ } else if (b_request == ACCESSORY_SET_HID_REPORT_DESC) { ++ spin_lock_irqsave(&dev->lock, flags); ++ hid = acc_hid_get(&dev->new_hid_list, w_value); ++ spin_unlock_irqrestore(&dev->lock, flags); ++ if (!hid) { ++ value = -EINVAL; ++ goto err; ++ } ++ offset = w_index; ++ if (offset != hid->report_desc_offset ++ || offset + w_length > hid->report_desc_len) { ++ value = -EINVAL; ++ goto err; ++ } ++ cdev->req->context = hid; ++ cdev->req->complete = acc_complete_set_hid_report_desc; ++ value = w_length; ++ } else if (b_request == ACCESSORY_SEND_HID_EVENT) { ++ spin_lock_irqsave(&dev->lock, flags); ++ hid = acc_hid_get(&dev->hid_list, w_value); ++ spin_unlock_irqrestore(&dev->lock, flags); ++ if (!hid) { ++ value = -EINVAL; ++ goto err; ++ } ++ cdev->req->context = hid; ++ cdev->req->complete = acc_complete_send_hid_event; ++ value = w_length; ++ } ++ } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { ++ if (b_request == ACCESSORY_GET_PROTOCOL) { ++ *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; ++ value = sizeof(u16); ++ cdev->req->complete = acc_complete_setup_noop; ++ /* clear any string left over from a previous session */ ++ memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); ++ memset(dev->model, 0, sizeof(dev->model)); ++ memset(dev->description, 0, sizeof(dev->description)); ++ memset(dev->version, 0, sizeof(dev->version)); ++ memset(dev->uri, 0, sizeof(dev->uri)); ++ memset(dev->serial, 0, sizeof(dev->serial)); ++ dev->start_requested = 0; ++ dev->audio_mode = 0; ++ } ++ } ++ ++ if (value >= 0) { ++ cdev->req->zero = 0; ++ cdev->req->length = value; ++ value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); ++ if (value < 0) ++ ERROR(cdev, "%s setup response queue error\n", ++ __func__); ++ } ++ ++err: ++ if (value == -EOPNOTSUPP) ++ VDBG(cdev, ++ "unknown class-specific control req " ++ "%02x.%02x v%04x i%04x l%u\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ w_value, w_index, w_length); ++ return value; ++} ++EXPORT_SYMBOL_GPL(acc_ctrlrequest); ++ ++static int ++__acc_function_bind(struct usb_configuration *c, ++ struct usb_function *f, bool configfs) ++{ ++ struct usb_composite_dev *cdev = c->cdev; ++ struct acc_dev *dev = func_to_dev(f); ++ int id; ++ int ret; ++ ++ DBG(cdev, "acc_function_bind dev: %p\n", dev); ++ ++ if (configfs) { ++ if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { ++ ret = usb_string_id(c->cdev); ++ if (ret < 0) ++ return ret; ++ acc_string_defs[INTERFACE_STRING_INDEX].id = ret; ++ acc_interface_desc.iInterface = ret; ++ } ++ dev->cdev = c->cdev; ++ } ++ ret = hid_register_driver(&acc_hid_driver); ++ if (ret) ++ return ret; ++ ++ dev->start_requested = 0; ++ ++ /* allocate interface ID(s) */ ++ id = usb_interface_id(c, f); ++ if (id < 0) ++ return id; ++ acc_interface_desc.bInterfaceNumber = id; ++ ++ /* allocate endpoints */ ++ ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, ++ &acc_fullspeed_out_desc); ++ if (ret) ++ return ret; ++ ++ /* support high speed hardware */ ++ if (gadget_is_dualspeed(c->cdev->gadget)) { ++ acc_highspeed_in_desc.bEndpointAddress = ++ acc_fullspeed_in_desc.bEndpointAddress; ++ acc_highspeed_out_desc.bEndpointAddress = ++ acc_fullspeed_out_desc.bEndpointAddress; ++ } ++ ++ DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", ++ gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", ++ f->name, dev->ep_in->name, dev->ep_out->name); ++ return 0; ++} ++ ++static int ++acc_function_bind_configfs(struct usb_configuration *c, ++ struct usb_function *f) { ++ return __acc_function_bind(c, f, true); ++} ++ ++static void ++kill_all_hid_devices(struct acc_dev *dev) ++{ ++ struct acc_hid_dev *hid; ++ struct list_head *entry, *temp; ++ unsigned long flags; ++ ++ /* do nothing if usb accessory device doesn't exist */ ++ if (!dev) ++ return; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ list_for_each_safe(entry, temp, &dev->hid_list) { ++ hid = list_entry(entry, struct acc_hid_dev, list); ++ list_del(&hid->list); ++ list_add(&hid->list, &dev->dead_hid_list); ++ } ++ list_for_each_safe(entry, temp, &dev->new_hid_list) { ++ hid = list_entry(entry, struct acc_hid_dev, list); ++ list_del(&hid->list); ++ list_add(&hid->list, &dev->dead_hid_list); ++ } ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ schedule_work(&dev->hid_work); ++} ++ ++static void ++acc_hid_unbind(struct acc_dev *dev) ++{ ++ hid_unregister_driver(&acc_hid_driver); ++ kill_all_hid_devices(dev); ++} ++ ++static void ++acc_function_unbind(struct usb_configuration *c, struct usb_function *f) ++{ ++ struct acc_dev *dev = func_to_dev(f); ++ struct usb_request *req; ++ int i; ++ ++ dev->online = 0; /* clear online flag */ ++ wake_up(&dev->read_wq); /* unblock reads on closure */ ++ wake_up(&dev->write_wq); /* likewise for writes */ ++ ++ while ((req = req_get(dev, &dev->tx_idle))) ++ acc_request_free(req, dev->ep_in); ++ for (i = 0; i < RX_REQ_MAX; i++) ++ acc_request_free(dev->rx_req[i], dev->ep_out); ++ ++ acc_hid_unbind(dev); ++} ++ ++static void acc_start_work(struct work_struct *data) ++{ ++ char *envp[2] = { "ACCESSORY=START", NULL }; ++ ++ kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); ++} ++ ++static int acc_hid_init(struct acc_hid_dev *hdev) ++{ ++ struct hid_device *hid; ++ int ret; ++ ++ hid = hid_allocate_device(); ++ if (IS_ERR(hid)) ++ return PTR_ERR(hid); ++ ++ hid->ll_driver = &acc_hid_ll_driver; ++ hid->dev.parent = acc_device.this_device; ++ ++ hid->bus = BUS_USB; ++ hid->vendor = HID_ANY_ID; ++ hid->product = HID_ANY_ID; ++ hid->driver_data = hdev; ++ ret = hid_add_device(hid); ++ if (ret) { ++ pr_err("can't add hid device: %d\n", ret); ++ hid_destroy_device(hid); ++ return ret; ++ } ++ ++ hdev->hid = hid; ++ return 0; ++} ++ ++static void acc_hid_delete(struct acc_hid_dev *hid) ++{ ++ kfree(hid->report_desc); ++ kfree(hid); ++} ++ ++static void acc_hid_work(struct work_struct *data) ++{ ++ struct acc_dev *dev = _acc_dev; ++ struct list_head *entry, *temp; ++ struct acc_hid_dev *hid; ++ struct list_head new_list, dead_list; ++ unsigned long flags; ++ ++ INIT_LIST_HEAD(&new_list); ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ ++ /* copy hids that are ready for initialization to new_list */ ++ list_for_each_safe(entry, temp, &dev->new_hid_list) { ++ hid = list_entry(entry, struct acc_hid_dev, list); ++ if (hid->report_desc_offset == hid->report_desc_len) ++ list_move(&hid->list, &new_list); ++ } ++ ++ if (list_empty(&dev->dead_hid_list)) { ++ INIT_LIST_HEAD(&dead_list); ++ } else { ++ /* move all of dev->dead_hid_list to dead_list */ ++ dead_list.prev = dev->dead_hid_list.prev; ++ dead_list.next = dev->dead_hid_list.next; ++ dead_list.next->prev = &dead_list; ++ dead_list.prev->next = &dead_list; ++ INIT_LIST_HEAD(&dev->dead_hid_list); ++ } ++ ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ /* register new HID devices */ ++ list_for_each_safe(entry, temp, &new_list) { ++ hid = list_entry(entry, struct acc_hid_dev, list); ++ if (acc_hid_init(hid)) { ++ pr_err("can't add HID device %p\n", hid); ++ acc_hid_delete(hid); ++ } else { ++ spin_lock_irqsave(&dev->lock, flags); ++ list_move(&hid->list, &dev->hid_list); ++ spin_unlock_irqrestore(&dev->lock, flags); ++ } ++ } ++ ++ /* remove dead HID devices */ ++ list_for_each_safe(entry, temp, &dead_list) { ++ hid = list_entry(entry, struct acc_hid_dev, list); ++ list_del(&hid->list); ++ if (hid->hid) ++ hid_destroy_device(hid->hid); ++ acc_hid_delete(hid); ++ } ++} ++ ++static int acc_function_set_alt(struct usb_function *f, ++ unsigned intf, unsigned alt) ++{ ++ struct acc_dev *dev = func_to_dev(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ int ret; ++ ++ DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); ++ ++ ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); ++ if (ret) ++ return ret; ++ ++ ret = usb_ep_enable(dev->ep_in); ++ if (ret) ++ return ret; ++ ++ ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); ++ if (ret) ++ return ret; ++ ++ ret = usb_ep_enable(dev->ep_out); ++ if (ret) { ++ usb_ep_disable(dev->ep_in); ++ return ret; ++ } ++ ++ dev->online = 1; ++ dev->disconnected = 0; /* if online then not disconnected */ ++ ++ /* readers may be blocked waiting for us to go online */ ++ wake_up(&dev->read_wq); ++ return 0; ++} ++ ++static void acc_function_disable(struct usb_function *f) ++{ ++ struct acc_dev *dev = func_to_dev(f); ++ struct usb_composite_dev *cdev = dev->cdev; ++ ++ DBG(cdev, "acc_function_disable\n"); ++ acc_set_disconnected(dev); /* this now only sets disconnected */ ++ dev->online = 0; /* so now need to clear online flag here too */ ++ usb_ep_disable(dev->ep_in); ++ usb_ep_disable(dev->ep_out); ++ ++ /* readers may be blocked waiting for us to go online */ ++ wake_up(&dev->read_wq); ++ ++ VDBG(cdev, "%s disabled\n", dev->function.name); ++} ++ ++static int acc_setup(void) ++{ ++ struct acc_dev *dev; ++ int ret; ++ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ if (!dev) ++ return -ENOMEM; ++ ++ spin_lock_init(&dev->lock); ++ init_waitqueue_head(&dev->read_wq); ++ init_waitqueue_head(&dev->write_wq); ++ atomic_set(&dev->open_excl, 0); ++ INIT_LIST_HEAD(&dev->tx_idle); ++ INIT_LIST_HEAD(&dev->hid_list); ++ INIT_LIST_HEAD(&dev->new_hid_list); ++ INIT_LIST_HEAD(&dev->dead_hid_list); ++ INIT_DELAYED_WORK(&dev->start_work, acc_start_work); ++ INIT_WORK(&dev->hid_work, acc_hid_work); ++ ++ /* _acc_dev must be set before calling usb_gadget_register_driver */ ++ _acc_dev = dev; ++ ++ ret = misc_register(&acc_device); ++ if (ret) ++ goto err; ++ ++ return 0; ++ ++err: ++ kfree(dev); ++ pr_err("USB accessory gadget driver failed to initialize\n"); ++ return ret; ++} ++ ++void acc_disconnect(void) ++{ ++ /* unregister all HID devices if USB is disconnected */ ++ kill_all_hid_devices(_acc_dev); ++} ++EXPORT_SYMBOL_GPL(acc_disconnect); ++ ++static void acc_cleanup(void) ++{ ++ misc_deregister(&acc_device); ++ kfree(_acc_dev); ++ _acc_dev = NULL; ++} ++static struct acc_instance *to_acc_instance(struct config_item *item) ++{ ++ return container_of(to_config_group(item), struct acc_instance, ++ func_inst.group); ++} ++ ++static void acc_attr_release(struct config_item *item) ++{ ++ struct acc_instance *fi_acc = to_acc_instance(item); ++ ++ usb_put_function_instance(&fi_acc->func_inst); ++} ++ ++static struct configfs_item_operations acc_item_ops = { ++ .release = acc_attr_release, ++}; ++ ++static struct config_item_type acc_func_type = { ++ .ct_item_ops = &acc_item_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct acc_instance *to_fi_acc(struct usb_function_instance *fi) ++{ ++ return container_of(fi, struct acc_instance, func_inst); ++} ++ ++static int acc_set_inst_name(struct usb_function_instance *fi, const char *name) ++{ ++ struct acc_instance *fi_acc; ++ char *ptr; ++ int name_len; ++ ++ name_len = strlen(name) + 1; ++ if (name_len > MAX_INST_NAME_LEN) ++ return -ENAMETOOLONG; ++ ++ ptr = kstrndup(name, name_len, GFP_KERNEL); ++ if (!ptr) ++ return -ENOMEM; ++ ++ fi_acc = to_fi_acc(fi); ++ fi_acc->name = ptr; ++ return 0; ++} ++ ++static void acc_free_inst(struct usb_function_instance *fi) ++{ ++ struct acc_instance *fi_acc; ++ ++ fi_acc = to_fi_acc(fi); ++ kfree(fi_acc->name); ++ acc_cleanup(); ++} ++ ++static struct usb_function_instance *acc_alloc_inst(void) ++{ ++ struct acc_instance *fi_acc; ++ struct acc_dev *dev; ++ int err; ++ ++ fi_acc = kzalloc(sizeof(*fi_acc), GFP_KERNEL); ++ if (!fi_acc) ++ return ERR_PTR(-ENOMEM); ++ fi_acc->func_inst.set_inst_name = acc_set_inst_name; ++ fi_acc->func_inst.free_func_inst = acc_free_inst; ++ ++ err = acc_setup(); ++ if (err) { ++ kfree(fi_acc); ++ pr_err("Error setting ACCESSORY\n"); ++ return ERR_PTR(err); ++ } ++ ++ config_group_init_type_name(&fi_acc->func_inst.group, ++ "", &acc_func_type); ++ dev = _acc_dev; ++ return &fi_acc->func_inst; ++} ++ ++static void acc_free(struct usb_function *f) ++{ ++/*NO-OP: no function specific resource allocation in mtp_alloc*/ ++} ++ ++int acc_ctrlrequest_configfs(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) { ++ if (f->config != NULL && f->config->cdev != NULL) ++ return acc_ctrlrequest(f->config->cdev, ctrl); ++ else ++ return -1; ++} ++ ++static struct usb_function *acc_alloc(struct usb_function_instance *fi) ++{ ++ struct acc_dev *dev = _acc_dev; ++ ++ pr_info("acc_alloc\n"); ++ ++ dev->function.name = "accessory"; ++ dev->function.strings = acc_strings, ++ dev->function.fs_descriptors = fs_acc_descs; ++ dev->function.hs_descriptors = hs_acc_descs; ++ dev->function.bind = acc_function_bind_configfs; ++ dev->function.unbind = acc_function_unbind; ++ dev->function.set_alt = acc_function_set_alt; ++ dev->function.disable = acc_function_disable; ++ dev->function.free_func = acc_free; ++ dev->function.setup = acc_ctrlrequest_configfs; ++ ++ return &dev->function; ++} ++DECLARE_USB_FUNCTION_INIT(accessory, acc_alloc_inst, acc_alloc); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/usb/f_accessory.h b/include/linux/usb/f_accessory.h +new file mode 100644 +index 0000000000000..ebe3c4d593098 +--- /dev/null ++++ b/include/linux/usb/f_accessory.h +@@ -0,0 +1,23 @@ ++/* ++ * Gadget Function Driver for Android USB accessories ++ * ++ * Copyright (C) 2011 Google, Inc. ++ * Author: Mike Lockwood ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef __LINUX_USB_F_ACCESSORY_H ++#define __LINUX_USB_F_ACCESSORY_H ++ ++#include ++ ++#endif /* __LINUX_USB_F_ACCESSORY_H */ +diff --git a/include/uapi/linux/usb/f_accessory.h b/include/uapi/linux/usb/f_accessory.h +new file mode 100644 +index 0000000000000..0baeb7d0d74ce +--- /dev/null ++++ b/include/uapi/linux/usb/f_accessory.h +@@ -0,0 +1,146 @@ ++/* ++ * Gadget Function Driver for Android USB accessories ++ * ++ * Copyright (C) 2011 Google, Inc. ++ * Author: Mike Lockwood ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H ++#define _UAPI_LINUX_USB_F_ACCESSORY_H ++ ++/* Use Google Vendor ID when in accessory mode */ ++#define USB_ACCESSORY_VENDOR_ID 0x18D1 ++ ++ ++/* Product ID to use when in accessory mode */ ++#define USB_ACCESSORY_PRODUCT_ID 0x2D00 ++ ++/* Product ID to use when in accessory mode and adb is enabled */ ++#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01 ++ ++/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */ ++#define ACCESSORY_STRING_MANUFACTURER 0 ++#define ACCESSORY_STRING_MODEL 1 ++#define ACCESSORY_STRING_DESCRIPTION 2 ++#define ACCESSORY_STRING_VERSION 3 ++#define ACCESSORY_STRING_URI 4 ++#define ACCESSORY_STRING_SERIAL 5 ++ ++/* Control request for retrieving device's protocol version ++ * ++ * requestType: USB_DIR_IN | USB_TYPE_VENDOR ++ * request: ACCESSORY_GET_PROTOCOL ++ * value: 0 ++ * index: 0 ++ * data version number (16 bits little endian) ++ * 1 for original accessory support ++ * 2 adds HID and device to host audio support ++ */ ++#define ACCESSORY_GET_PROTOCOL 51 ++ ++/* Control request for host to send a string to the device ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_SEND_STRING ++ * value: 0 ++ * index: string ID ++ * data zero terminated UTF8 string ++ * ++ * The device can later retrieve these strings via the ++ * ACCESSORY_GET_STRING_* ioctls ++ */ ++#define ACCESSORY_SEND_STRING 52 ++ ++/* Control request for starting device in accessory mode. ++ * The host sends this after setting all its strings to the device. ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_START ++ * value: 0 ++ * index: 0 ++ * data none ++ */ ++#define ACCESSORY_START 53 ++ ++/* Control request for registering a HID device. ++ * Upon registering, a unique ID is sent by the accessory in the ++ * value parameter. This ID will be used for future commands for ++ * the device ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_REGISTER_HID_DEVICE ++ * value: Accessory assigned ID for the HID device ++ * index: total length of the HID report descriptor ++ * data none ++ */ ++#define ACCESSORY_REGISTER_HID 54 ++ ++/* Control request for unregistering a HID device. ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_REGISTER_HID ++ * value: Accessory assigned ID for the HID device ++ * index: 0 ++ * data none ++ */ ++#define ACCESSORY_UNREGISTER_HID 55 ++ ++/* Control request for sending the HID report descriptor. ++ * If the HID descriptor is longer than the endpoint zero max packet size, ++ * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC ++ * commands. The data for the descriptor must be sent sequentially ++ * if multiple packets are needed. ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_SET_HID_REPORT_DESC ++ * value: Accessory assigned ID for the HID device ++ * index: offset of data in descriptor ++ * (needed when HID descriptor is too big for one packet) ++ * data the HID report descriptor ++ */ ++#define ACCESSORY_SET_HID_REPORT_DESC 56 ++ ++/* Control request for sending HID events. ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_SEND_HID_EVENT ++ * value: Accessory assigned ID for the HID device ++ * index: 0 ++ * data the HID report for the event ++ */ ++#define ACCESSORY_SEND_HID_EVENT 57 ++ ++/* Control request for setting the audio mode. ++ * ++ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR ++ * request: ACCESSORY_SET_AUDIO_MODE ++ * value: 0 - no audio ++ * 1 - device to host, 44100 16-bit stereo PCM ++ * index: 0 ++ * data none ++ */ ++#define ACCESSORY_SET_AUDIO_MODE 58 ++ ++/* ioctls for retrieving strings set by the host */ ++#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256]) ++#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256]) ++#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256]) ++#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256]) ++#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256]) ++#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256]) ++/* returns 1 if there is a start request pending */ ++#define ACCESSORY_IS_START_REQUESTED _IO('M', 7) ++/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */ ++#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8) ++ ++#endif /* _UAPI_LINUX_USB_F_ACCESSORY_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-.patch b/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-.patch new file mode 100644 index 000000000000..dc0e340e8328 --- /dev/null +++ b/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-.patch @@ -0,0 +1,1153 @@ +From 5ec5732f5613c9394a6f4b61fbb3de05a4135d0c Mon Sep 17 00:00:00 2001 +From: Mike Lockwood +Date: Fri, 11 May 2012 09:01:08 -0700 +Subject: ANDROID: usb: gadget: f_audio_source: New gadget + driver for audio output + +This driver presents a standard USB audio class interface to the host +and an ALSA PCM device to userspace + +Bug: 78114713 +Bug: 120441124 +[badhri: f_audio_source is being migrated to userspace.] +Change-Id: If16b14a5ff27045f9cb2daaf1ae9195c5eeab7d0 +Signed-off-by: Mike Lockwood +[AmitP: Folded following android-4.9 commit changes into this patch + Parts of e27543931009 ("ANDROID: usb: gadget: Fixes and hacks to make android usb gadget compile on 3.8") + i6d9285e2574a ("ANDROID: usb: gadget: f_audio_source:replace deprecated API")] +Signed-off-by: Amit Pundir +[astrachan: Folded the following changes into this patch: + ddfd0c4070c1 ("ANDROID: usb: gadget: f_audio_source: Move to USB_FUNCTION API") + a3ab81aaa19e ("ANDROID: usb: gadget: f_audio_source: Move gadget functions code") + 2095c953d894 ("ANDROID: usb: gadget: f_audio_source: change max ISO packet size") + 8671b3e53638 ("ANDROID: usb: gadget: f_audio_source: Fixed USB Audio Class Interface Descriptor") + af98f36edbe2 ("ANDROID: usb: gadget: f_audio_source: disable the CPU C-states upon playback") + a830751a338e ("CHROMIUM: usb: gadget: f_audio_source: add .free_func callback")] +Signed-off-by: Alistair Strachan +--- + drivers/usb/gadget/Kconfig | 12 + + drivers/usb/gadget/function/Makefile | 2 + + drivers/usb/gadget/function/f_audio_source.c | 1071 ++++++++++++++++++ + 3 files changed, 1085 insertions(+) + create mode 100644 drivers/usb/gadget/function/f_audio_source.c + +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 7749fb1decb01..920ff2d2c5579 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -219,6 +219,9 @@ config USB_F_TCM + config USB_F_ACC + tristate + ++config USB_F_AUDIO_SRC ++ tristate ++ + # this first set of drivers all depend on bulk-capable hardware. + + config USB_CONFIGFS +@@ -387,6 +390,15 @@ config USB_CONFIGFS_F_ACC + help + USB gadget Accessory support + ++config USB_CONFIGFS_F_AUDIO_SRC ++ bool "Audio Source gadget" ++ depends on USB_CONFIGFS ++ depends on SND ++ select SND_PCM ++ select USB_F_AUDIO_SRC ++ help ++ USB gadget Audio Source support ++ + config USB_CONFIGFS_F_UAC1 + bool "Audio Class 1.0" + depends on USB_CONFIGFS +diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile +index 2305360e5f22d..dd33a1243342c 100644 +--- a/drivers/usb/gadget/function/Makefile ++++ b/drivers/usb/gadget/function/Makefile +@@ -52,3 +52,5 @@ usb_f_tcm-y := f_tcm.o + obj-$(CONFIG_USB_F_TCM) += usb_f_tcm.o + usb_f_accessory-y := f_accessory.o + obj-$(CONFIG_USB_F_ACC) += usb_f_accessory.o ++usb_f_audio_source-y := f_audio_source.o ++obj-$(CONFIG_USB_F_AUDIO_SRC) += usb_f_audio_source.o +diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c +new file mode 100644 +index 0000000000000..8124af33b7383 +--- /dev/null ++++ b/drivers/usb/gadget/function/f_audio_source.c +@@ -0,0 +1,1071 @@ ++/* ++ * Gadget Function Driver for USB audio source device ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define SAMPLE_RATE 44100 ++#define FRAMES_PER_MSEC (SAMPLE_RATE / 1000) ++ ++#define IN_EP_MAX_PACKET_SIZE 256 ++ ++/* Number of requests to allocate */ ++#define IN_EP_REQ_COUNT 4 ++ ++#define AUDIO_AC_INTERFACE 0 ++#define AUDIO_AS_INTERFACE 1 ++#define AUDIO_NUM_INTERFACES 2 ++#define MAX_INST_NAME_LEN 40 ++ ++/* B.3.1 Standard AC Interface Descriptor */ ++static struct usb_interface_descriptor ac_interface_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, ++}; ++ ++DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); ++ ++#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(AUDIO_NUM_INTERFACES) ++/* 1 input terminal, 1 output terminal and 1 feature unit */ ++#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ ++ + UAC_DT_INPUT_TERMINAL_SIZE + UAC_DT_OUTPUT_TERMINAL_SIZE \ ++ + UAC_DT_FEATURE_UNIT_SIZE(0)) ++/* B.3.2 Class-Specific AC Interface Descriptor */ ++static struct uac1_ac_header_descriptor_2 ac_header_desc = { ++ .bLength = UAC_DT_AC_HEADER_LENGTH, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_HEADER, ++ .bcdADC = __constant_cpu_to_le16(0x0100), ++ .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), ++ .bInCollection = AUDIO_NUM_INTERFACES, ++ .baInterfaceNr = { ++ [0] = AUDIO_AC_INTERFACE, ++ [1] = AUDIO_AS_INTERFACE, ++ } ++}; ++ ++#define INPUT_TERMINAL_ID 1 ++static struct uac_input_terminal_descriptor input_terminal_desc = { ++ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_INPUT_TERMINAL, ++ .bTerminalID = INPUT_TERMINAL_ID, ++ .wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE, ++ .bAssocTerminal = 0, ++ .wChannelConfig = 0x3, ++}; ++ ++DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); ++ ++#define FEATURE_UNIT_ID 2 ++static struct uac_feature_unit_descriptor_0 feature_unit_desc = { ++ .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_FEATURE_UNIT, ++ .bUnitID = FEATURE_UNIT_ID, ++ .bSourceID = INPUT_TERMINAL_ID, ++ .bControlSize = 2, ++}; ++ ++#define OUTPUT_TERMINAL_ID 3 ++static struct uac1_output_terminal_descriptor output_terminal_desc = { ++ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, ++ .bTerminalID = OUTPUT_TERMINAL_ID, ++ .wTerminalType = UAC_TERMINAL_STREAMING, ++ .bAssocTerminal = FEATURE_UNIT_ID, ++ .bSourceID = FEATURE_UNIT_ID, ++}; ++ ++/* B.4.1 Standard AS Interface Descriptor */ ++static struct usb_interface_descriptor as_interface_alt_0_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 0, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++static struct usb_interface_descriptor as_interface_alt_1_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 1, ++ .bNumEndpoints = 1, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++/* B.4.2 Class-Specific AS Interface Descriptor */ ++static struct uac1_as_header_descriptor as_header_desc = { ++ .bLength = UAC_DT_AS_HEADER_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_AS_GENERAL, ++ .bTerminalLink = INPUT_TERMINAL_ID, ++ .bDelay = 1, ++ .wFormatTag = UAC_FORMAT_TYPE_I_PCM, ++}; ++ ++DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); ++ ++static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { ++ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_FORMAT_TYPE, ++ .bFormatType = UAC_FORMAT_TYPE_I, ++ .bSubframeSize = 2, ++ .bBitResolution = 16, ++ .bSamFreqType = 1, ++}; ++ ++/* Standard ISO IN Endpoint Descriptor for highspeed */ ++static struct usb_endpoint_descriptor hs_as_in_ep_desc = { ++ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_IN, ++ .bmAttributes = USB_ENDPOINT_SYNC_SYNC ++ | USB_ENDPOINT_XFER_ISOC, ++ .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), ++ .bInterval = 4, /* poll 1 per millisecond */ ++}; ++ ++/* Standard ISO IN Endpoint Descriptor for highspeed */ ++static struct usb_endpoint_descriptor fs_as_in_ep_desc = { ++ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_IN, ++ .bmAttributes = USB_ENDPOINT_SYNC_SYNC ++ | USB_ENDPOINT_XFER_ISOC, ++ .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), ++ .bInterval = 1, /* poll 1 per millisecond */ ++}; ++ ++/* Class-specific AS ISO OUT Endpoint Descriptor */ ++static struct uac_iso_endpoint_descriptor as_iso_in_desc = { ++ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, ++ .bDescriptorType = USB_DT_CS_ENDPOINT, ++ .bDescriptorSubtype = UAC_EP_GENERAL, ++ .bmAttributes = 1, ++ .bLockDelayUnits = 1, ++ .wLockDelay = __constant_cpu_to_le16(1), ++}; ++ ++static struct usb_descriptor_header *hs_audio_desc[] = { ++ (struct usb_descriptor_header *)&ac_interface_desc, ++ (struct usb_descriptor_header *)&ac_header_desc, ++ ++ (struct usb_descriptor_header *)&input_terminal_desc, ++ (struct usb_descriptor_header *)&output_terminal_desc, ++ (struct usb_descriptor_header *)&feature_unit_desc, ++ ++ (struct usb_descriptor_header *)&as_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_header_desc, ++ ++ (struct usb_descriptor_header *)&as_type_i_desc, ++ ++ (struct usb_descriptor_header *)&hs_as_in_ep_desc, ++ (struct usb_descriptor_header *)&as_iso_in_desc, ++ NULL, ++}; ++ ++static struct usb_descriptor_header *fs_audio_desc[] = { ++ (struct usb_descriptor_header *)&ac_interface_desc, ++ (struct usb_descriptor_header *)&ac_header_desc, ++ ++ (struct usb_descriptor_header *)&input_terminal_desc, ++ (struct usb_descriptor_header *)&output_terminal_desc, ++ (struct usb_descriptor_header *)&feature_unit_desc, ++ ++ (struct usb_descriptor_header *)&as_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_header_desc, ++ ++ (struct usb_descriptor_header *)&as_type_i_desc, ++ ++ (struct usb_descriptor_header *)&fs_as_in_ep_desc, ++ (struct usb_descriptor_header *)&as_iso_in_desc, ++ NULL, ++}; ++ ++static struct snd_pcm_hardware audio_hw_info = { ++ .info = SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_BATCH | ++ SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER, ++ ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .channels_min = 2, ++ .channels_max = 2, ++ .rate_min = SAMPLE_RATE, ++ .rate_max = SAMPLE_RATE, ++ ++ .buffer_bytes_max = 1024 * 1024, ++ .period_bytes_min = 64, ++ .period_bytes_max = 512 * 1024, ++ .periods_min = 2, ++ .periods_max = 1024, ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++struct audio_source_config { ++ int card; ++ int device; ++}; ++ ++struct audio_dev { ++ struct usb_function func; ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ struct snd_pcm_substream *substream; ++ ++ struct list_head idle_reqs; ++ struct usb_ep *in_ep; ++ ++ spinlock_t lock; ++ ++ /* beginning, end and current position in our buffer */ ++ void *buffer_start; ++ void *buffer_end; ++ void *buffer_pos; ++ ++ /* byte size of a "period" */ ++ unsigned int period; ++ /* bytes sent since last call to snd_pcm_period_elapsed */ ++ unsigned int period_offset; ++ /* time we started playing */ ++ ktime_t start_time; ++ /* number of frames sent since start_time */ ++ s64 frames_sent; ++ struct audio_source_config *config; ++ /* for creating and issuing QoS requests */ ++ struct pm_qos_request pm_qos; ++}; ++ ++static inline struct audio_dev *func_to_audio(struct usb_function *f) ++{ ++ return container_of(f, struct audio_dev, func); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++struct audio_source_instance { ++ struct usb_function_instance func_inst; ++ const char *name; ++ struct audio_source_config *config; ++ struct device *audio_device; ++}; ++ ++static void audio_source_attr_release(struct config_item *item); ++ ++static struct configfs_item_operations audio_source_item_ops = { ++ .release = audio_source_attr_release, ++}; ++ ++static struct config_item_type audio_source_func_type = { ++ .ct_item_ops = &audio_source_item_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static ssize_t audio_source_pcm_show(struct device *dev, ++ struct device_attribute *attr, char *buf); ++ ++static DEVICE_ATTR(pcm, S_IRUGO, audio_source_pcm_show, NULL); ++ ++static struct device_attribute *audio_source_function_attributes[] = { ++ &dev_attr_pcm, ++ NULL ++}; ++ ++/*--------------------------------------------------------------------------*/ ++ ++static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size) ++{ ++ struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); ++ ++ if (!req) ++ return NULL; ++ ++ req->buf = kmalloc(buffer_size, GFP_KERNEL); ++ if (!req->buf) { ++ usb_ep_free_request(ep, req); ++ return NULL; ++ } ++ req->length = buffer_size; ++ return req; ++} ++ ++static void audio_request_free(struct usb_request *req, struct usb_ep *ep) ++{ ++ if (req) { ++ kfree(req->buf); ++ usb_ep_free_request(ep, req); ++ } ++} ++ ++static void audio_req_put(struct audio_dev *audio, struct usb_request *req) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&audio->lock, flags); ++ list_add_tail(&req->list, &audio->idle_reqs); ++ spin_unlock_irqrestore(&audio->lock, flags); ++} ++ ++static struct usb_request *audio_req_get(struct audio_dev *audio) ++{ ++ unsigned long flags; ++ struct usb_request *req; ++ ++ spin_lock_irqsave(&audio->lock, flags); ++ if (list_empty(&audio->idle_reqs)) { ++ req = 0; ++ } else { ++ req = list_first_entry(&audio->idle_reqs, struct usb_request, ++ list); ++ list_del(&req->list); ++ } ++ spin_unlock_irqrestore(&audio->lock, flags); ++ return req; ++} ++ ++/* send the appropriate number of packets to match our bitrate */ ++static void audio_send(struct audio_dev *audio) ++{ ++ struct snd_pcm_runtime *runtime; ++ struct usb_request *req; ++ int length, length1, length2, ret; ++ s64 msecs; ++ s64 frames; ++ ktime_t now; ++ ++ /* audio->substream will be null if we have been closed */ ++ if (!audio->substream) ++ return; ++ /* audio->buffer_pos will be null if we have been stopped */ ++ if (!audio->buffer_pos) ++ return; ++ ++ runtime = audio->substream->runtime; ++ ++ /* compute number of frames to send */ ++ now = ktime_get(); ++ msecs = div_s64((ktime_to_ns(now) - ktime_to_ns(audio->start_time)), ++ 1000000); ++ frames = div_s64((msecs * SAMPLE_RATE), 1000); ++ ++ /* Readjust our frames_sent if we fall too far behind. ++ * If we get too far behind it is better to drop some frames than ++ * to keep sending data too fast in an attempt to catch up. ++ */ ++ if (frames - audio->frames_sent > 10 * FRAMES_PER_MSEC) ++ audio->frames_sent = frames - FRAMES_PER_MSEC; ++ ++ frames -= audio->frames_sent; ++ ++ /* We need to send something to keep the pipeline going */ ++ if (frames <= 0) ++ frames = FRAMES_PER_MSEC; ++ ++ while (frames > 0) { ++ req = audio_req_get(audio); ++ if (!req) ++ break; ++ ++ length = frames_to_bytes(runtime, frames); ++ if (length > IN_EP_MAX_PACKET_SIZE) ++ length = IN_EP_MAX_PACKET_SIZE; ++ ++ if (audio->buffer_pos + length > audio->buffer_end) ++ length1 = audio->buffer_end - audio->buffer_pos; ++ else ++ length1 = length; ++ memcpy(req->buf, audio->buffer_pos, length1); ++ if (length1 < length) { ++ /* Wrap around and copy remaining length ++ * at beginning of buffer. ++ */ ++ length2 = length - length1; ++ memcpy(req->buf + length1, audio->buffer_start, ++ length2); ++ audio->buffer_pos = audio->buffer_start + length2; ++ } else { ++ audio->buffer_pos += length1; ++ if (audio->buffer_pos >= audio->buffer_end) ++ audio->buffer_pos = audio->buffer_start; ++ } ++ ++ req->length = length; ++ ret = usb_ep_queue(audio->in_ep, req, GFP_ATOMIC); ++ if (ret < 0) { ++ pr_err("usb_ep_queue failed ret: %d\n", ret); ++ audio_req_put(audio, req); ++ break; ++ } ++ ++ frames -= bytes_to_frames(runtime, length); ++ audio->frames_sent += bytes_to_frames(runtime, length); ++ } ++} ++ ++static void audio_control_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ /* nothing to do here */ ++} ++ ++static void audio_data_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct audio_dev *audio = req->context; ++ ++ pr_debug("audio_data_complete req->status %d req->actual %d\n", ++ req->status, req->actual); ++ ++ audio_req_put(audio, req); ++ ++ if (!audio->buffer_start || req->status) ++ return; ++ ++ audio->period_offset += req->actual; ++ if (audio->period_offset >= audio->period) { ++ snd_pcm_period_elapsed(audio->substream); ++ audio->period_offset = 0; ++ } ++ audio_send(audio); ++} ++ ++static int audio_set_endpoint_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ int value = -EOPNOTSUPP; ++ u16 ep = le16_to_cpu(ctrl->wIndex); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ ++ pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ++ ctrl->bRequest, w_value, len, ep); ++ ++ switch (ctrl->bRequest) { ++ case UAC_SET_CUR: ++ case UAC_SET_MIN: ++ case UAC_SET_MAX: ++ case UAC_SET_RES: ++ value = len; ++ break; ++ default: ++ break; ++ } ++ ++ return value; ++} ++ ++static int audio_get_endpoint_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_composite_dev *cdev = f->config->cdev; ++ int value = -EOPNOTSUPP; ++ u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u8 *buf = cdev->req->buf; ++ ++ pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ++ ctrl->bRequest, w_value, len, ep); ++ ++ if (w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) { ++ switch (ctrl->bRequest) { ++ case UAC_GET_CUR: ++ case UAC_GET_MIN: ++ case UAC_GET_MAX: ++ case UAC_GET_RES: ++ /* return our sample rate */ ++ buf[0] = (u8)SAMPLE_RATE; ++ buf[1] = (u8)(SAMPLE_RATE >> 8); ++ buf[2] = (u8)(SAMPLE_RATE >> 16); ++ value = 3; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return value; ++} ++ ++static int ++audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_request *req = cdev->req; ++ int value = -EOPNOTSUPP; ++ u16 w_index = le16_to_cpu(ctrl->wIndex); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u16 w_length = le16_to_cpu(ctrl->wLength); ++ ++ /* composite driver infrastructure handles everything; interface ++ * activation uses set_alt(). ++ */ ++ switch (ctrl->bRequestType) { ++ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: ++ value = audio_set_endpoint_req(f, ctrl); ++ break; ++ ++ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: ++ value = audio_get_endpoint_req(f, ctrl); ++ break; ++ } ++ ++ /* respond with data transfer or status phase? */ ++ if (value >= 0) { ++ pr_debug("audio req%02x.%02x v%04x i%04x l%d\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ w_value, w_index, w_length); ++ req->zero = 0; ++ req->length = value; ++ req->complete = audio_control_complete; ++ value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); ++ if (value < 0) ++ pr_err("audio response on err %d\n", value); ++ } ++ ++ /* device either stalls (value < 0) or reports success */ ++ return value; ++} ++ ++static int audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ++{ ++ struct audio_dev *audio = func_to_audio(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ int ret; ++ ++ pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt); ++ ++ ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep); ++ if (ret) ++ return ret; ++ ++ usb_ep_enable(audio->in_ep); ++ return 0; ++} ++ ++static void audio_disable(struct usb_function *f) ++{ ++ struct audio_dev *audio = func_to_audio(f); ++ ++ pr_debug("audio_disable\n"); ++ usb_ep_disable(audio->in_ep); ++} ++ ++static void audio_free_func(struct usb_function *f) ++{ ++ /* no-op */ ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void audio_build_desc(struct audio_dev *audio) ++{ ++ u8 *sam_freq; ++ int rate; ++ ++ /* Set channel numbers */ ++ input_terminal_desc.bNrChannels = 2; ++ as_type_i_desc.bNrChannels = 2; ++ ++ /* Set sample rates */ ++ rate = SAMPLE_RATE; ++ sam_freq = as_type_i_desc.tSamFreq[0]; ++ memcpy(sam_freq, &rate, 3); ++} ++ ++ ++static int snd_card_setup(struct usb_configuration *c, ++ struct audio_source_config *config); ++static struct audio_source_instance *to_fi_audio_source( ++ const struct usb_function_instance *fi); ++ ++ ++/* audio function driver setup/binding */ ++static int ++audio_bind(struct usb_configuration *c, struct usb_function *f) ++{ ++ struct usb_composite_dev *cdev = c->cdev; ++ struct audio_dev *audio = func_to_audio(f); ++ int status; ++ struct usb_ep *ep; ++ struct usb_request *req; ++ int i; ++ int err; ++ ++ if (IS_ENABLED(CONFIG_USB_CONFIGFS)) { ++ struct audio_source_instance *fi_audio = ++ to_fi_audio_source(f->fi); ++ struct audio_source_config *config = ++ fi_audio->config; ++ ++ err = snd_card_setup(c, config); ++ if (err) ++ return err; ++ } ++ ++ audio_build_desc(audio); ++ ++ /* allocate instance-specific interface IDs, and patch descriptors */ ++ status = usb_interface_id(c, f); ++ if (status < 0) ++ goto fail; ++ ac_interface_desc.bInterfaceNumber = status; ++ ++ /* AUDIO_AC_INTERFACE */ ++ ac_header_desc.baInterfaceNr[0] = status; ++ ++ status = usb_interface_id(c, f); ++ if (status < 0) ++ goto fail; ++ as_interface_alt_0_desc.bInterfaceNumber = status; ++ as_interface_alt_1_desc.bInterfaceNumber = status; ++ ++ /* AUDIO_AS_INTERFACE */ ++ ac_header_desc.baInterfaceNr[1] = status; ++ ++ status = -ENODEV; ++ ++ /* allocate our endpoint */ ++ ep = usb_ep_autoconfig(cdev->gadget, &fs_as_in_ep_desc); ++ if (!ep) ++ goto fail; ++ audio->in_ep = ep; ++ ep->driver_data = audio; /* claim */ ++ ++ if (gadget_is_dualspeed(c->cdev->gadget)) ++ hs_as_in_ep_desc.bEndpointAddress = ++ fs_as_in_ep_desc.bEndpointAddress; ++ ++ f->fs_descriptors = fs_audio_desc; ++ f->hs_descriptors = hs_audio_desc; ++ ++ for (i = 0, status = 0; i < IN_EP_REQ_COUNT && status == 0; i++) { ++ req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE); ++ if (req) { ++ req->context = audio; ++ req->complete = audio_data_complete; ++ audio_req_put(audio, req); ++ } else ++ status = -ENOMEM; ++ } ++ ++fail: ++ return status; ++} ++ ++static void ++audio_unbind(struct usb_configuration *c, struct usb_function *f) ++{ ++ struct audio_dev *audio = func_to_audio(f); ++ struct usb_request *req; ++ ++ while ((req = audio_req_get(audio))) ++ audio_request_free(req, audio->in_ep); ++ ++ snd_card_free_when_closed(audio->card); ++ audio->card = NULL; ++ audio->pcm = NULL; ++ audio->substream = NULL; ++ audio->in_ep = NULL; ++ ++ if (IS_ENABLED(CONFIG_USB_CONFIGFS)) { ++ struct audio_source_instance *fi_audio = ++ to_fi_audio_source(f->fi); ++ struct audio_source_config *config = ++ fi_audio->config; ++ ++ config->card = -1; ++ config->device = -1; ++ } ++} ++ ++static void audio_pcm_playback_start(struct audio_dev *audio) ++{ ++ audio->start_time = ktime_get(); ++ audio->frames_sent = 0; ++ audio_send(audio); ++} ++ ++static void audio_pcm_playback_stop(struct audio_dev *audio) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&audio->lock, flags); ++ audio->buffer_start = 0; ++ audio->buffer_end = 0; ++ audio->buffer_pos = 0; ++ spin_unlock_irqrestore(&audio->lock, flags); ++} ++ ++static int audio_pcm_open(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct audio_dev *audio = substream->private_data; ++ ++ runtime->private_data = audio; ++ runtime->hw = audio_hw_info; ++ snd_pcm_limit_hw_rates(runtime); ++ runtime->hw.channels_max = 2; ++ ++ audio->substream = substream; ++ ++ /* Add the QoS request and set the latency to 0 */ ++ pm_qos_add_request(&audio->pm_qos, PM_QOS_CPU_DMA_LATENCY, 0); ++ ++ return 0; ++} ++ ++static int audio_pcm_close(struct snd_pcm_substream *substream) ++{ ++ struct audio_dev *audio = substream->private_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&audio->lock, flags); ++ ++ /* Remove the QoS request */ ++ pm_qos_remove_request(&audio->pm_qos); ++ ++ audio->substream = NULL; ++ spin_unlock_irqrestore(&audio->lock, flags); ++ ++ return 0; ++} ++ ++static int audio_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ unsigned int channels = params_channels(params); ++ unsigned int rate = params_rate(params); ++ ++ if (rate != SAMPLE_RATE) ++ return -EINVAL; ++ if (channels != 2) ++ return -EINVAL; ++ ++ return snd_pcm_lib_alloc_vmalloc_buffer(substream, ++ params_buffer_bytes(params)); ++} ++ ++static int audio_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_vmalloc_buffer(substream); ++} ++ ++static int audio_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct audio_dev *audio = runtime->private_data; ++ ++ audio->period = snd_pcm_lib_period_bytes(substream); ++ audio->period_offset = 0; ++ audio->buffer_start = runtime->dma_area; ++ audio->buffer_end = audio->buffer_start ++ + snd_pcm_lib_buffer_bytes(substream); ++ audio->buffer_pos = audio->buffer_start; ++ ++ return 0; ++} ++ ++static snd_pcm_uframes_t audio_pcm_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct audio_dev *audio = runtime->private_data; ++ ssize_t bytes = audio->buffer_pos - audio->buffer_start; ++ ++ /* return offset of next frame to fill in our buffer */ ++ return bytes_to_frames(runtime, bytes); ++} ++ ++static int audio_pcm_playback_trigger(struct snd_pcm_substream *substream, ++ int cmd) ++{ ++ struct audio_dev *audio = substream->runtime->private_data; ++ int ret = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ audio_pcm_playback_start(audio); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ audio_pcm_playback_stop(audio); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static struct audio_dev _audio_dev = { ++ .func = { ++ .name = "audio_source", ++ .bind = audio_bind, ++ .unbind = audio_unbind, ++ .set_alt = audio_set_alt, ++ .setup = audio_setup, ++ .disable = audio_disable, ++ .free_func = audio_free_func, ++ }, ++ .lock = __SPIN_LOCK_UNLOCKED(_audio_dev.lock), ++ .idle_reqs = LIST_HEAD_INIT(_audio_dev.idle_reqs), ++}; ++ ++static struct snd_pcm_ops audio_playback_ops = { ++ .open = audio_pcm_open, ++ .close = audio_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = audio_pcm_hw_params, ++ .hw_free = audio_pcm_hw_free, ++ .prepare = audio_pcm_prepare, ++ .trigger = audio_pcm_playback_trigger, ++ .pointer = audio_pcm_pointer, ++}; ++ ++int audio_source_bind_config(struct usb_configuration *c, ++ struct audio_source_config *config) ++{ ++ struct audio_dev *audio; ++ int err; ++ ++ config->card = -1; ++ config->device = -1; ++ ++ audio = &_audio_dev; ++ ++ err = snd_card_setup(c, config); ++ if (err) ++ return err; ++ ++ err = usb_add_function(c, &audio->func); ++ if (err) ++ goto add_fail; ++ ++ return 0; ++ ++add_fail: ++ snd_card_free(audio->card); ++ return err; ++} ++ ++static int snd_card_setup(struct usb_configuration *c, ++ struct audio_source_config *config) ++{ ++ struct audio_dev *audio; ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ int err; ++ ++ audio = &_audio_dev; ++ ++ err = snd_card_new(&c->cdev->gadget->dev, ++ SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, ++ THIS_MODULE, 0, &card); ++ if (err) ++ return err; ++ ++ err = snd_pcm_new(card, "USB audio source", 0, 1, 0, &pcm); ++ if (err) ++ goto pcm_fail; ++ ++ pcm->private_data = audio; ++ pcm->info_flags = 0; ++ audio->pcm = pcm; ++ ++ strlcpy(pcm->name, "USB gadget audio", sizeof(pcm->name)); ++ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &audio_playback_ops); ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ NULL, 0, 64 * 1024); ++ ++ strlcpy(card->driver, "audio_source", sizeof(card->driver)); ++ strlcpy(card->shortname, card->driver, sizeof(card->shortname)); ++ strlcpy(card->longname, "USB accessory audio source", ++ sizeof(card->longname)); ++ ++ err = snd_card_register(card); ++ if (err) ++ goto register_fail; ++ ++ config->card = pcm->card->number; ++ config->device = pcm->device; ++ audio->card = card; ++ return 0; ++ ++register_fail: ++pcm_fail: ++ snd_card_free(audio->card); ++ return err; ++} ++ ++static struct audio_source_instance *to_audio_source_instance( ++ struct config_item *item) ++{ ++ return container_of(to_config_group(item), struct audio_source_instance, ++ func_inst.group); ++} ++ ++static struct audio_source_instance *to_fi_audio_source( ++ const struct usb_function_instance *fi) ++{ ++ return container_of(fi, struct audio_source_instance, func_inst); ++} ++ ++static void audio_source_attr_release(struct config_item *item) ++{ ++ struct audio_source_instance *fi_audio = to_audio_source_instance(item); ++ ++ usb_put_function_instance(&fi_audio->func_inst); ++} ++ ++static int audio_source_set_inst_name(struct usb_function_instance *fi, ++ const char *name) ++{ ++ struct audio_source_instance *fi_audio; ++ char *ptr; ++ int name_len; ++ ++ name_len = strlen(name) + 1; ++ if (name_len > MAX_INST_NAME_LEN) ++ return -ENAMETOOLONG; ++ ++ ptr = kstrndup(name, name_len, GFP_KERNEL); ++ if (!ptr) ++ return -ENOMEM; ++ ++ fi_audio = to_fi_audio_source(fi); ++ fi_audio->name = ptr; ++ ++ return 0; ++} ++ ++static void audio_source_free_inst(struct usb_function_instance *fi) ++{ ++ struct audio_source_instance *fi_audio; ++ ++ fi_audio = to_fi_audio_source(fi); ++ device_destroy(fi_audio->audio_device->class, ++ fi_audio->audio_device->devt); ++ kfree(fi_audio->name); ++ kfree(fi_audio->config); ++} ++ ++static ssize_t audio_source_pcm_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct audio_source_instance *fi_audio = dev_get_drvdata(dev); ++ struct audio_source_config *config = fi_audio->config; ++ ++ /* print PCM card and device numbers */ ++ return sprintf(buf, "%d %d\n", config->card, config->device); ++} ++ ++struct device *create_function_device(char *name); ++ ++static struct usb_function_instance *audio_source_alloc_inst(void) ++{ ++ struct audio_source_instance *fi_audio; ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ struct device *dev; ++ void *err_ptr; ++ int err = 0; ++ ++ fi_audio = kzalloc(sizeof(*fi_audio), GFP_KERNEL); ++ if (!fi_audio) ++ return ERR_PTR(-ENOMEM); ++ ++ fi_audio->func_inst.set_inst_name = audio_source_set_inst_name; ++ fi_audio->func_inst.free_func_inst = audio_source_free_inst; ++ ++ fi_audio->config = kzalloc(sizeof(struct audio_source_config), ++ GFP_KERNEL); ++ if (!fi_audio->config) { ++ err_ptr = ERR_PTR(-ENOMEM); ++ goto fail_audio; ++ } ++ ++ config_group_init_type_name(&fi_audio->func_inst.group, "", ++ &audio_source_func_type); ++ dev = create_function_device("f_audio_source"); ++ ++ if (IS_ERR(dev)) { ++ err_ptr = dev; ++ goto fail_audio_config; ++ } ++ ++ fi_audio->config->card = -1; ++ fi_audio->config->device = -1; ++ fi_audio->audio_device = dev; ++ ++ attrs = audio_source_function_attributes; ++ if (attrs) { ++ while ((attr = *attrs++) && !err) ++ err = device_create_file(dev, attr); ++ if (err) { ++ err_ptr = ERR_PTR(-EINVAL); ++ goto fail_device; ++ } ++ } ++ ++ dev_set_drvdata(dev, fi_audio); ++ _audio_dev.config = fi_audio->config; ++ ++ return &fi_audio->func_inst; ++ ++fail_device: ++ device_destroy(dev->class, dev->devt); ++fail_audio_config: ++ kfree(fi_audio->config); ++fail_audio: ++ kfree(fi_audio); ++ return err_ptr; ++ ++} ++ ++static struct usb_function *audio_source_alloc(struct usb_function_instance *fi) ++{ ++ return &_audio_dev.func; ++} ++ ++DECLARE_USB_FUNCTION_INIT(audio_source, audio_source_alloc_inst, ++ audio_source_alloc); ++MODULE_LICENSE("GPL"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch b/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch new file mode 100644 index 000000000000..687ef634d0ed --- /dev/null +++ b/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch @@ -0,0 +1,110 @@ +From a3f67c143957149153c09bce680ec9659e99e72c Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Wed, 2 Sep 2015 22:49:10 -0700 +Subject: ANDROID: usb: gadget: f_midi: create F_midi device + +Android frameworks relies on the alsa +config reported by the f_midi device. + +Bug: 111003288 +Bug: 120441124 +Change-Id: I0695e00b166fd953f50acea93802245b0d5a5240 +[badhri: The framework should be moved away from this] +Signed-off-by: Badhri Jagan Sridharan +--- + drivers/usb/gadget/function/f_midi.c | 65 ++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index 46af0aa07e2e3..2a86b3cf313fd 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -1216,6 +1216,65 @@ static void f_midi_free_inst(struct usb_function_instance *f) + } + } + ++#ifdef CONFIG_USB_CONFIGFS_UEVENT ++extern struct device *create_function_device(char *name); ++static ssize_t alsa_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct usb_function_instance *fi_midi = dev_get_drvdata(dev); ++ struct f_midi *midi; ++ ++ if (!fi_midi->f) ++ dev_warn(dev, "f_midi: function not set\n"); ++ ++ if (fi_midi && fi_midi->f) { ++ midi = func_to_midi(fi_midi->f); ++ if (midi->rmidi && midi->rmidi->card) ++ return sprintf(buf, "%d %d\n", ++ midi->rmidi->card->number, midi->rmidi->device); ++ } ++ ++ /* print PCM card and device numbers */ ++ return sprintf(buf, "%d %d\n", -1, -1); ++} ++ ++static DEVICE_ATTR(alsa, S_IRUGO, alsa_show, NULL); ++ ++static struct device_attribute *alsa_function_attributes[] = { ++ &dev_attr_alsa, ++ NULL ++}; ++ ++static int create_alsa_device(struct usb_function_instance *fi) ++{ ++ struct device *dev; ++ struct device_attribute **attrs; ++ struct device_attribute *attr; ++ int err = 0; ++ ++ dev = create_function_device("f_midi"); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ attrs = alsa_function_attributes; ++ if (attrs) { ++ while ((attr = *attrs++) && !err) ++ err = device_create_file(dev, attr); ++ if (err) { ++ device_destroy(dev->class, dev->devt); ++ return -EINVAL; ++ } ++ } ++ dev_set_drvdata(dev, fi); ++ return 0; ++} ++#else ++static int create_alsa_device(struct usb_function_instance *fi) ++{ ++ return 0; ++} ++#endif ++ + static struct usb_function_instance *f_midi_alloc_inst(void) + { + struct f_midi_opts *opts; +@@ -1234,6 +1293,11 @@ static struct usb_function_instance *f_midi_alloc_inst(void) + opts->out_ports = 1; + opts->refcnt = 1; + ++ if (create_alsa_device(&opts->func_inst)) { ++ kfree(opts); ++ return ERR_PTR(-ENODEV); ++ } ++ + config_group_init_type_name(&opts->func_inst.group, "", + &midi_func_type); + +@@ -1341,6 +1405,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) + midi->func.disable = f_midi_disable; + midi->func.free_func = f_midi_free; + ++ fi->f = &midi->func; + return &midi->func; + + setup_fail: +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free.patch b/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free.patch new file mode 100644 index 000000000000..e0c0eee62a44 --- /dev/null +++ b/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free.patch @@ -0,0 +1,56 @@ +From 87e38b1310018005fffe35f847206dd54b8c70d2 Mon Sep 17 00:00:00 2001 +From: Winter Wang +Date: Fri, 20 May 2016 11:05:00 +0800 +Subject: ANDROID: usb: gadget: f_midi: set fi->f to NULL when + free f_midi function + +fi->f is set in f_midi's alloc_func, need to clean this to +NULL in free_func, otherwise on ConfigFS's function switch, +midi->usb_function it self is freed, fi->f will be a wild +pointer and run into below kernel panic: +--------------- +[ 58.950628] Unable to handle kernel paging request at virtual address 63697664 +[ 58.957869] pgd = c0004000 +[ 58.960583] [63697664] *pgd=00000000 +[ 58.964185] Internal error: Oops: 80000005 [#1] PREEMPT SMP ARM +[ 58.970111] Modules linked in: +[ 58.973191] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.15-03504-g34c857c-dirty #89 +[ 58.981024] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +[ 58.987557] task: c110bd70 ti: c1100000 task.ti: c1100000 +[ 58.992962] PC is at 0x63697664 +[ 58.996120] LR is at android_setup+0x78/0x138 +<..snip..> +[ 60.044980] 1fc0: ffffffff ffffffff c1000684 00000000 00000000 c108ecd0 c11f7294 c11039c0 +[ 60.053181] 1fe0: c108eccc c110d148 1000406a 412fc09a 00000000 1000807c 00000000 00000000 +[ 60.061420] [] (android_setup) from [] (udc_irq+0x758/0x1034) +[ 60.068951] [] (udc_irq) from [] (handle_irq_event_percpu+0x50/0x254) +[ 60.077165] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x3c/0x5c) +[ 60.086072] [] (handle_irq_event) from [] (handle_fasteoi_irq+0xe0/0x198) +[ 60.094630] [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x2c/0x3c) +[ 60.103271] [] (generic_handle_irq) from [] (__handle_domain_irq+0x7c/0xec) +[ 60.112000] [] (__handle_domain_irq) from [] (gic_handle_irq+0x24/0x5c) +-------------- + +Bug: 111003288 +Bug: 120441124 +Change-Id: Iaf7cc809379c184048a2d9ab1f59e71ebaa3416e +Signed-off-by: Winter Wang +--- + drivers/usb/gadget/function/f_midi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index 2a86b3cf313fd..4713a1c7f622a 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -1318,6 +1318,7 @@ static void f_midi_free(struct usb_function *f) + kfifo_free(&midi->in_req_fifo); + kfree(midi); + free = true; ++ opts->func_inst.f = NULL; + } + mutex_unlock(&opts->lock); + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per.patch b/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per.patch new file mode 100644 index 000000000000..04d45c23982a --- /dev/null +++ b/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per.patch @@ -0,0 +1,892 @@ +From 7c9e0be2377aeb19c254de8d503e4c39f97f1044 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Wed, 26 Oct 2016 16:27:45 -0700 +Subject: ANDROID: vfs: Add permission2 for filesystems with + per mount permissions + +This allows filesystems to use their mount private data to +influence the permssions they return in permission2. It has +been separated into a new call to avoid disrupting current +permission users. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Bug: 35848445 +Change-Id: I9d416e3b8b6eca84ef3e336bd2af89ddd51df6ca +Signed-off-by: Daniel Rosenberg +[AmitP: Minor refactoring of original patch to align with + changes from the following upstream commit + 4bfd054ae11e ("fs: fold __inode_permission() into inode_permission()"). + Also introduce vfs_mkobj2(), because do_create() + moved from using vfs_create() to vfs_mkobj() + eecec19d9e70 ("mqueue: switch to vfs_mkobj(), quit abusing ->d_fsdata") + do_create() is dropped/cleaned-up upstream so a + minor refactoring there as well. + 066cc813e94a ("do_mq_open(): move all work prior to dentry_open() into a helper")] +Signed-off-by: Amit Pundir +[astrachan: Folded the following changes into this patch: + f46c9d62dd81 ("ANDROID: fs: Export vfs_rmdir2") + 9992eb8b9a1e ("ANDROID: xattr: Pass EOPNOTSUPP to permission2")] +Signed-off-by: Alistair Strachan +Signed-off-by: Yongqin Liu +--- + fs/attr.c | 2 +- + fs/exec.c | 2 +- + fs/namei.c | 187 ++++++++++++++++++++--------- + fs/notify/fanotify/fanotify_user.c | 2 +- + fs/notify/inotify/inotify_user.c | 2 +- + fs/open.c | 13 +- + fs/xattr.c | 2 +- + include/linux/fs.h | 13 ++ + include/linux/namei.h | 1 + + ipc/mqueue.c | 14 +-- + security/inode.c | 2 +- + 11 files changed, 168 insertions(+), 72 deletions(-) + +Index: common/fs/attr.c +=================================================================== +--- common.orig/fs/attr.c ++++ common/fs/attr.c +@@ -250,7 +250,7 @@ int notify_change2(struct vfsmount *mnt, + return -EPERM; + + if (!inode_owner_or_capable(inode)) { +- error = inode_permission(inode, MAY_WRITE); ++ error = inode_permission2(mnt, inode, MAY_WRITE); + if (error) + return error; + } +Index: common/fs/exec.c +=================================================================== +--- common.orig/fs/exec.c ++++ common/fs/exec.c +@@ -1313,7 +1313,7 @@ EXPORT_SYMBOL(flush_old_exec); + void would_dump(struct linux_binprm *bprm, struct file *file) + { + struct inode *inode = file_inode(file); +- if (inode_permission(inode, MAY_READ) < 0) { ++ if (inode_permission2(file->f_path.mnt, inode, MAY_READ) < 0) { + struct user_namespace *old, *user_ns; + bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; + +Index: common/fs/namei.c +=================================================================== +--- common.orig/fs/namei.c ++++ common/fs/namei.c +@@ -377,9 +377,11 @@ EXPORT_SYMBOL(generic_permission); + * flag in inode->i_opflags, that says "this has not special + * permission function, use the fast case". + */ +-static inline int do_inode_permission(struct inode *inode, int mask) ++static inline int do_inode_permission(struct vfsmount *mnt, struct inode *inode, int mask) + { + if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) { ++ if (likely(mnt && inode->i_op->permission2)) ++ return inode->i_op->permission2(mnt, inode, mask); + if (likely(inode->i_op->permission)) + return inode->i_op->permission(inode, mask); + +@@ -412,7 +414,8 @@ static int sb_permission(struct super_bl + } + + /** +- * inode_permission - Check for access rights to a given inode ++ * inode_permission2 - Check for access rights to a given inode ++ * @mnt: + * @inode: Inode to check permission on + * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) + * +@@ -422,7 +425,7 @@ static int sb_permission(struct super_bl + * + * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + */ +-int inode_permission(struct inode *inode, int mask) ++int inode_permission2(struct vfsmount *mnt, struct inode *inode, int mask) + { + int retval; + +@@ -446,7 +449,7 @@ int inode_permission(struct inode *inode + return -EACCES; + } + +- retval = do_inode_permission(inode, mask); ++ retval = do_inode_permission(mnt, inode, mask); + if (retval) + return retval; + +@@ -454,7 +457,14 @@ int inode_permission(struct inode *inode + if (retval) + return retval; + +- return security_inode_permission(inode, mask); ++ retval = security_inode_permission(inode, mask); ++ return retval; ++} ++EXPORT_SYMBOL(inode_permission2); ++ ++int inode_permission(struct inode *inode, int mask) ++{ ++ return inode_permission2(NULL, inode, mask); + } + EXPORT_SYMBOL(inode_permission); + +@@ -1685,13 +1695,13 @@ static struct dentry *lookup_slow(const + static inline int may_lookup(struct nameidata *nd) + { + if (nd->flags & LOOKUP_RCU) { +- int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK); ++ int err = inode_permission2(nd->path.mnt, nd->inode, MAY_EXEC|MAY_NOT_BLOCK); + if (err != -ECHILD) + return err; + if (unlazy_walk(nd)) + return -ECHILD; + } +- return inode_permission(nd->inode, MAY_EXEC); ++ return inode_permission2(nd->path.mnt, nd->inode, MAY_EXEC); + } + + static inline int handle_dots(struct nameidata *nd, int type) +@@ -2445,8 +2455,8 @@ int vfs_path_lookup(struct dentry *dentr + } + EXPORT_SYMBOL(vfs_path_lookup); + +-static int lookup_one_len_common(const char *name, struct dentry *base, +- int len, struct qstr *this) ++static int lookup_one_len_common(const char *name, struct vfsmount *mnt, ++ struct dentry *base, int len, struct qstr *this) + { + this->name = name; + this->len = len; +@@ -2474,7 +2484,7 @@ static int lookup_one_len_common(const c + return err; + } + +- return inode_permission(base->d_inode, MAY_EXEC); ++ return inode_permission2(mnt, base->d_inode, MAY_EXEC); + } + + /** +@@ -2498,7 +2508,7 @@ struct dentry *try_lookup_one_len(const + + WARN_ON_ONCE(!inode_is_locked(base->d_inode)); + +- err = lookup_one_len_common(name, base, len, &this); ++ err = lookup_one_len_common(name, NULL, base, len, &this); + if (err) + return ERR_PTR(err); + +@@ -2517,7 +2527,7 @@ EXPORT_SYMBOL(try_lookup_one_len); + * + * The caller must hold base->i_mutex. + */ +-struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) ++struct dentry *lookup_one_len2(const char *name, struct vfsmount *mnt, struct dentry *base, int len) + { + struct dentry *dentry; + struct qstr this; +@@ -2525,13 +2535,19 @@ struct dentry *lookup_one_len(const char + + WARN_ON_ONCE(!inode_is_locked(base->d_inode)); + +- err = lookup_one_len_common(name, base, len, &this); ++ err = lookup_one_len_common(name, mnt, base, len, &this); + if (err) + return ERR_PTR(err); + + dentry = lookup_dcache(&this, base, 0); + return dentry ? dentry : __lookup_slow(&this, base, 0); + } ++EXPORT_SYMBOL(lookup_one_len2); ++ ++struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) ++{ ++ return lookup_one_len2(name, NULL, base, len); ++} + EXPORT_SYMBOL(lookup_one_len); + + /** +@@ -2553,7 +2569,7 @@ struct dentry *lookup_one_len_unlocked(c + int err; + struct dentry *ret; + +- err = lookup_one_len_common(name, base, len, &this); ++ err = lookup_one_len_common(name, NULL, base, len, &this); + if (err) + return ERR_PTR(err); + +@@ -2777,7 +2793,7 @@ EXPORT_SYMBOL(__check_sticky); + * 11. We don't allow removal of NFS sillyrenamed files; it's handled by + * nfs_async_unlink(). + */ +-static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) ++static int may_delete(struct vfsmount *mnt, struct inode *dir, struct dentry *victim, bool isdir) + { + struct inode *inode = d_backing_inode(victim); + int error; +@@ -2794,7 +2810,7 @@ static int may_delete(struct inode *dir, + + audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); + +- error = inode_permission(dir, MAY_WRITE | MAY_EXEC); ++ error = inode_permission2(mnt, dir, MAY_WRITE | MAY_EXEC); + if (error) + return error; + if (IS_APPEND(dir)) +@@ -2826,7 +2842,7 @@ static int may_delete(struct inode *dir, + * 4. We should have write and exec permissions on dir + * 5. We can't do it if dir is immutable (done in permission()) + */ +-static inline int may_create(struct inode *dir, struct dentry *child) ++static inline int may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) + { + struct user_namespace *s_user_ns; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); +@@ -2838,7 +2854,7 @@ static inline int may_create(struct inod + if (!kuid_has_mapping(s_user_ns, current_fsuid()) || + !kgid_has_mapping(s_user_ns, current_fsgid())) + return -EOVERFLOW; +- return inode_permission(dir, MAY_WRITE | MAY_EXEC); ++ return inode_permission2(mnt, dir, MAY_WRITE | MAY_EXEC); + } + + /* +@@ -2885,10 +2901,10 @@ void unlock_rename(struct dentry *p1, st + } + EXPORT_SYMBOL(unlock_rename); + +-int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, +- bool want_excl) ++int vfs_create2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, ++ umode_t mode, bool want_excl) + { +- int error = may_create(dir, dentry); ++ int error = may_create(mnt, dir, dentry); + if (error) + return error; + +@@ -2904,14 +2920,21 @@ int vfs_create(struct inode *dir, struct + fsnotify_create(dir, dentry); + return error; + } ++EXPORT_SYMBOL(vfs_create2); ++ ++int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool want_excl) ++{ ++ return vfs_create2(NULL, dir, dentry, mode, want_excl); ++} + EXPORT_SYMBOL(vfs_create); + +-int vfs_mkobj(struct dentry *dentry, umode_t mode, ++int vfs_mkobj2(struct vfsmount *mnt, struct dentry *dentry, umode_t mode, + int (*f)(struct dentry *, umode_t, void *), + void *arg) + { + struct inode *dir = dentry->d_parent->d_inode; +- int error = may_create(dir, dentry); ++ int error = may_create(mnt, dir, dentry); + if (error) + return error; + +@@ -2925,6 +2948,15 @@ int vfs_mkobj(struct dentry *dentry, umo + fsnotify_create(dir, dentry); + return error; + } ++EXPORT_SYMBOL(vfs_mkobj2); ++ ++ ++int vfs_mkobj(struct dentry *dentry, umode_t mode, ++ int (*f)(struct dentry *, umode_t, void *), ++ void *arg) ++{ ++ return vfs_mkobj2(NULL, dentry, mode, f, arg); ++} + EXPORT_SYMBOL(vfs_mkobj); + + bool may_open_dev(const struct path *path) +@@ -2936,6 +2968,7 @@ bool may_open_dev(const struct path *pat + static int may_open(const struct path *path, int acc_mode, int flag) + { + struct dentry *dentry = path->dentry; ++ struct vfsmount *mnt = path->mnt; + struct inode *inode = dentry->d_inode; + int error; + +@@ -2960,7 +2993,7 @@ static int may_open(const struct path *p + break; + } + +- error = inode_permission(inode, MAY_OPEN | acc_mode); ++ error = inode_permission2(mnt, inode, MAY_OPEN | acc_mode); + if (error) + return error; + +@@ -3022,7 +3055,7 @@ static int may_o_create(const struct pat + !kgid_has_mapping(s_user_ns, current_fsgid())) + return -EOVERFLOW; + +- error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC); ++ error = inode_permission2(dir->mnt, dir->dentry->d_inode, MAY_WRITE | MAY_EXEC); + if (error) + return error; + +@@ -3430,7 +3463,8 @@ struct dentry *vfs_tmpfile(struct dentry + int error; + + /* we want directory to be writable */ +- error = inode_permission(dir, MAY_WRITE | MAY_EXEC); ++ error = inode_permission2(ERR_PTR(-EOPNOTSUPP), dir, ++ MAY_WRITE | MAY_EXEC); + if (error) + goto out_err; + error = -EOPNOTSUPP; +@@ -3685,9 +3719,9 @@ inline struct dentry *user_path_create(i + } + EXPORT_SYMBOL(user_path_create); + +-int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) ++int vfs_mknod2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) + { +- int error = may_create(dir, dentry); ++ int error = may_create(mnt, dir, dentry); + + if (error) + return error; +@@ -3711,6 +3745,12 @@ int vfs_mknod(struct inode *dir, struct + fsnotify_create(dir, dentry); + return error; + } ++EXPORT_SYMBOL(vfs_mknod2); ++ ++int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) ++{ ++ return vfs_mknod2(NULL, dir, dentry, mode, dev); ++} + EXPORT_SYMBOL(vfs_mknod); + + static int may_mknod(umode_t mode) +@@ -3753,12 +3793,12 @@ retry: + goto out; + switch (mode & S_IFMT) { + case 0: case S_IFREG: +- error = vfs_create(path.dentry->d_inode,dentry,mode,true); ++ error = vfs_create2(path.mnt, path.dentry->d_inode,dentry,mode,true); + if (!error) + ima_post_path_mknod(dentry); + break; + case S_IFCHR: case S_IFBLK: +- error = vfs_mknod(path.dentry->d_inode,dentry,mode, ++ error = vfs_mknod2(path.mnt, path.dentry->d_inode,dentry,mode, + new_decode_dev(dev)); + break; + case S_IFIFO: case S_IFSOCK: +@@ -3785,9 +3825,9 @@ SYSCALL_DEFINE3(mknod, const char __user + return do_mknodat(AT_FDCWD, filename, mode, dev); + } + +-int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++int vfs_mkdir2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, umode_t mode) + { +- int error = may_create(dir, dentry); ++ int error = may_create(mnt, dir, dentry); + unsigned max_links = dir->i_sb->s_max_links; + + if (error) +@@ -3809,6 +3849,12 @@ int vfs_mkdir(struct inode *dir, struct + fsnotify_mkdir(dir, dentry); + return error; + } ++EXPORT_SYMBOL(vfs_mkdir2); ++ ++int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ return vfs_mkdir2(NULL, dir, dentry, mode); ++} + EXPORT_SYMBOL(vfs_mkdir); + + long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) +@@ -3827,7 +3873,7 @@ retry: + mode &= ~current_umask(); + error = security_path_mkdir(&path, dentry, mode); + if (!error) +- error = vfs_mkdir(path.dentry->d_inode, dentry, mode); ++ error = vfs_mkdir2(path.mnt, path.dentry->d_inode, dentry, mode); + done_path_create(&path, dentry); + if (retry_estale(error, lookup_flags)) { + lookup_flags |= LOOKUP_REVAL; +@@ -3846,9 +3892,9 @@ SYSCALL_DEFINE2(mkdir, const char __user + return do_mkdirat(AT_FDCWD, pathname, mode); + } + +-int vfs_rmdir(struct inode *dir, struct dentry *dentry) ++int vfs_rmdir2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry) + { +- int error = may_delete(dir, dentry, 1); ++ int error = may_delete(mnt, dir, dentry, 1); + + if (error) + return error; +@@ -3884,6 +3930,12 @@ out: + d_delete(dentry); + return error; + } ++EXPORT_SYMBOL(vfs_rmdir2); ++ ++int vfs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ return vfs_rmdir2(NULL, dir, dentry); ++} + EXPORT_SYMBOL(vfs_rmdir); + + long do_rmdir(int dfd, const char __user *pathname) +@@ -3929,7 +3981,7 @@ retry: + error = security_path_rmdir(&path, dentry); + if (error) + goto exit3; +- error = vfs_rmdir(path.dentry->d_inode, dentry); ++ error = vfs_rmdir2(path.mnt, path.dentry->d_inode, dentry); + exit3: + dput(dentry); + exit2: +@@ -3968,10 +4020,10 @@ SYSCALL_DEFINE1(rmdir, const char __user + * be appropriate for callers that expect the underlying filesystem not + * to be NFS exported. + */ +-int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) ++int vfs_unlink2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) + { + struct inode *target = dentry->d_inode; +- int error = may_delete(dir, dentry, 0); ++ int error = may_delete(mnt, dir, dentry, 0); + + if (error) + return error; +@@ -4007,6 +4059,12 @@ out: + + return error; + } ++EXPORT_SYMBOL(vfs_unlink2); ++ ++int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) ++{ ++ return vfs_unlink2(NULL, dir, dentry, delegated_inode); ++} + EXPORT_SYMBOL(vfs_unlink); + + /* +@@ -4052,7 +4110,7 @@ retry_deleg: + error = security_path_unlink(&path, dentry); + if (error) + goto exit2; +- error = vfs_unlink(path.dentry->d_inode, dentry, &delegated_inode); ++ error = vfs_unlink2(path.mnt, path.dentry->d_inode, dentry, &delegated_inode); + exit2: + dput(dentry); + } +@@ -4102,9 +4160,9 @@ SYSCALL_DEFINE1(unlink, const char __use + return do_unlinkat(AT_FDCWD, getname(pathname)); + } + +-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) ++int vfs_symlink2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, const char *oldname) + { +- int error = may_create(dir, dentry); ++ int error = may_create(mnt, dir, dentry); + + if (error) + return error; +@@ -4121,6 +4179,12 @@ int vfs_symlink(struct inode *dir, struc + fsnotify_create(dir, dentry); + return error; + } ++EXPORT_SYMBOL(vfs_symlink2); ++ ++int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) ++{ ++ return vfs_symlink2(NULL, dir, dentry, oldname); ++} + EXPORT_SYMBOL(vfs_symlink); + + long do_symlinkat(const char __user *oldname, int newdfd, +@@ -4143,7 +4207,7 @@ retry: + + error = security_path_symlink(&path, dentry, from->name); + if (!error) +- error = vfs_symlink(path.dentry->d_inode, dentry, from->name); ++ error = vfs_symlink2(path.mnt, path.dentry->d_inode, dentry, from->name); + done_path_create(&path, dentry); + if (retry_estale(error, lookup_flags)) { + lookup_flags |= LOOKUP_REVAL; +@@ -4184,7 +4248,7 @@ SYSCALL_DEFINE2(symlink, const char __us + * be appropriate for callers that expect the underlying filesystem not + * to be NFS exported. + */ +-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) ++int vfs_link2(struct vfsmount *mnt, struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) + { + struct inode *inode = old_dentry->d_inode; + unsigned max_links = dir->i_sb->s_max_links; +@@ -4193,7 +4257,7 @@ int vfs_link(struct dentry *old_dentry, + if (!inode) + return -ENOENT; + +- error = may_create(dir, new_dentry); ++ error = may_create(mnt, dir, new_dentry); + if (error) + return error; + +@@ -4243,6 +4307,12 @@ int vfs_link(struct dentry *old_dentry, + fsnotify_link(dir, inode, new_dentry); + return error; + } ++EXPORT_SYMBOL(vfs_link2); ++ ++int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) ++{ ++ return vfs_link2(NULL, old_dentry, dir, new_dentry, delegated_inode); ++} + EXPORT_SYMBOL(vfs_link); + + /* +@@ -4298,7 +4368,7 @@ retry: + error = security_path_link(old_path.dentry, &new_path, new_dentry); + if (error) + goto out_dput; +- error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode); ++ error = vfs_link2(old_path.mnt, old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode); + out_dput: + done_path_create(&new_path, new_dentry); + if (delegated_inode) { +@@ -4380,7 +4450,8 @@ SYSCALL_DEFINE2(link, const char __user + * ->i_mutex on parents, which works but leads to some truly excessive + * locking]. + */ +-int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++int vfs_rename2(struct vfsmount *mnt, ++ struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + struct inode **delegated_inode, unsigned int flags) + { +@@ -4395,19 +4466,19 @@ int vfs_rename(struct inode *old_dir, st + if (source == target) + return 0; + +- error = may_delete(old_dir, old_dentry, is_dir); ++ error = may_delete(mnt, old_dir, old_dentry, is_dir); + if (error) + return error; + + if (!target) { +- error = may_create(new_dir, new_dentry); ++ error = may_create(mnt, new_dir, new_dentry); + } else { + new_is_dir = d_is_dir(new_dentry); + + if (!(flags & RENAME_EXCHANGE)) +- error = may_delete(new_dir, new_dentry, is_dir); ++ error = may_delete(mnt, new_dir, new_dentry, is_dir); + else +- error = may_delete(new_dir, new_dentry, new_is_dir); ++ error = may_delete(mnt, new_dir, new_dentry, new_is_dir); + } + if (error) + return error; +@@ -4421,12 +4492,12 @@ int vfs_rename(struct inode *old_dir, st + */ + if (new_dir != old_dir) { + if (is_dir) { +- error = inode_permission(source, MAY_WRITE); ++ error = inode_permission2(mnt, source, MAY_WRITE); + if (error) + return error; + } + if ((flags & RENAME_EXCHANGE) && new_is_dir) { +- error = inode_permission(target, MAY_WRITE); ++ error = inode_permission2(mnt, target, MAY_WRITE); + if (error) + return error; + } +@@ -4503,6 +4574,14 @@ out: + + return error; + } ++EXPORT_SYMBOL(vfs_rename2); ++ ++int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct inode **delegated_inode, unsigned int flags) ++{ ++ return vfs_rename2(NULL, old_dir, old_dentry, new_dir, new_dentry, delegated_inode, flags); ++} + EXPORT_SYMBOL(vfs_rename); + + static int do_renameat2(int olddfd, const char __user *oldname, int newdfd, +@@ -4616,7 +4695,7 @@ retry_deleg: + &new_path, new_dentry, flags); + if (error) + goto exit5; +- error = vfs_rename(old_path.dentry->d_inode, old_dentry, ++ error = vfs_rename2(old_path.mnt, old_path.dentry->d_inode, old_dentry, + new_path.dentry->d_inode, new_dentry, + &delegated_inode, flags); + exit5: +@@ -4667,7 +4746,7 @@ SYSCALL_DEFINE2(rename, const char __use + + int vfs_whiteout(struct inode *dir, struct dentry *dentry) + { +- int error = may_create(dir, dentry); ++ int error = may_create(NULL, dir, dentry); + if (error) + return error; + +Index: common/fs/notify/fanotify/fanotify_user.c +=================================================================== +--- common.orig/fs/notify/fanotify/fanotify_user.c ++++ common/fs/notify/fanotify/fanotify_user.c +@@ -567,7 +567,7 @@ static int fanotify_find_path(int dfd, c + } + + /* you can only watch an inode if you have read permissions on it */ +- ret = inode_permission(path->dentry->d_inode, MAY_READ); ++ ret = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ); + if (ret) { + path_put(path); + goto out; +Index: common/fs/notify/inotify/inotify_user.c +=================================================================== +--- common.orig/fs/notify/inotify/inotify_user.c ++++ common/fs/notify/inotify/inotify_user.c +@@ -341,7 +341,7 @@ static int inotify_find_inode(const char + if (error) + return error; + /* you can only watch an inode if you have read permissions on it */ +- error = inode_permission(path->dentry->d_inode, MAY_READ); ++ error = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ); + if (error) { + path_put(path); + return error; +Index: common/fs/open.c +=================================================================== +--- common.orig/fs/open.c ++++ common/fs/open.c +@@ -90,7 +90,7 @@ long vfs_truncate(const struct path *pat + if (error) + goto out; + +- error = inode_permission(inode, MAY_WRITE); ++ error = inode_permission2(mnt, inode, MAY_WRITE); + if (error) + goto mnt_drop_write_and_out; + +@@ -360,6 +360,7 @@ long do_faccessat(int dfd, const char __ + struct cred *override_cred; + struct path path; + struct inode *inode; ++ struct vfsmount *mnt; + int res; + unsigned int lookup_flags = LOOKUP_FOLLOW; + +@@ -409,6 +410,7 @@ retry: + goto out; + + inode = d_backing_inode(path.dentry); ++ mnt = path.mnt; + + if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { + /* +@@ -420,7 +422,7 @@ retry: + goto out_path_release; + } + +- res = inode_permission(inode, mode | MAY_ACCESS); ++ res = inode_permission2(mnt, inode, mode | MAY_ACCESS); + /* SuS v2 requires we report a read only fs too */ + if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) + goto out_path_release; +@@ -469,7 +471,7 @@ retry: + if (error) + goto out; + +- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); ++ error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); + if (error) + goto dput_and_out; + +@@ -503,7 +505,8 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd + if (!d_can_lookup(f.file->f_path.dentry)) + goto out_putf; + +- error = inode_permission(file_inode(f.file), MAY_EXEC | MAY_CHDIR); ++ error = inode_permission2(f.file->f_path.mnt, file_inode(f.file), ++ MAY_EXEC | MAY_CHDIR); + if (!error) + set_fs_pwd(current->fs, &f.file->f_path); + out_putf: +@@ -522,7 +525,7 @@ retry: + if (error) + goto out; + +- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); ++ error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); + if (error) + goto dput_and_out; + +Index: common/fs/xattr.c +=================================================================== +--- common.orig/fs/xattr.c ++++ common/fs/xattr.c +@@ -131,7 +131,7 @@ xattr_permission(struct inode *inode, co + return -EPERM; + } + +- return inode_permission(inode, mask); ++ return inode_permission2(ERR_PTR(-EOPNOTSUPP), inode, mask); + } + + int +Index: common/include/linux/fs.h +=================================================================== +--- common.orig/include/linux/fs.h ++++ common/include/linux/fs.h +@@ -1709,13 +1709,21 @@ extern bool inode_owner_or_capable(const + * VFS helper functions.. + */ + extern int vfs_create(struct inode *, struct dentry *, umode_t, bool); ++extern int vfs_create2(struct vfsmount *, struct inode *, struct dentry *, umode_t, bool); + extern int vfs_mkdir(struct inode *, struct dentry *, umode_t); ++extern int vfs_mkdir2(struct vfsmount *, struct inode *, struct dentry *, umode_t); + extern int vfs_mknod(struct inode *, struct dentry *, umode_t, dev_t); ++extern int vfs_mknod2(struct vfsmount *, struct inode *, struct dentry *, umode_t, dev_t); + extern int vfs_symlink(struct inode *, struct dentry *, const char *); ++extern int vfs_symlink2(struct vfsmount *, struct inode *, struct dentry *, const char *); + extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **); ++extern int vfs_link2(struct vfsmount *, struct dentry *, struct inode *, struct dentry *, struct inode **); + extern int vfs_rmdir(struct inode *, struct dentry *); ++extern int vfs_rmdir2(struct vfsmount *, struct inode *, struct dentry *); + extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); ++extern int vfs_unlink2(struct vfsmount *, struct inode *, struct dentry *, struct inode **); + extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); ++extern int vfs_rename2(struct vfsmount *, struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); + extern int vfs_whiteout(struct inode *, struct dentry *); + + extern struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, +@@ -1724,6 +1732,9 @@ extern struct dentry *vfs_tmpfile(struct + int vfs_mkobj(struct dentry *, umode_t, + int (*f)(struct dentry *, umode_t, void *), + void *); ++int vfs_mkobj2(struct vfsmount *, struct dentry *, umode_t, ++ int (*f)(struct dentry *, umode_t, void *), ++ void *); + + extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); + +@@ -1857,6 +1868,7 @@ struct inode_operations { + struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); + const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); + int (*permission) (struct inode *, int); ++ int (*permission2) (struct vfsmount *, struct inode *, int); + struct posix_acl * (*get_acl)(struct inode *, int); + + int (*readlink) (struct dentry *, char __user *,int); +@@ -2871,6 +2883,7 @@ extern sector_t bmap(struct inode *, sec + extern int notify_change(struct dentry *, struct iattr *, struct inode **); + extern int notify_change2(struct vfsmount *, struct dentry *, struct iattr *, struct inode **); + extern int inode_permission(struct inode *, int); ++extern int inode_permission2(struct vfsmount *, struct inode *, int); + extern int generic_permission(struct inode *, int); + extern int __check_sticky(struct inode *dir, struct inode *inode); + +Index: common/include/linux/namei.h +=================================================================== +--- common.orig/include/linux/namei.h ++++ common/include/linux/namei.h +@@ -59,6 +59,7 @@ extern int kern_path_mountpoint(int, con + + extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); + extern struct dentry *lookup_one_len(const char *, struct dentry *, int); ++extern struct dentry *lookup_one_len2(const char *, struct vfsmount *mnt, struct dentry *, int); + extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); + + extern int follow_down_one(struct path *); +Index: common/ipc/mqueue.c +=================================================================== +--- common.orig/ipc/mqueue.c ++++ common/ipc/mqueue.c +@@ -768,7 +768,7 @@ static void remove_notification(struct m + info->notify_user_ns = NULL; + } + +-static int prepare_open(struct dentry *dentry, int oflag, int ro, ++static int prepare_open(struct vfsmount *mnt, struct dentry *dentry, int oflag, int ro, + umode_t mode, struct filename *name, + struct mq_attr *attr) + { +@@ -782,7 +782,7 @@ static int prepare_open(struct dentry *d + if (ro) + return ro; + audit_inode_parent_hidden(name, dentry->d_parent); +- return vfs_mkobj(dentry, mode & ~current_umask(), ++ return vfs_mkobj2(mnt, dentry, mode & ~current_umask(), + mqueue_create_attr, attr); + } + /* it already existed */ +@@ -792,7 +792,7 @@ static int prepare_open(struct dentry *d + if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) + return -EINVAL; + acc = oflag2acc[oflag & O_ACCMODE]; +- return inode_permission(d_inode(dentry), acc); ++ return inode_permission2(mnt, d_inode(dentry), acc); + } + + static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, +@@ -816,13 +816,13 @@ static int do_mq_open(const char __user + + ro = mnt_want_write(mnt); /* we'll drop it in any case */ + inode_lock(d_inode(root)); +- path.dentry = lookup_one_len(name->name, root, strlen(name->name)); ++ path.dentry = lookup_one_len2(name->name, mnt, root, strlen(name->name)); + if (IS_ERR(path.dentry)) { + error = PTR_ERR(path.dentry); + goto out_putfd; + } + path.mnt = mntget(mnt); +- error = prepare_open(path.dentry, oflag, ro, mode, name, attr); ++ error = prepare_open(path.mnt, path.dentry, oflag, ro, mode, name, attr); + if (!error) { + struct file *file = dentry_open(&path, oflag, current_cred()); + if (!IS_ERR(file)) +@@ -872,7 +872,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __ + if (err) + goto out_name; + inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT); +- dentry = lookup_one_len(name->name, mnt->mnt_root, ++ dentry = lookup_one_len2(name->name, mnt, mnt->mnt_root, + strlen(name->name)); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); +@@ -884,7 +884,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __ + err = -ENOENT; + } else { + ihold(inode); +- err = vfs_unlink(d_inode(dentry->d_parent), dentry, NULL); ++ err = vfs_unlink2(mnt, d_inode(dentry->d_parent), dentry, NULL); + } + dput(dentry); + +Index: common/security/inode.c +=================================================================== +--- common.orig/security/inode.c ++++ common/security/inode.c +@@ -128,7 +128,7 @@ static struct dentry *securityfs_create_ + dir = d_inode(parent); + + inode_lock(dir); +- dentry = lookup_one_len(name, parent, strlen(name)); ++ dentry = lookup_one_len2(name, mount, parent, strlen(name)); + if (IS_ERR(dentry)) + goto out; + diff --git a/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mo.patch b/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mo.patch new file mode 100644 index 000000000000..c92ba13ac672 --- /dev/null +++ b/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mo.patch @@ -0,0 +1,262 @@ +From c7bee6d1909136f102ac6f5a70a7036096804f5f Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Wed, 26 Oct 2016 16:33:11 -0700 +Subject: ANDROID: vfs: Add setattr2 for filesystems with per + mount permissions + +This allows filesystems to use their mount private data to +influence the permssions they use in setattr2. It has +been separated into a new call to avoid disrupting current +setattr users. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Change-Id: I19959038309284448f1b7f232d579674ef546385 +Signed-off-by: Daniel Rosenberg +Signed-off-by: Yongqin Liu +--- + fs/attr.c | 12 ++++++++++-- + fs/coredump.c | 2 +- + fs/inode.c | 6 +++--- + fs/namei.c | 2 +- + fs/open.c | 23 ++++++++++++++++------- + fs/utimes.c | 2 +- + include/linux/fs.h | 6 +++++- + 7 files changed, 37 insertions(+), 16 deletions(-) + +diff --git a/fs/attr.c b/fs/attr.c +index d22e8187477fa..e55ed6e817d39 100644 +--- a/fs/attr.c ++++ b/fs/attr.c +@@ -223,7 +223,7 @@ EXPORT_SYMBOL(setattr_copy); + * the file open for write, as there can be no conflicting delegation in + * that case. + */ +-int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) ++int notify_change2(struct vfsmount *mnt, struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) + { + struct inode *inode = dentry->d_inode; + umode_t mode = inode->i_mode; +@@ -330,7 +330,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de + if (error) + return error; + +- if (inode->i_op->setattr) ++ if (mnt && inode->i_op->setattr2) ++ error = inode->i_op->setattr2(mnt, dentry, attr); ++ else if (inode->i_op->setattr) + error = inode->i_op->setattr(dentry, attr); + else + error = simple_setattr(dentry, attr); +@@ -343,4 +345,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de + + return error; + } ++EXPORT_SYMBOL(notify_change2); ++ ++int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) ++{ ++ return notify_change2(NULL, dentry, attr, delegated_inode); ++} + EXPORT_SYMBOL(notify_change); +diff --git a/fs/coredump.c b/fs/coredump.c +index b1ea7dfbd1494..a6b542bb4d854 100644 +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -775,7 +775,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) + goto close_fail; + if (!(cprm.file->f_mode & FMODE_CAN_WRITE)) + goto close_fail; +- if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file)) ++ if (do_truncate2(cprm.file->f_path.mnt, cprm.file->f_path.dentry, 0, 0, cprm.file)) + goto close_fail; + } + +diff --git a/fs/inode.c b/fs/inode.c +index 0f1e3b563c472..a13406a904cb3 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1807,7 +1807,7 @@ int dentry_needs_remove_privs(struct dentry *dentry) + return mask; + } + +-static int __remove_privs(struct dentry *dentry, int kill) ++static int __remove_privs(struct vfsmount *mnt, struct dentry *dentry, int kill) + { + struct iattr newattrs; + +@@ -1816,7 +1816,7 @@ static int __remove_privs(struct dentry *dentry, int kill) + * Note we call this on write, so notify_change will not + * encounter any conflicting delegations: + */ +- return notify_change(dentry, &newattrs, NULL); ++ return notify_change2(mnt, dentry, &newattrs, NULL); + } + + /* +@@ -1843,7 +1843,7 @@ int file_remove_privs(struct file *file) + if (kill < 0) + return kill; + if (kill) +- error = __remove_privs(dentry, kill); ++ error = __remove_privs(file->f_path.mnt, dentry, kill); + if (!error) + inode_has_no_xattr(inode); + +diff --git a/fs/namei.c b/fs/namei.c +index 209c51a5226c9..7452758e0e558 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3003,7 +3003,7 @@ static int handle_truncate(struct file *filp) + if (!error) + error = security_path_truncate(path); + if (!error) { +- error = do_truncate(path->dentry, 0, ++ error = do_truncate2(path->mnt, path->dentry, 0, + ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, + filp); + } +diff --git a/fs/open.c b/fs/open.c +index a59abe3c669ae..47906b576e6a4 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -35,8 +35,8 @@ + + #include "internal.h" + +-int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, +- struct file *filp) ++int do_truncate2(struct vfsmount *mnt, struct dentry *dentry, loff_t length, ++ unsigned int time_attrs, struct file *filp) + { + int ret; + struct iattr newattrs; +@@ -61,17 +61,24 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, + + inode_lock(dentry->d_inode); + /* Note any delegations or leases have already been broken: */ +- ret = notify_change(dentry, &newattrs, NULL); ++ ret = notify_change2(mnt, dentry, &newattrs, NULL); + inode_unlock(dentry->d_inode); + return ret; + } ++int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, ++ struct file *filp) ++{ ++ return do_truncate2(NULL, dentry, length, time_attrs, filp); ++} + + long vfs_truncate(const struct path *path, loff_t length) + { + struct inode *inode; ++ struct vfsmount *mnt; + long error; + + inode = path->dentry->d_inode; ++ mnt = path->mnt; + + /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ + if (S_ISDIR(inode->i_mode)) +@@ -107,7 +114,7 @@ long vfs_truncate(const struct path *path, loff_t length) + if (!error) + error = security_path_truncate(path); + if (!error) +- error = do_truncate(path->dentry, length, 0, NULL); ++ error = do_truncate2(mnt, path->dentry, length, 0, NULL); + + put_write_and_out: + put_write_access(inode); +@@ -156,6 +163,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) + { + struct inode *inode; + struct dentry *dentry; ++ struct vfsmount *mnt; + struct fd f; + int error; + +@@ -172,6 +180,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) + small = 0; + + dentry = f.file->f_path.dentry; ++ mnt = f.file->f_path.mnt; + inode = dentry->d_inode; + error = -EINVAL; + if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE)) +@@ -192,7 +201,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) + if (!error) + error = security_path_truncate(&f.file->f_path); + if (!error) +- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); ++ error = do_truncate2(mnt, dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); + sb_end_write(inode->i_sb); + out_putf: + fdput(f); +@@ -558,7 +567,7 @@ static int chmod_common(const struct path *path, umode_t mode) + goto out_unlock; + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; +- error = notify_change(path->dentry, &newattrs, &delegated_inode); ++ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); + out_unlock: + inode_unlock(inode); + if (delegated_inode) { +@@ -649,7 +658,7 @@ static int chown_common(const struct path *path, uid_t user, gid_t group) + inode_lock(inode); + error = security_path_chown(path, uid, gid); + if (!error) +- error = notify_change(path->dentry, &newattrs, &delegated_inode); ++ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); + inode_unlock(inode); + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); +diff --git a/fs/utimes.c b/fs/utimes.c +index 350c9c16ace1a..9cf7092b1dd8e 100644 +--- a/fs/utimes.c ++++ b/fs/utimes.c +@@ -59,7 +59,7 @@ static int utimes_common(const struct path *path, struct timespec64 *times) + } + retry_deleg: + inode_lock(inode); +- error = notify_change(path->dentry, &newattrs, &delegated_inode); ++ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); + inode_unlock(inode); + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 997a530ff4e9d..b4f5eda8a4464 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1846,7 +1846,8 @@ struct inode_operations { + int (*rename) (struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); + int (*setattr) (struct dentry *, struct iattr *); +- int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); ++ int (*setattr2) (struct vfsmount *, struct dentry *, struct iattr *); ++ int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); + ssize_t (*listxattr) (struct dentry *, char *, size_t); + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, + u64 len); +@@ -2492,6 +2493,8 @@ static_assert(offsetof(struct filename, iname) % sizeof(long) == 0); + extern long vfs_truncate(const struct path *, loff_t); + extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, + struct file *filp); ++extern int do_truncate2(struct vfsmount *, struct dentry *, loff_t start, ++ unsigned int time_attrs, struct file *filp); + extern int vfs_fallocate(struct file *file, int mode, loff_t offset, + loff_t len); + extern long do_sys_open(int dfd, const char __user *filename, int flags, +@@ -2812,6 +2815,7 @@ extern void emergency_remount(void); + extern sector_t bmap(struct inode *, sector_t); + #endif + extern int notify_change(struct dentry *, struct iattr *, struct inode **); ++extern int notify_change2(struct vfsmount *, struct dentry *, struct iattr *, struct inode **); + extern int inode_permission(struct inode *, int); + extern int generic_permission(struct inode *, int); + extern int __check_sticky(struct inode *dir, struct inode *inode); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesys.patch b/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesys.patch new file mode 100644 index 000000000000..851a5b6718c3 --- /dev/null +++ b/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesys.patch @@ -0,0 +1,113 @@ +From a873fae63398553a7ca1f85b47f08e55d3891b4c Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Thu, 11 Feb 2016 16:44:15 -0800 +Subject: ANDROID: vfs: add d_canonical_path for stacked + filesystem support + +Inotify does not currently know when a filesystem +is acting as a wrapper around another fs. This means +that inotify watchers will miss any modifications to +the base file, as well as any made in a separate +stacked fs that points to the same file. +d_canonical_path solves this problem by allowing the fs +to map a dentry to a path in the lower fs. Inotify +can use it to find the appropriate place to watch to +be informed of all changes to a file. + +Test: HiKey/X15 + Pie + android-mainline, + and HiKey + AOSP Maser + android-mainline, + directories under /sdcard created, + output of mount is right, + CTS test collecting device infor works + +Bug: 70706497 +Change-Id: I09563baffad1711a045e45c1bd0bd8713c2cc0b6 +Signed-off-by: Daniel Rosenberg +[astrachan: Folded 34df4102216e ("ANDROID: fsnotify: Notify lower fs of + open") into this patch] +Signed-off-by: Alistair Strachan +Signed-off-by: Yongqin Liu +--- + fs/notify/inotify/inotify_user.c | 15 +++++++++++++-- + include/linux/dcache.h | 1 + + include/linux/fsnotify.h | 7 +++++++ + 3 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c +index b6fee358e93fd..cade62c6219d6 100644 +--- a/fs/notify/inotify/inotify_user.c ++++ b/fs/notify/inotify/inotify_user.c +@@ -692,6 +692,8 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, + struct fsnotify_group *group; + struct inode *inode; + struct path path; ++ struct path alteredpath; ++ struct path *canonical_path = &path; + struct fd f; + int ret; + unsigned flags = 0; +@@ -737,13 +739,22 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, + if (ret) + goto fput_and_out; + ++ /* support stacked filesystems */ ++ if(path.dentry && path.dentry->d_op) { ++ if (path.dentry->d_op->d_canonical_path) { ++ path.dentry->d_op->d_canonical_path(&path, &alteredpath); ++ canonical_path = &alteredpath; ++ path_put(&path); ++ } ++ } ++ + /* inode held in place by reference to path; group by fget on fd */ +- inode = path.dentry->d_inode; ++ inode = canonical_path->dentry->d_inode; + group = f.file->private_data; + + /* create/update an inode mark */ + ret = inotify_update_watch(group, inode, mask); +- path_put(&path); ++ path_put(canonical_path); + fput_and_out: + fdput(f); + return ret; +diff --git a/include/linux/dcache.h b/include/linux/dcache.h +index 9451011ac014a..c541a3d99da46 100644 +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -147,6 +147,7 @@ struct dentry_operations { + struct vfsmount *(*d_automount)(struct path *); + int (*d_manage)(const struct path *, bool); + struct dentry *(*d_real)(struct dentry *, const struct inode *); ++ void (*d_canonical_path)(const struct path *, struct path *); + } ____cacheline_aligned; + + /* +diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h +index a2d5d175d3c15..e018872b047c5 100644 +--- a/include/linux/fsnotify.h ++++ b/include/linux/fsnotify.h +@@ -262,6 +262,7 @@ static inline void fsnotify_modify(struct file *file) + static inline void fsnotify_open(struct file *file) + { + const struct path *path = &file->f_path; ++ struct path lower_path; + struct inode *inode = file_inode(file); + __u32 mask = FS_OPEN; + +@@ -270,6 +271,12 @@ static inline void fsnotify_open(struct file *file) + if (file->f_flags & __FMODE_EXEC) + mask |= FS_OPEN_EXEC; + ++ if (path->dentry->d_op && path->dentry->d_op->d_canonical_path) { ++ path->dentry->d_op->d_canonical_path(path, &lower_path); ++ fsnotify_parent(&lower_path, NULL, mask); ++ fsnotify(lower_path.dentry->d_inode, mask, &lower_path, FSNOTIFY_EVENT_PATH, NULL, 0); ++ path_put(&lower_path); ++ } + fsnotify_path(inode, path, mask); + } + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-x86-Remove-a-useless-warning-message.patch b/patches/ANDROID-x86-Remove-a-useless-warning-message.patch new file mode 100644 index 000000000000..f45297fb28f5 --- /dev/null +++ b/patches/ANDROID-x86-Remove-a-useless-warning-message.patch @@ -0,0 +1,39 @@ +From a2ad8abfb9fbc330e2499038cabbbfe66002124e Mon Sep 17 00:00:00 2001 +From: Alistair Strachan +Date: Mon, 29 Oct 2018 15:20:05 -0700 +Subject: ANDROID: x86: Remove a useless warning message + +While we wait for a clang prebuilt with asm-goto support, we have +removed the kbuild's detection of a clang without asm-goto (the +kernel builds fine without it), so we don't need to see the same +warning about not having the compiler feature fill the kernel build +log, which potentially hides other issues. + +This patch should be reverted when the new clang prebuilt lands and +we have reverted the other reverts. + +Bug: 120440614 +Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 +Change-Id: I26aee5b9dd291f27b950dee4b0c64471d972ddb5 +Signed-off-by: Alistair Strachan +--- + arch/x86/include/asm/cpufeature.h | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h +index 58acda5038178..c636a148f71fe 100644 +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -147,9 +147,6 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); + * Workaround for the sake of BPF compilation which utilizes kernel + * headers, but clang does not support ASM GOTO and fails the build. + */ +-#ifndef __BPF_TRACING__ +-#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" +-#endif + + #define static_cpu_has(bit) boot_cpu_has(bit) + +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch b/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch new file mode 100644 index 000000000000..0e3f4f2af6f6 --- /dev/null +++ b/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch @@ -0,0 +1,27 @@ +From 74a92b41b8dec54e66664a42135c9a725e942bc4 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 12 Jun 2019 17:17:06 -0700 +Subject: ANDROID: x86 gki_defconfig: enable DMA_CMA + +Test: Boot x86 gki +Change-Id: Ic517f4de7865b9bb3f20fbd282a97dd7d8fa775e +Signed-off-by: Ram Muthiah +--- + arch/x86/configs/gki_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 94690e9d016a2..7f4edee2b52d8 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -321,6 +321,7 @@ CONFIG_CRYPTO_ANSI_CPRNG=y + CONFIG_CRYPTO_DEV_VIRTIO=y + CONFIG_CRC8=y + CONFIG_XZ_DEC=y ++CONFIG_DMA_CMA=y + CONFIG_PRINTK_TIME=y + CONFIG_DEBUG_INFO=y + # CONFIG_ENABLE_MUST_CHECK is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch b/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch new file mode 100644 index 000000000000..f9bc2d2ffb20 --- /dev/null +++ b/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch @@ -0,0 +1,47 @@ +From 4336c0c080c9a073237a8d589c3ff7d3046aa0ca Mon Sep 17 00:00:00 2001 +From: Tri Vo +Date: Thu, 25 Jul 2019 16:57:16 -0700 +Subject: ANDROID: xfrm: remove in_compat_syscall() checks + +This hack is needed to run 32-bit userspace on 64-bit kernel. + +Bug: 138147164 +Test: kernel_net_tests +Signed-off-by: Tri Vo +Change-Id: I083d32b45ca985cfadfe3ce57d253b63202befde +--- + net/xfrm/xfrm_state.c | 3 --- + net/xfrm/xfrm_user.c | 3 --- + 2 files changed, 6 deletions(-) + +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index c6f3c4a1bd993..c023b27c70e1c 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -2266,9 +2266,6 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen + struct xfrm_mgr *km; + struct xfrm_policy *pol = NULL; + +- if (in_compat_syscall()) +- return -EOPNOTSUPP; +- + if (!optval && !optlen) { + xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); + xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL); +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index b88ba45ff1ace..ed6e6790b3e74 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -2634,9 +2634,6 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + const struct xfrm_link *link; + int type, err; + +- if (in_compat_syscall()) +- return -EOPNOTSUPP; +- + type = nlh->nlmsg_type; + if (type > XFRM_MSG_MAX) + return -EINVAL; +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/Adding-GKI-Ramdisk-to-gki-config.patch b/patches/Adding-GKI-Ramdisk-to-gki-config.patch new file mode 100644 index 000000000000..4be05b0c803c --- /dev/null +++ b/patches/Adding-GKI-Ramdisk-to-gki-config.patch @@ -0,0 +1,32 @@ +From 21d4489e0abdfcff64c88a0505392f9256315c2a Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Tue, 13 Aug 2019 10:11:28 -0700 +Subject: Adding GKI Ramdisk to gki config + +Test: Treehugger +Bug: 132629930 +Change-Id: I3773d828cea4ab0ea8cfaef8a533a5ae925f037c +Signed-of-by: Ram Muthiah +--- + build.config.gki.aarch64 | 1 + + build.config.gki.x86_64 | 1 + + 2 files changed, 2 insertions(+) + +Index: common/build.config.gki.aarch64 +=================================================================== +--- common.orig/build.config.gki.aarch64 ++++ common/build.config.gki.aarch64 +@@ -16,3 +16,4 @@ vmlinux + System.map + " + STOP_SHIP_TRACEPRINTK=1 ++BUILD_INITRAMFS=1 +Index: common/build.config.gki.x86_64 +=================================================================== +--- common.orig/build.config.gki.x86_64 ++++ common/build.config.gki.x86_64 +@@ -16,3 +16,4 @@ vmlinux + System.map + " + STOP_SHIP_TRACEPRINTK=1 ++BUILD_INITRAMFS=1 diff --git a/patches/Adding-SERIAL_OF_PLATFORM-module-to-gki.patch b/patches/Adding-SERIAL_OF_PLATFORM-module-to-gki.patch new file mode 100644 index 000000000000..fd5d4d04f583 --- /dev/null +++ b/patches/Adding-SERIAL_OF_PLATFORM-module-to-gki.patch @@ -0,0 +1,49 @@ +From 642620ef780f3c59ddfeee0c8549cc3beb6643b2 Mon Sep 17 00:00:00 2001 +From: Ram Muthiah +Date: Wed, 4 Sep 2019 16:18:17 -0700 +Subject: Adding SERIAL_OF_PLATFORM module to gki + +Bug: 132629930 +Change-Id: I722540edb8b7a7289e45e63de2959399cb563e23 +Signed-off-by: Ram Muthiah +--- + arch/arm64/configs/gki_defconfig | 2 +- + arch/x86/configs/gki_defconfig | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 6aae6d55e96c5..d650f7d141e7f 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -268,7 +268,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 + CONFIG_SERIAL_8250_EXTENDED=y + CONFIG_SERIAL_8250_MANY_PORTS=y + CONFIG_SERIAL_8250_SHARE_IRQ=y +-CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_OF_PLATFORM=m + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + CONFIG_VIRTIO_CONSOLE=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index b3dad521ee8a2..511a763add373 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -170,6 +170,7 @@ CONFIG_RFKILL=y + CONFIG_PCI=y + # CONFIG_ALLOW_DEV_COREDUMP is not set + CONFIG_DEBUG_DEVRES=y ++CONFIG_OF=y + CONFIG_ZRAM=y + CONFIG_BLK_DEV_LOOP=y + CONFIG_BLK_DEV_RAM=y +@@ -240,6 +241,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 + CONFIG_SERIAL_8250_EXTENDED=y + CONFIG_SERIAL_8250_MANY_PORTS=y + CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_OF_PLATFORM=m + CONFIG_HW_RANDOM=y + CONFIG_HW_RANDOM_VIRTIO=m + # CONFIG_I2C_COMPAT is not set +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/CONFIG_MMC-m.patch b/patches/CONFIG_MMC-m.patch new file mode 100644 index 000000000000..08217899cbfb --- /dev/null +++ b/patches/CONFIG_MMC-m.patch @@ -0,0 +1,48 @@ +From 76dd6e0a5844f12e518d76df823eee1ad31cef9b Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Thu, 12 Sep 2019 14:06:44 -0700 +Subject: CONFIG_MMC=m + +Signed-off-by: Mark Salyzyn +Test: compile +Bug: 140652382 +Change-Id: Ie6002cde4d964920c71edd347851df9ceec4ee0f +(cherry picked from commit 30f8bea960e42921156a401e8e8ddb80fa3ee5c6) +--- + arch/arm64/configs/gki_defconfig | 6 +++--- + arch/x86/configs/gki_defconfig | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +Index: common/arch/arm64/configs/gki_defconfig +=================================================================== +--- common.orig/arch/arm64/configs/gki_defconfig ++++ common/arch/arm64/configs/gki_defconfig +@@ -323,11 +323,11 @@ CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y +-CONFIG_MMC=y ++CONFIG_MMC=m + # CONFIG_PWRSEQ_EMMC is not set + # CONFIG_PWRSEQ_SIMPLE is not set +-CONFIG_MMC_SDHCI=y +-CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI=m ++CONFIG_MMC_SDHCI_PLTFM=m + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y +Index: common/arch/x86/configs/gki_defconfig +=================================================================== +--- common.orig/arch/x86/configs/gki_defconfig ++++ common/arch/x86/configs/gki_defconfig +@@ -280,8 +280,7 @@ CONFIG_USB_CONFIGFS_F_FS=y + CONFIG_USB_CONFIGFS_F_ACC=y + CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y + CONFIG_USB_CONFIGFS_F_MIDI=y +-CONFIG_MMC=y +-# CONFIG_MMC_BLOCK is not set ++CONFIG_MMC=m + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_TRIGGERS=y diff --git a/patches/Enable-CONFIG_ION_SYSTEM_HEAP.patch b/patches/Enable-CONFIG_ION_SYSTEM_HEAP.patch new file mode 100644 index 000000000000..687719ba2146 --- /dev/null +++ b/patches/Enable-CONFIG_ION_SYSTEM_HEAP.patch @@ -0,0 +1,41 @@ +From 56a578319367ae92d8c64809a8a96ddd4d5b6f72 Mon Sep 17 00:00:00 2001 +From: "Jorge E. Moreira" +Date: Thu, 23 May 2019 17:26:51 -0700 +Subject: Enable CONFIG_ION_SYSTEM_HEAP + +Bug: 132983011 +Test: atest MediaStore_Video_ThumbnailsTest +Signed-off-by: Jorge E. Moreira +Change-Id: I2211af2700439c14e7ff53ac5c7e45579d0ab8bf +--- + arch/arm64/configs/cuttlefish_defconfig | 1 + + arch/x86/configs/x86_64_cuttlefish_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig +index 41502bd397dd5..69ee170e471d6 100644 +--- a/arch/arm64/configs/cuttlefish_defconfig ++++ b/arch/arm64/configs/cuttlefish_defconfig +@@ -390,6 +390,7 @@ CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y ++CONFIG_ION_SYSTEM_HEAP=y + CONFIG_COMMON_CLK_SCPI=y + # CONFIG_COMMON_CLK_XGENE is not set + CONFIG_MAILBOX=y +diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig +index 06c931405999c..cdb7e31593e1c 100644 +--- a/arch/x86/configs/x86_64_cuttlefish_defconfig ++++ b/arch/x86/configs/x86_64_cuttlefish_defconfig +@@ -407,6 +407,7 @@ CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y ++CONFIG_ION_SYSTEM_HEAP=y + # CONFIG_X86_PLATFORM_DEVICES is not set + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_ANDROID=y +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch b/patches/Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch new file mode 100644 index 000000000000..2d764c5ccfa9 --- /dev/null +++ b/patches/Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch @@ -0,0 +1,29 @@ +From c50dd17439543a7ac4b26fd901f588cdac6177a5 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Thu, 22 Aug 2019 16:53:19 -0700 +Subject: Revert "um: irq: don't set the chip for all irqs" + +This reverts commit 1987b1b8f9f17a06255877e7917d0bb5b5377774. + +Reason: Broke UML used by kernel_tests + +Bug: 139897923 +Change-Id: If3541721fdca7cf6d77410309ae5b503b5a848d0 +Signed-off-by: Alistair Delva +--- + arch/um/kernel/irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: common/arch/um/kernel/irq.c +=================================================================== +--- common.orig/arch/um/kernel/irq.c ++++ common/arch/um/kernel/irq.c +@@ -480,7 +480,7 @@ void __init init_IRQ(void) + irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); + + +- for (i = 1; i <= LAST_IRQ; i++) ++ for (i = 1; i < NR_IRQS; i++) + irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); + /* Initialize EPOLL Loop */ + os_setup_epoll(); diff --git a/patches/Revert-um-remove-uses-of-variable-length-arrays.patch b/patches/Revert-um-remove-uses-of-variable-length-arrays.patch new file mode 100644 index 000000000000..20a2c726293c --- /dev/null +++ b/patches/Revert-um-remove-uses-of-variable-length-arrays.patch @@ -0,0 +1,110 @@ +From f0abb84e2e0c4d039751ad35b9c02b7603812255 Mon Sep 17 00:00:00 2001 +From: Alistair Delva +Date: Thu, 22 Aug 2019 16:53:55 -0700 +Subject: Revert "um: remove uses of variable length arrays" + +This reverts commit 0d4e5ac7e78035950d564e65c38ce148cb9af681. + +Reason: Broke UML used by kernel_tests + +Bug: 139897923 +Change-Id: Ibf57c1f535e60caaef32dd14c4abbe253d8e185d +Signed-off-by: Alistair Delva +--- + arch/um/os-Linux/umid.c | 36 +++++++++--------------------------- + 1 file changed, 9 insertions(+), 27 deletions(-) + +diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c +index e261656fe9d7a..998fbb4454586 100644 +--- a/arch/um/os-Linux/umid.c ++++ b/arch/um/os-Linux/umid.c +@@ -135,18 +135,12 @@ static int remove_files_and_dir(char *dir) + */ + static inline int is_umdir_used(char *dir) + { +- char pid[sizeof("nnnnn\0")], *end, *file; ++ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; ++ char pid[sizeof("nnnnn\0")], *end; + int dead, fd, p, n, err; +- size_t filelen; + +- err = asprintf(&file, "%s/pid", dir); +- if (err < 0) +- return 0; +- +- filelen = strlen(file); +- +- n = snprintf(file, filelen, "%s/pid", dir); +- if (n >= filelen) { ++ n = snprintf(file, sizeof(file), "%s/pid", dir); ++ if (n >= sizeof(file)) { + printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n"); + err = -E2BIG; + goto out; +@@ -191,7 +185,6 @@ static inline int is_umdir_used(char *dir) + out_close: + close(fd); + out: +- free(file); + return 0; + } + +@@ -217,21 +210,18 @@ static int umdir_take_if_dead(char *dir) + + static void __init create_pid_file(void) + { +- char pid[sizeof("nnnnn\0")], *file; ++ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; ++ char pid[sizeof("nnnnn\0")]; + int fd, n; + +- file = malloc(strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")); +- if (!file) +- return; +- + if (umid_file_name("pid", file, sizeof(file))) +- goto out; ++ return; + + fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); + if (fd < 0) { + printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: " + "%s\n", file, strerror(errno)); +- goto out; ++ return; + } + + snprintf(pid, sizeof(pid), "%d\n", getpid()); +@@ -241,8 +231,6 @@ static void __init create_pid_file(void) + errno); + + close(fd); +-out: +- free(file); + } + + int __init set_umid(char *name) +@@ -397,19 +385,13 @@ __uml_setup("uml_dir=", set_uml_dir, + + static void remove_umid_dir(void) + { +- char *dir, err; +- +- dir = malloc(strlen(uml_dir) + UMID_LEN + 1); +- if (!dir) +- return; ++ char dir[strlen(uml_dir) + UMID_LEN + 1], err; + + sprintf(dir, "%s%s", uml_dir, umid); + err = remove_files_and_dir(dir); + if (err) + os_warn("%s - remove_files_and_dir failed with err = %d\n", + __func__, err); +- +- free(dir); + } + + __uml_exitcall(remove_umid_dir); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/Revert-x86-mm-Identify-the-end-of-the-kernel-area-to.patch b/patches/Revert-x86-mm-Identify-the-end-of-the-kernel-area-to.patch new file mode 100644 index 000000000000..8441635ac763 --- /dev/null +++ b/patches/Revert-x86-mm-Identify-the-end-of-the-kernel-area-to.patch @@ -0,0 +1,79 @@ +From d0fa12fa41a25d30ac927fa4ca53aa7b704087b9 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Tue, 23 Jul 2019 14:52:18 +0200 +Subject: Revert "x86/mm: Identify the end of the kernel area + to be reserved" + +This reverts commit c603a309cc75f3dd018ddb20ee44c05047918cbf. + +It breaks the build with clang. + +Signed-off-by: Greg Kroah-Hartman +Change-Id: I2e50915dacfa823c80067f38dc43ef368c24bd2e +--- + arch/x86/include/asm/sections.h | 2 -- + arch/x86/kernel/setup.c | 8 +------- + arch/x86/kernel/vmlinux.lds.S | 9 +-------- + 3 files changed, 2 insertions(+), 17 deletions(-) + +diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h +index 71b32f2570abc..8ea1cfdbeabc1 100644 +--- a/arch/x86/include/asm/sections.h ++++ b/arch/x86/include/asm/sections.h +@@ -13,6 +13,4 @@ extern char __end_rodata_aligned[]; + extern char __end_rodata_hpage_align[]; + #endif + +-extern char __end_of_kernel_reserve[]; +- + #endif /* _ASM_X86_SECTIONS_H */ +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index bbe35bf879f57..dcbdf54fb5c10 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -836,14 +836,8 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) + + void __init setup_arch(char **cmdline_p) + { +- /* +- * Reserve the memory occupied by the kernel between _text and +- * __end_of_kernel_reserve symbols. Any kernel sections after the +- * __end_of_kernel_reserve symbol must be explicitly reserved with a +- * separate memblock_reserve() or they will be discarded. +- */ + memblock_reserve(__pa_symbol(_text), +- (unsigned long)__end_of_kernel_reserve - (unsigned long)_text); ++ (unsigned long)__bss_stop - (unsigned long)_text); + + /* + * Make sure page 0 is always reserved because on systems with +diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S +index e2feacf921a03..4f062d33ef734 100644 +--- a/arch/x86/kernel/vmlinux.lds.S ++++ b/arch/x86/kernel/vmlinux.lds.S +@@ -368,14 +368,6 @@ SECTIONS + __bss_stop = .; + } + +- /* +- * The memory occupied from _text to here, __end_of_kernel_reserve, is +- * automatically reserved in setup_arch(). Anything after here must be +- * explicitly reserved using memblock_reserve() or it will be discarded +- * and treated as available memory. +- */ +- __end_of_kernel_reserve = .; +- + . = ALIGN(PAGE_SIZE); + .brk : AT(ADDR(.brk) - LOAD_OFFSET) { + __brk_base = .; +@@ -415,6 +407,7 @@ SECTIONS + STABS_DEBUG + DWARF_DEBUG + ++ /* Sections to be discarded */ + DISCARDS + /DISCARD/ : { + *(.eh_frame) +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/UPSTREAM-fix-sched-membarrier-Fix-p-mm-membarrier_s.patch b/patches/UPSTREAM-fix-sched-membarrier-Fix-p-mm-membarrier_s.patch new file mode 100644 index 000000000000..6929ee8d80e1 --- /dev/null +++ b/patches/UPSTREAM-fix-sched-membarrier-Fix-p-mm-membarrier_s.patch @@ -0,0 +1,31 @@ +From 935f8bc6f7aa2acf33de46a7aa15ec9a5825f977 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 2 Oct 2019 19:11:32 +0200 +Subject: UPSTREAM: fix "sched/membarrier: Fix + p->mm->membarrier_state racy load" + +Upstream patch fix from this thread: +https://lore.kernel.org/lkml/20191001071921.GJ4519@hirez.programming.kicks-ass.net/ + +Signed-off-by: Greg Kroah-Hartman +Reviewed-by: Joel Fernandes (Google) +Change-Id: Ia54bf5a29eba3c6d36e7a0b32442af7ff09a3998 +--- + kernel/sched/membarrier.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c +index a39bed2c784f..168479a7d61b 100644 +--- a/kernel/sched/membarrier.c ++++ b/kernel/sched/membarrier.c +@@ -174,7 +174,6 @@ static int membarrier_private_expedited(int flags) + */ + if (cpu == raw_smp_processor_id()) + continue; +- rcu_read_lock(); + p = rcu_dereference(cpu_rq(cpu)->curr); + if (p && p->mm == mm) + __cpumask_set_cpu(cpu, tmpmask); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/drivers-qcom-rpmh-rsc-modularize-RSC-controller-driv.patch b/patches/drivers-qcom-rpmh-rsc-modularize-RSC-controller-driv.patch new file mode 100644 index 000000000000..e8ae1b633aba --- /dev/null +++ b/patches/drivers-qcom-rpmh-rsc-modularize-RSC-controller-driv.patch @@ -0,0 +1,61 @@ +From 4b8f8bdfbe40a2045c51ef091751a12ae9fed0a1 Mon Sep 17 00:00:00 2001 +From: Lina Iyer +Date: Thu, 29 Aug 2019 14:27:59 -0600 +Subject: drivers: qcom: rpmh-rsc: modularize RSC controller + driver + +Enable RSC controller driver to be compiled as modules. Since RPMH +communication is need for enabling/disabling critical clocks and busses +needed for the application processor, it is better to keep this module +enabled. Hence declare the driver as a builtin platform driver. + +Signed-off-by: Hridya Valsaraju +Signed-off-by: Lina Iyer + +Change-Id: I5e90b68bbf2c7ed3a2666e0687ff4ade40b9c7a3 +--- + drivers/soc/qcom/Kconfig | 2 +- + drivers/soc/qcom/rpmh-rsc.c | 9 ++++----- + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig +index a6d1bfb17279e..6b0cdba4d7097 100644 +--- a/drivers/soc/qcom/Kconfig ++++ b/drivers/soc/qcom/Kconfig +@@ -102,7 +102,7 @@ config QCOM_RMTFS_MEM + Say y here if you intend to boot the modem remoteproc. + + config QCOM_RPMH +- bool "Qualcomm RPM-Hardened (RPMH) Communication" ++ tristate "Qualcomm Technologies, Inc. RPM-Hardened (RPMH) Communication driver" + depends on ARCH_QCOM && ARM64 || COMPILE_TEST + help + Support for communication with the hardened-RPM blocks in +diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c +index e278fc11fe5cf..d7d9e1b8a4f18 100644 +--- a/drivers/soc/qcom/rpmh-rsc.c ++++ b/drivers/soc/qcom/rpmh-rsc.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -687,9 +688,7 @@ static struct platform_driver rpmh_driver = { + .of_match_table = rpmh_drv_match, + }, + }; ++builtin_platform_driver(rpmh_driver); + +-static int __init rpmh_driver_init(void) +-{ +- return platform_driver_register(&rpmh_driver); +-} +-arch_initcall(rpmh_driver_init); ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMH communication driver"); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/series b/patches/series new file mode 100644 index 000000000000..54a81ec967f6 --- /dev/null +++ b/patches/series @@ -0,0 +1,214 @@ +# +# android-mainline patches +# +# Applies onto mainline 54ecb8f7028c5 Linux 5.4-rc1 +# Matches android-mainline c8e152bc7d05 ANDROID: staging: ion: Fix missing entry in kerneldoc header +# +ANDROID-x86-Remove-a-useless-warning-message.patch +ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-targ.patch +ANDROID-defconfig-build-config-for-cuttlefish.patch +ANDROID-cuttlefish_defconfig-Enable-EAS-related-defi.patch +ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-complian.patch +ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch +ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-opti.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_CMDLINE_E.patch +ANDROID-fs-epoll-use-freezable-blocking-call.patch +ANDROID-mm-add-a-field-to-store-names-for-private-an.patch +ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-.patch +ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-use.patch +ANDROID-usb-gadget-configfs-Add-function-devices-to-.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_UEVENT.patch +ANDROID-usb-gadget-configfs-Add-state-attribute-to-a.patch +ANDROID-usb-gadget-configfs-Add-device-attribute-to-.patch +ANDROID-usb-gadget-f_accessory-Add-Android-Accessory.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_ACC.patch +ANDROID-usb-gadget-f_midi-create-F_midi-device.patch +ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free.patch +ANDROID-usb-gadget-f_audio_source-New-gadget-driver-.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_USB_CONFIGFS_F_AUDIO_SRC.patch +ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functional.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_MMC.patch +ANDROID-uid_cputime-Adds-accounting-for-the-cputimes.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_UID_SYS_S.patch +ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch +ANDROID-taskstats-track-fsync-syscalls.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPUSETS.patch +ANDROID-AVB-error-handler-to-invalidate-vbmeta-parti.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_DM_VERITY.patch +ANDROID-fs-FS-tracepoints-to-track-IO.patch +ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpu.patch +ANDROID-add-extra-free-kbytes-tunable.patch +ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup.patch +ANDROID-netfilter-xt_quota2-adding-the-original-quot.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_NETFILTER.patch +ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-t.patch +ANDROID-security-perf-Allow-further-restriction-of-p.patch +ANDROID-cuttlefish_defconfig-Enable-SECURITY_PERF_EV.patch +ANDROID-net-ipv6-autoconf-routes-into-per-device-tab.patch +ANDROID-binder-add-support-for-RT-prio-inheritance.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_CRYPTO_AD.patch +ANDROID-Move-from-clang-r328903-to-r346389b.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_ARM64_LSE.patch +ANDROID-cuttlefish_defconfig-Enable-VIRT_WIFI.patch +ANDROID-cuttlefish_defconfig-Enable-VIRTIO_INPUT.patch +ANDROID-cuttlefish-enable-CONFIG_NET_CLS_BPF-y.patch +ANDROID-cuttlefish_defconfig-Enable-vsock-options.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_RTC_HCTOS.patch +ANDROID-Turn-xt_owner-module-on.patch +ANDROID-Move-from-clang-r346389b-to-r349610.patch +ANDROID-cuttlefish-enable-CONFIG_NET_SCH_NETEM-y.patch +ANDROID-cuttlefish-enable-CONFIG_NETFILTER_XT_TARGET.patch +ANDROID-cpufreq-track-per-task-time-in-state.patch +ANDROID-cpufreq-times-track-per-uid-time-in-state.patch +ANDROID-proc-Add-proc-uid-directory.patch +ANDROID-cpufreq-Add-time_in_state-to-proc-uid-direct.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_CPU_FREQ_.patch +ANDROID-cpufreq-times-add-proc-uid_concurrent_-activ.patch +ANDROID-cpufreq-times-record-fast-switch-frequency-t.patch +ANDROID-cpufreq-times-optimize-proc-files.patch +ANDROID-cuttlefish_defconfig-Add-support-for-AC97-au.patch +ANDROID-cuttlefish-enable-CONFIG_USB_RTL8152-y.patch +ANDROID-cuttlefish-enable-CONFIG_INET_UDP_DIAG-y.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_PSI.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_INPUT_MOU.patch +ANDROID-dm-bow-Add-dm-bow-feature.patch +ANDROID-Add-dm-bow-to-cuttlefish-configuration.patch +ANDROID-dm-bow-Fix-32-bit-compile-errors.patch +ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-.patch +ANDROID-cuttlefish-enable-CONFIG_NET_SCH_INGRESS-y.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_OVERLAY_F.patch +ANDROID-cuttlefish_defconfig-Enable-CONFIG_FUSE_FS.patch +ANDROID-cuttlefish_defconfig-sync-with-android-mainl-1.patch +ANDROID-gki_defconfig-initial-config-based-on-cuttle.patch +ANDROID-gki_defconfig-Remove-recommended-configs-not.patch +ANDROID-gki_defconfig-Remove-cuttlefish-specific-con.patch +ANDROID-gki_defconfig-common-configs-for-device-DLKM.patch +ANDROID-cuttlefish_defconfig-sync-with-android-mainl-2.patch +ANDROID-Expose-gki_defconfig-to-build.config.patch +ANDROID-Move-from-clang-r349610-to-r353983c.patch +ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVIC.patch +ANDROID-gki_defconfig-sync-with-savedefconfig.patch +ANDROID-gki_defconfig-remove-more-recommended-config.patch +ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch +ANDROID-sync-defconfigs-with-savedefconfig.patch +ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch +ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch +ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch +ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch +ANDROID-Removed-check-for-asm-goto.patch +ANDROID-Add-initial-x86_64-gki_defconfig.patch +ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttl.patch +Enable-CONFIG_ION_SYSTEM_HEAP.patch +ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AR.patch +ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SL.patch +ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDO.patch +ANDROID-gki_defconfig-enable-DMA_CMA.patch +ANDROID-Fixed-x86-regression.patch +ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch +ANDROID-Removed-extraneous-configs-from-gki.patch +ANDROID-gki_defconfig-more-configs-for-partners.patch +ANDROID-gki_defconfig-workaround-to-enable-configs.patch +ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build.patch +ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-wr.patch +ANDROID-gki_defconfig-enable-more-configs.patch +ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch +ANDROID-sdcardfs-Enable-modular-sdcardfs.patch +ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mo.patch +ANDROID-vfs-Add-permission2-for-filesystems-with-per.patch +ANDROID-Add-show_options2-to-view-private-mount-data.patch +ANDROID-vfs-add-d_canonical_path-for-stacked-filesys.patch +ANDROID-fs-Restore-vfs_path_lookup-export.patch +ANDROID-mnt-Add-filesystem-private-data-to-mount-poi.patch +ANDROID-sdcardfs-Define-magic-value.patch +ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch +ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCA.patch +ANDROID-mnt-Fix-null-pointer-dereference.patch +ANDROID-build-configs-switch-prebuilt-path-location.patch +Revert-x86-mm-Identify-the-end-of-the-kernel-area-to.patch +ANDROID-xfrm-remove-in_compat_syscall-checks.patch +ANDROID-Add-initial-rockpi4_defconfig.patch +ANDROID-label-cuttlefish-modules-for-gki.patch +ANDROID-staging-android-ion-Decouple-ION-page-poolin.patch +ANDROID-staging-android-ion-Expose-ion_alloc-to-kern.patch +ANDROID-dma-buf-Add-support-for-partial-cache-mainte.patch +ANDROID-dma-buf-Add-support-for-mapping-buffers-with.patch +ANDROID-dma-buf-Add-support-to-get-flags-associated-.patch +ANDROID-Removed-hardcoded-kernel-command-line-argume.patch +ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch +ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch +Adding-GKI-Ramdisk-to-gki-config.patch +ANDROID-Remove-unused-cuttlefish-build-infra.patch +staging-ion-refactor-ion-s-buffer-manipulators-into-.patch +staging-ion-refactor-ion-s-dmabuf-manipulators-into-.patch +staging-ion-refactor-ion-s-heap-manipulators-into-a-.patch +staging-ion-Move-ion-heaps-into-their-own-directory.patch +staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch +staging-ion-split-system-and-system-contig-heaps.patch +staging-ion-make-system-and-contig-heaps-modular.patch +ANDROID-staging-ion-Build-fix-for-mips.patch +ANDROID-fix-kernelci-build-break.patch +ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch +ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch +Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch +Revert-um-remove-uses-of-variable-length-arrays.patch +ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch +ANDROID-gki_defconfig-Minimally-enable-EFI.patch +ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMA.patch +ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB.patch +ANDROID-refactor-build.config-files-to-remove-duplic.patch +ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-io.patch +ANDROID-staging-ion-reserve-specific-heap-ids-for-kn.patch +ANDROID-staging-ion-add-support-for-consistent-heap-.patch +ANDROID-staging-ion-Fix-uninitialized-variable-warni.patch +ANDROID-staging-ion-Add-support-for-heap-specific-dm.patch +ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch +ANDROID-create-build.configs-for-allmodconfig.patch +ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch +ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch +ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfi.patch +ANDROID-first-pass-cuttlefish-GKI-modularization.patch +drivers-qcom-rpmh-rsc-modularize-RSC-controller-driv.patch +staging-ion-fix-off-by-1-error-in-heap-search.patch +staging-ion-uapi-match-the-existing-heap-type-enums.patch +staging-ion-export-ion_free-for-ion_heaps.patch +ANDROID-cuttlefish-overlayfs-regression.patch +Adding-SERIAL_OF_PLATFORM-module-to-gki.patch +ANDROID-Removed-extraneous-serial-8250-configs.patch +ANDROID-Log-which-device-failed-to-suspend-in-dpm_su.patch +CONFIG_MMC-m.patch +ANDROID-gki_defconfig-enable-CONFIG_UIO.patch +ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch +ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch +ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch +ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch +ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch +ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch +ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch +ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch +ANDROID-net-enable-wireless-core-features-with-GKI_.patch +ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch +ANDROID-update-gki_defconfig-1.patch +ANDROID-update-arm64-gki_defconfig.patch +ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-mo.patch +ANDROID-staging-ion-make-cma-heap-a-module.patch +ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch +ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch +ANDROID-Fix-arm64-allmodconfig-build.patch +ANDROID-update-gki_defconfig-2.patch +UPSTREAM-fix-sched-membarrier-Fix-p-mm-membarrier_s.patch +ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_en.patch +ANDROID-sched-Unconditionally-honor-sync-flag-for-en.patch +ANDROID-sched-fair-add-arch-scaling-function-for-max.patch +ANDROID-cpufreq-arch_topology-implement-max-frequenc.patch +ANDROID-arm64-enable-max-frequency-capping.patch +ANDROID-arm-enable-max-frequency-capping.patch +ANDROID-sched-Update-max-cpu-capacity-in-case-of-max.patch +ANDROID-sched-Prevent-unnecessary-active-balance-of-.patch +ANDROID-sched-fair-Attempt-to-improve-throughput-for.patch +ANDROID-sched-fair-Don-t-balance-misfits-if-it-would.patch +ANDROID-sched-fair-Also-do-misfit-in-overloaded-grou.patch +ANDROID-arm64-defconfig-Enable-EAS-by-default.patch +ANDROID-sched-core-Add-a-latency-sensitive-flag-to-u.patch +ANDROID-sched-Introduce-uclamp-latency-and-boost-wra.patch +ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch +ANDROID-Initial-abi_gki_aarch64-definition.patch diff --git a/patches/staging-ion-Move-ion-heaps-into-their-own-directory.patch b/patches/staging-ion-Move-ion-heaps-into-their-own-directory.patch new file mode 100644 index 000000000000..233f8a3bf1d1 --- /dev/null +++ b/patches/staging-ion-Move-ion-heaps-into-their-own-directory.patch @@ -0,0 +1,139 @@ +From d4e829d1c2917a33db2b2b643c5c7e24115dafb3 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Thu, 8 Aug 2019 08:00:53 -0700 +Subject: staging: ion: Move ion heaps into their own directory + +This is preparatory work for ION heaps to be kernel modules, so +they stay in their own directory inside ION. The heap modules are +planned to be *overridable*, so it makes sense to isolate them +in source to explicitly draw the line between what is a kernel API. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: Iefc4e22d186139832f54b9cfc629383fb6698fc6 +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/Kconfig | 15 +-------------- + drivers/staging/android/ion/Makefile | 5 ++--- + drivers/staging/android/ion/heaps/Kconfig | 15 +++++++++++++++ + drivers/staging/android/ion/heaps/Makefile | 3 +++ + .../android/ion/{ => heaps}/ion_cma_heap.c | 2 +- + .../android/ion/{ => heaps}/ion_page_pool.c | 0 + .../android/ion/{ => heaps}/ion_page_pool.h | 0 + .../android/ion/{ => heaps}/ion_system_heap.c | 2 +- + 8 files changed, 23 insertions(+), 19 deletions(-) + create mode 100644 drivers/staging/android/ion/heaps/Kconfig + create mode 100644 drivers/staging/android/ion/heaps/Makefile + rename drivers/staging/android/ion/{ => heaps}/ion_cma_heap.c (99%) + rename drivers/staging/android/ion/{ => heaps}/ion_page_pool.c (100%) + rename drivers/staging/android/ion/{ => heaps}/ion_page_pool.h (100%) + rename drivers/staging/android/ion/{ => heaps}/ion_system_heap.c (99%) + +diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig +index 989fe84a9f9d7..7b7da979991e4 100644 +--- a/drivers/staging/android/ion/Kconfig ++++ b/drivers/staging/android/ion/Kconfig +@@ -11,17 +11,4 @@ menuconfig ION + If you're not using Android its probably safe to + say N here. + +-config ION_SYSTEM_HEAP +- bool "Ion system heap" +- depends on ION +- help +- Choose this option to enable the Ion system heap. The system heap +- is backed by pages from the buddy allocator. If in doubt, say Y. +- +-config ION_CMA_HEAP +- bool "Ion CMA heap support" +- depends on ION && DMA_CMA +- help +- Choose this option to enable CMA heaps with Ion. This heap is backed +- by the Contiguous Memory Allocator (CMA). If your system has these +- regions, you should say Y here. ++source "drivers/staging/android/ion/heaps/Kconfig" +diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile +index b6fab28167819..1f7704e02fb08 100644 +--- a/drivers/staging/android/ion/Makefile ++++ b/drivers/staging/android/ion/Makefile +@@ -1,4 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o +-obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o +-obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o ++obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o ++obj-y += heaps/ +diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig +new file mode 100644 +index 0000000000000..7affa91ecabbe +--- /dev/null ++++ b/drivers/staging/android/ion/heaps/Kconfig +@@ -0,0 +1,15 @@ ++# SPDX-License-Identifier: GPL-2.0 ++config ION_SYSTEM_HEAP ++ bool "Ion system heap" ++ depends on ION ++ help ++ Choose this option to enable the Ion system heap. The system heap ++ is backed by pages from the buddy allocator. If in doubt, say Y. ++ ++config ION_CMA_HEAP ++ bool "Ion CMA heap support" ++ depends on ION && DMA_CMA ++ help ++ Choose this option to enable CMA heaps with Ion. This heap is backed ++ by the Contiguous Memory Allocator (CMA). If your system has these ++ regions, you should say Y here. +diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile +new file mode 100644 +index 0000000000000..127912629f0b0 +--- /dev/null ++++ b/drivers/staging/android/ion/heaps/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o ++obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o +diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c +similarity index 99% +rename from drivers/staging/android/ion/ion_cma_heap.c +rename to drivers/staging/android/ion/heaps/ion_cma_heap.c +index bf65e67ef9d80..0872e5d630f83 100644 +--- a/drivers/staging/android/ion/ion_cma_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c +@@ -14,7 +14,7 @@ + #include + #include + +-#include "ion.h" ++#include "../ion.h" + + struct ion_cma_heap { + struct ion_heap heap; +diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/heaps/ion_page_pool.c +similarity index 100% +rename from drivers/staging/android/ion/ion_page_pool.c +rename to drivers/staging/android/ion/heaps/ion_page_pool.c +diff --git a/drivers/staging/android/ion/ion_page_pool.h b/drivers/staging/android/ion/heaps/ion_page_pool.h +similarity index 100% +rename from drivers/staging/android/ion/ion_page_pool.h +rename to drivers/staging/android/ion/heaps/ion_page_pool.h +diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c +similarity index 99% +rename from drivers/staging/android/ion/ion_system_heap.c +rename to drivers/staging/android/ion/heaps/ion_system_heap.c +index 66a2b8e8b51ee..f6e20892499fd 100644 +--- a/drivers/staging/android/ion/ion_system_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_system_heap.c +@@ -14,7 +14,7 @@ + #include + #include + +-#include "ion.h" ++#include "../ion.h" + #include "ion_page_pool.h" + + #define NUM_ORDERS ARRAY_SIZE(orders) +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-export-ion_free-for-ion_heaps.patch b/patches/staging-ion-export-ion_free-for-ion_heaps.patch new file mode 100644 index 000000000000..fb22c2710a57 --- /dev/null +++ b/patches/staging-ion-export-ion_free-for-ion_heaps.patch @@ -0,0 +1,63 @@ +From 49d72714132604a0c4070120f6532a0dc6fba391 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Tue, 10 Sep 2019 05:13:51 -0700 +Subject: staging: ion: export ion_free() for ion_heaps. + +ion_free() is a generic function needed to release +an ion buffer back to the heap. So, export it for the +heap module. + +Bug: 140294230 +Test: ion-unit-tests + +Change-Id: Iaa467ab3df18fa219412dd9f5913cd022a93455d +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.c | 1 + + include/linux/ion.h | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index 33f6f8f990398..0f37cbb20e542 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -41,6 +41,7 @@ int ion_free(struct ion_buffer *buffer) + { + return ion_buffer_destroy(internal_dev, buffer); + } ++EXPORT_SYMBOL_GPL(ion_free); + + static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, + unsigned int flags) +diff --git a/include/linux/ion.h b/include/linux/ion.h +index 87aa2bcec7d39..88622fb8f9ea5 100644 +--- a/include/linux/ion.h ++++ b/include/linux/ion.h +@@ -293,6 +293,13 @@ int ion_buffer_zero(struct ion_buffer *buffer); + struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + unsigned int flags); + ++/** ++ * ion_free - Releases the ion buffer. ++ * ++ * @buffer: ion buffer to be released ++ */ ++int ion_free(struct ion_buffer *buffer); ++ + #else + + static inline int __ion_device_add_heap(struct ion_heap *heap, +@@ -357,5 +364,10 @@ static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + return ERR_PTR(-ENOMEM); + } + ++static inline int ion_free(struct ion_buffer *buffer) ++{ ++ return 0; ++} ++ + #endif /* CONFIG_ION */ + #endif /* _ION_KERNEL_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-fix-off-by-1-error-in-heap-search.patch b/patches/staging-ion-fix-off-by-1-error-in-heap-search.patch new file mode 100644 index 000000000000..3e72189ae8ea --- /dev/null +++ b/patches/staging-ion-fix-off-by-1-error-in-heap-search.patch @@ -0,0 +1,42 @@ +From a875875cc78d919ea17317848400c4202a5b9c89 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 9 Sep 2019 08:21:20 -0700 +Subject: staging: ion: fix off-by-1 error in heap search + +ion allocation was wrong because of an off-by-1 error +in heap search for buffer allocation. Fix it. + +Bug: 140507100 +Test: ion-unit-tests + +Change-Id: I6ac5b0ddc6b31b5409645f62a96781d464b7bdf3 +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index 4631953b9c964..33f6f8f990398 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -279,7 +279,7 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) + + if (test_and_set_bit(id_bit - 1, dev->heap_ids)) + return -EEXIST; +- heap->id = id_bit; ++ heap->id = id_bit - 1; + dev->heap_cnt++; + + return 0; +@@ -392,7 +392,7 @@ void ion_device_remove_heap(struct ion_heap *heap) + __func__, heap->name); + } + debugfs_remove_recursive(heap->debugfs_dir); +- clear_bit(heap->id - 1, dev->heap_ids); ++ clear_bit(heap->id, dev->heap_ids); + dev->heap_cnt--; + up_write(&dev->lock); + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-make-system-and-contig-heaps-modular.patch b/patches/staging-ion-make-system-and-contig-heaps-modular.patch new file mode 100644 index 000000000000..0251d04aa5fd --- /dev/null +++ b/patches/staging-ion-make-system-and-contig-heaps-modular.patch @@ -0,0 +1,515 @@ +From 67b22fc45b1ec4b1b6bd4fa8e26a00c365e6d1d6 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 12 Aug 2019 17:23:25 -0700 +Subject: staging: ion: make system and contig heaps modular + +Add symmetric heap add/remove APIs and export symbols from +ion core that are needed to make both heaps modular. + +Bug: 133508579 +Test: ion-unit-test, rmmod, modprobe + +Change-Id: Ic5f40936531936c9bfab48ea147108c019d28e2c +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/heaps/Kconfig | 4 +- + drivers/staging/android/ion/heaps/Makefile | 4 +- + .../ion/heaps/ion_system_contig_heap.c | 36 ++++------ + .../android/ion/heaps/ion_system_heap.c | 67 +++++++++---------- + drivers/staging/android/ion/ion.c | 54 ++++++++++++--- + drivers/staging/android/ion/ion_buffer.c | 13 ++++ + drivers/staging/android/ion/ion_heap.c | 39 ++++++++++- + drivers/staging/android/ion/ion_private.h | 3 + + include/linux/ion.h | 24 ++++++- + 9 files changed, 169 insertions(+), 75 deletions(-) + +diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig +index f1c7a6b79c014..af6fce69e61a1 100644 +--- a/drivers/staging/android/ion/heaps/Kconfig ++++ b/drivers/staging/android/ion/heaps/Kconfig +@@ -1,13 +1,13 @@ + # SPDX-License-Identifier: GPL-2.0 + config ION_SYSTEM_HEAP +- bool "Ion system heap" ++ tristate "Ion system heap" + depends on ION + help + Choose this option to enable the Ion system heap. The system heap + is backed by pages from the buddy allocator. If in doubt, say Y. + + config ION_SYSTEM_CONTIG_HEAP +- bool "Ion system contig heap" ++ tristate "Ion system contig heap" + depends on ION + help + Choose this option to enable Ion system contig heap. The system contig heap +diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile +index e2ee931100d0b..4498790358779 100644 +--- a/drivers/staging/android/ion/heaps/Makefile ++++ b/drivers/staging/android/ion/heaps/Makefile +@@ -1,4 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o ++obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_sys_heap.o ++ion_sys_heap-y := ion_system_heap.o ion_page_pool.o ++ + obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o + obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o +diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +index 3a07ef931c2ee..9cb18e38dc96e 100644 +--- a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -81,31 +82,22 @@ static struct ion_heap_ops kmalloc_ops = { + .map_user = ion_heap_map_user, + }; + +-static struct ion_heap *__ion_system_contig_heap_create(void) +-{ +- struct ion_heap *heap; +- +- heap = kzalloc(sizeof(*heap), GFP_KERNEL); +- if (!heap) +- return ERR_PTR(-ENOMEM); +- heap->ops = &kmalloc_ops; +- heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; +- heap->name = "ion_system_contig_heap"; ++static struct ion_heap contig_heap = { ++ .ops = &kmalloc_ops, ++ .type = ION_HEAP_TYPE_SYSTEM_CONTIG, ++ .name = "ion_system_contig_heap", ++}; + +- return heap; ++static int __init ion_system_contig_heap_init(void) ++{ ++ return ion_device_add_heap(&contig_heap); + } + +-static int ion_system_contig_heap_create(void) ++static void __exit ion_system_contig_heap_exit(void) + { +- struct ion_heap *heap; +- +- heap = __ion_system_contig_heap_create(); +- if (IS_ERR(heap)) +- return PTR_ERR(heap); +- +- ion_device_add_heap(heap); +- +- return 0; ++ ion_device_remove_heap(&contig_heap); + } +-device_initcall(ion_system_contig_heap_create); + ++module_init(ion_system_contig_heap_init); ++module_exit(ion_system_contig_heap_exit); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c +index df4f5010fa820..e3d5129920c6d 100644 +--- a/drivers/staging/android/ion/heaps/ion_system_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_system_heap.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -204,15 +205,6 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, + return nr_total; + } + +-static struct ion_heap_ops system_heap_ops = { +- .allocate = ion_system_heap_allocate, +- .free = ion_system_heap_free, +- .map_kernel = ion_heap_map_kernel, +- .unmap_kernel = ion_heap_unmap_kernel, +- .map_user = ion_heap_map_user, +- .shrink = ion_system_heap_shrink, +-}; +- + static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) + { + int i; +@@ -246,38 +238,39 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools) + return -ENOMEM; + } + +-static struct ion_heap *__ion_system_heap_create(void) +-{ +- struct ion_system_heap *heap; +- +- heap = kzalloc(sizeof(*heap), GFP_KERNEL); +- if (!heap) +- return ERR_PTR(-ENOMEM); +- heap->heap.ops = &system_heap_ops; +- heap->heap.type = ION_HEAP_TYPE_SYSTEM; +- heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; ++static struct ion_heap_ops system_heap_ops = { ++ .allocate = ion_system_heap_allocate, ++ .free = ion_system_heap_free, ++ .map_kernel = ion_heap_map_kernel, ++ .unmap_kernel = ion_heap_unmap_kernel, ++ .map_user = ion_heap_map_user, ++ .shrink = ion_system_heap_shrink, ++}; + +- if (ion_system_heap_create_pools(heap->pools)) +- goto free_heap; ++struct ion_system_heap system_heap = { ++ .heap = { ++ .ops = &system_heap_ops, ++ .type = ION_HEAP_TYPE_SYSTEM, ++ .flags = ION_HEAP_FLAG_DEFER_FREE, ++ .name = "ion_system_heap", ++ } ++}; + +- return &heap->heap; ++static int __init ion_system_heap_init(void) ++{ ++ int ret = ion_system_heap_create_pools(system_heap.pools); ++ if (ret) ++ return ret; + +-free_heap: +- kfree(heap); +- return ERR_PTR(-ENOMEM); ++ return ion_device_add_heap(&system_heap.heap); + } + +-static int ion_system_heap_create(void) ++static void __exit ion_system_heap_exit(void) + { +- struct ion_heap *heap; +- +- heap = __ion_system_heap_create(); +- if (IS_ERR(heap)) +- return PTR_ERR(heap); +- heap->name = "ion_system_heap"; +- +- ion_device_add_heap(heap); +- +- return 0; ++ ion_device_remove_heap(&system_heap.heap); ++ ion_system_heap_destroy_pools(system_heap.pools); + } +-device_initcall(ion_system_heap_create); ++ ++module_init(ion_system_heap_init); ++module_exit(ion_system_heap_exit); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index 6a9f01ec4aed3..e4586eb6cae34 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -222,28 +222,36 @@ static int debug_shrink_get(void *data, u64 *val) + DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, + debug_shrink_set, "%llu\n"); + +-void ion_device_add_heap(struct ion_heap *heap) ++int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) + { + struct ion_device *dev = internal_dev; + int ret; + struct dentry *heap_root; + char debug_name[64]; + +- if (!heap->ops->allocate || !heap->ops->free) +- pr_err("%s: can not add heap with invalid ops struct.\n", +- __func__); ++ if (!heap || !heap->ops || !heap->ops->allocate || !heap->ops->free) { ++ pr_err("%s: invalid heap or heap_ops\n", __func__); ++ ret = -EINVAL; ++ goto out; ++ } + ++ heap->owner = owner; + spin_lock_init(&heap->free_lock); + spin_lock_init(&heap->stat_lock); + heap->free_list_size = 0; + +- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) +- ion_heap_init_deferred_free(heap); ++ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) { ++ ret = ion_heap_init_deferred_free(heap); ++ if (ret) ++ goto out_heap_cleanup; ++ } + + if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) { + ret = ion_heap_init_shrinker(heap); +- if (ret) ++ if (ret) { + pr_err("%s: Failed to register shrinker\n", __func__); ++ goto out_heap_cleanup; ++ } + } + + heap->num_of_buffers = 0; +@@ -273,6 +281,7 @@ void ion_device_add_heap(struct ion_heap *heap) + &debug_shrink_fops); + } + ++ heap->debugfs_dir = heap_root; + down_write(&dev->lock); + heap->id = heap_id++; + /* +@@ -284,8 +293,37 @@ void ion_device_add_heap(struct ion_heap *heap) + + dev->heap_cnt++; + up_write(&dev->lock); ++ ++ return 0; ++ ++out_heap_cleanup: ++ ion_heap_cleanup(heap); ++out: ++ return ret; ++} ++EXPORT_SYMBOL_GPL(__ion_device_add_heap); ++ ++void ion_device_remove_heap(struct ion_heap *heap) ++{ ++ struct ion_device *dev = internal_dev; ++ ++ if (!heap) { ++ pr_err("%s: Invalid argument\n", __func__); ++ return; ++ } ++ ++ // take semaphore and remove the heap from dev->heap list ++ down_write(&dev->lock); ++ /* So no new allocations can happen from this heap */ ++ plist_del(&heap->node, &dev->heaps); ++ if (ion_heap_cleanup(heap) != 0) { ++ pr_warn("%s: failed to cleanup heap (%s)\n", ++ __func__, heap->name); ++ } ++ debugfs_remove_recursive(heap->debugfs_dir); ++ up_write(&dev->lock); + } +-EXPORT_SYMBOL(ion_device_add_heap); ++EXPORT_SYMBOL(ion_device_remove_heap); + + static int ion_device_create(void) + { +diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c +index adce2d489f56e..879b3ddb08c0f 100644 +--- a/drivers/staging/android/ion/ion_buffer.c ++++ b/drivers/staging/android/ion/ion_buffer.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + + #include "ion_private.h" +@@ -76,6 +77,14 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, + heap->num_of_alloc_bytes += len; + if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) + heap->alloc_bytes_wm = heap->num_of_alloc_bytes; ++ if (heap->num_of_buffers == 1) { ++ /* This module reference lasts as long as at least one ++ * buffer is allocated from the heap. We are protected ++ * against ion_device_remove_heap() with dev->lock, so we can ++ * safely assume the module reference is going to* succeed. ++ */ ++ __module_get(heap->owner); ++ } + spin_unlock(&heap->stat_lock); + + INIT_LIST_HEAD(&buffer->attachments); +@@ -184,6 +193,7 @@ int ion_buffer_zero(struct ion_buffer *buffer) + + return ion_sglist_zero(table->sgl, table->nents, pgprot); + } ++EXPORT_SYMBOL_GPL(ion_buffer_zero); + + void ion_buffer_release(struct ion_buffer *buffer) + { +@@ -196,7 +206,10 @@ void ion_buffer_release(struct ion_buffer *buffer) + spin_lock(&buffer->heap->stat_lock); + buffer->heap->num_of_buffers--; + buffer->heap->num_of_alloc_bytes -= buffer->size; ++ if (buffer->heap->num_of_buffers == 0) ++ module_put(buffer->heap->owner); + spin_unlock(&buffer->heap->stat_lock); ++ /* drop reference to the heap module */ + + kfree(buffer); + } +diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c +index 755548a4382d2..e102f6a2ecf65 100644 +--- a/drivers/staging/android/ion/ion_heap.c ++++ b/drivers/staging/android/ion/ion_heap.c +@@ -101,12 +101,15 @@ static int ion_heap_deferred_free(void *data) + struct ion_buffer *buffer; + + wait_event_freezable(heap->waitqueue, +- ion_heap_freelist_size(heap) > 0); ++ (ion_heap_freelist_size(heap) > 0 || ++ kthread_should_stop())); + + spin_lock(&heap->free_lock); + if (list_empty(&heap->free_list)) { + spin_unlock(&heap->free_lock); +- continue; ++ if (!kthread_should_stop()) ++ continue; ++ break; + } + buffer = list_first_entry(&heap->free_list, struct ion_buffer, + list); +@@ -156,12 +159,14 @@ void *ion_heap_map_kernel(struct ion_heap *heap, + + return vaddr; + } ++EXPORT_SYMBOL_GPL(ion_heap_map_kernel); + + void ion_heap_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) + { + vunmap(buffer->vaddr); + } ++EXPORT_SYMBOL_GPL(ion_heap_unmap_kernel); + + int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + struct vm_area_struct *vma) +@@ -198,6 +203,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + + return 0; + } ++EXPORT_SYMBOL_GPL(ion_heap_map_user); + + void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) + { +@@ -256,3 +262,32 @@ int ion_heap_init_shrinker(struct ion_heap *heap) + + return register_shrinker(&heap->shrinker); + } ++ ++int ion_heap_cleanup(struct ion_heap *heap) ++{ ++ int ret; ++ ++ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE && ++ !IS_ERR_OR_NULL(heap->task)) { ++ size_t free_list_size = ion_heap_freelist_size(heap); ++ size_t total_drained = ion_heap_freelist_drain(heap, 0); ++ ++ if (total_drained != free_list_size) { ++ pr_err("%s: %s heap drained %zu bytes, requested %zu\n", ++ __func__, heap->name, free_list_size, ++ total_drained); ++ return -EBUSY; ++ } ++ ret = kthread_stop(heap->task); ++ if (ret < 0) { ++ pr_err("%s: failed to stop heap free thread\n", ++ __func__); ++ return ret; ++ } ++ } ++ ++ if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) ++ unregister_shrinker(&heap->shrinker); ++ ++ return 0; ++} +diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h +index ed7ed39d0df1e..5cc09fbfbefe2 100644 +--- a/drivers/staging/android/ion/ion_private.h ++++ b/drivers/staging/android/ion/ion_private.h +@@ -51,4 +51,7 @@ extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, + unsigned int flags); + extern int ion_free(struct ion_buffer *buffer); + ++/* ion heap helpers */ ++extern int ion_heap_cleanup(struct ion_heap *heap); ++ + #endif /* _ION_PRIVATE_H */ +diff --git a/include/linux/ion.h b/include/linux/ion.h +index 775e948a362c8..fe0d2cb1ef252 100644 +--- a/include/linux/ion.h ++++ b/include/linux/ion.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -105,6 +106,7 @@ struct ion_heap_ops { + * allocating. These are specified by platform data and + * MUST be unique + * @name: used for debugging ++ * @owner: kernel module that implements this heap + * @shrinker: a shrinker for the heap + * @free_list: free list head if deferred free is used + * @free_list_size size of the deferred free list in bytes +@@ -127,6 +129,7 @@ struct ion_heap { + unsigned long flags; + unsigned int id; + const char *name; ++ struct module *owner; + + /* deferred free support */ + struct shrinker shrinker; +@@ -143,16 +146,30 @@ struct ion_heap { + + /* protect heap statistics */ + spinlock_t stat_lock; ++ ++ /* heap's debugfs root */ ++ struct dentry *debugfs_dir; + }; + ++#define ion_device_add_heap(heap) __ion_device_add_heap(heap, THIS_MODULE) ++ + #ifdef CONFIG_ION + + /** +- * ion_device_add_heap - adds a heap to the ion device ++ * __ion_device_add_heap - adds a heap to the ion device + * + * @heap: the heap to add ++ * ++ * Returns 0 on success, negative error otherwise. ++ */ ++int __ion_device_add_heap(struct ion_heap *heap, struct module *owner); ++ ++/** ++ * ion_device_remove_heap - removes a heap from ion device ++ * ++ * @heap: pointer to the heap to be removed + */ +-void ion_device_add_heap(struct ion_heap *heap); ++void ion_device_remove_heap(struct ion_heap *heap); + + /** + * ion_heap_init_shrinker +@@ -283,7 +300,8 @@ struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + + #else + +-static inline int ion_device_add_heap(struct ion_heap *heap) ++static inline int __ion_device_add_heap(struct ion_heap *heap, ++ struct module *owner) + { + return -ENODEV; + } +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-refactor-ion-s-buffer-manipulators-into-.patch b/patches/staging-ion-refactor-ion-s-buffer-manipulators-into-.patch new file mode 100644 index 000000000000..2d1f208362ae --- /dev/null +++ b/patches/staging-ion-refactor-ion-s-buffer-manipulators-into-.patch @@ -0,0 +1,550 @@ +From a71f82c15a41dd1e3ca3dfe75aa896956a35e5c4 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Wed, 7 Aug 2019 12:12:47 -0700 +Subject: staging: ion: refactor ion's buffer manipulators into + a separate file. + +This patch is preparatory work for making ion heaps modular. The patch +itself doesn't make any significant changes except for re-organizing the +buffer manipulator functions in a single file. This will be helpful +later when we specifically export some of these functions to be used by +a heap module. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: I7438bd529a3e9c7a90910979e26bd754a8292e9a +Co-developed-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/Makefile | 2 +- + drivers/staging/android/ion/ion.c | 177 +------------------ + drivers/staging/android/ion/ion.h | 21 --- + drivers/staging/android/ion/ion_buffer.c | 198 ++++++++++++++++++++++ + drivers/staging/android/ion/ion_heap.c | 6 +- + drivers/staging/android/ion/ion_private.h | 47 +++++ + 6 files changed, 254 insertions(+), 197 deletions(-) + create mode 100644 drivers/staging/android/ion/ion_buffer.c + create mode 100644 drivers/staging/android/ion/ion_private.h + +Index: common/drivers/staging/android/ion/Makefile +=================================================================== +--- common.orig/drivers/staging/android/ion/Makefile ++++ common/drivers/staging/android/ion/Makefile +@@ -1,4 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_ION) += ion.o ion_heap.o ++obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_heap.o + obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o + obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o +Index: common/drivers/staging/android/ion/ion.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion.c ++++ common/drivers/staging/android/ion/ion.c +@@ -26,119 +26,11 @@ + #include + #include + +-#include "ion.h" ++#include "ion_private.h" + + static struct ion_device *internal_dev; + static int heap_id; + +-/* this function should only be called while dev->lock is held */ +-static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, +- struct ion_device *dev, +- unsigned long len, +- unsigned long flags) +-{ +- struct ion_buffer *buffer; +- int ret; +- +- buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); +- if (!buffer) +- return ERR_PTR(-ENOMEM); +- +- buffer->heap = heap; +- buffer->flags = flags; +- buffer->dev = dev; +- buffer->size = len; +- +- ret = heap->ops->allocate(heap, buffer, len, flags); +- +- if (ret) { +- if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) +- goto err2; +- +- ion_heap_freelist_drain(heap, 0); +- ret = heap->ops->allocate(heap, buffer, len, flags); +- if (ret) +- goto err2; +- } +- +- if (!buffer->sg_table) { +- WARN_ONCE(1, "This heap needs to set the sgtable"); +- ret = -EINVAL; +- goto err1; +- } +- +- spin_lock(&heap->stat_lock); +- heap->num_of_buffers++; +- heap->num_of_alloc_bytes += len; +- if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) +- heap->alloc_bytes_wm = heap->num_of_alloc_bytes; +- spin_unlock(&heap->stat_lock); +- +- INIT_LIST_HEAD(&buffer->attachments); +- mutex_init(&buffer->lock); +- return buffer; +- +-err1: +- heap->ops->free(buffer); +-err2: +- kfree(buffer); +- return ERR_PTR(ret); +-} +- +-void ion_buffer_destroy(struct ion_buffer *buffer) +-{ +- if (buffer->kmap_cnt > 0) { +- pr_warn_once("%s: buffer still mapped in the kernel\n", +- __func__); +- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); +- } +- buffer->heap->ops->free(buffer); +- spin_lock(&buffer->heap->stat_lock); +- buffer->heap->num_of_buffers--; +- buffer->heap->num_of_alloc_bytes -= buffer->size; +- spin_unlock(&buffer->heap->stat_lock); +- +- kfree(buffer); +-} +- +-static void _ion_buffer_destroy(struct ion_buffer *buffer) +-{ +- struct ion_heap *heap = buffer->heap; +- +- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) +- ion_heap_freelist_add(heap, buffer); +- else +- ion_buffer_destroy(buffer); +-} +- +-static void *ion_buffer_kmap_get(struct ion_buffer *buffer) +-{ +- void *vaddr; +- +- if (buffer->kmap_cnt) { +- buffer->kmap_cnt++; +- return buffer->vaddr; +- } +- vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); +- if (WARN_ONCE(!vaddr, +- "heap->ops->map_kernel should return ERR_PTR on error")) +- return ERR_PTR(-EINVAL); +- if (IS_ERR(vaddr)) +- return vaddr; +- buffer->vaddr = vaddr; +- buffer->kmap_cnt++; +- return vaddr; +-} +- +-static void ion_buffer_kmap_put(struct ion_buffer *buffer) +-{ +- buffer->kmap_cnt--; +- if (!buffer->kmap_cnt) { +- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); +- buffer->vaddr = NULL; +- } +-} +- + static struct sg_table *dup_sg_table(struct sg_table *table) + { + struct sg_table *new_table; +@@ -273,7 +165,7 @@ static void ion_dma_buf_release(struct d + { + struct ion_buffer *buffer = dmabuf->priv; + +- _ion_buffer_destroy(buffer); ++ ion_buffer_destroy(internal_dev, buffer); + } + + static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) +@@ -358,39 +250,14 @@ static const struct dma_buf_ops dma_buf_ + static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, + unsigned int flags) + { +- struct ion_device *dev = internal_dev; +- struct ion_buffer *buffer = NULL; +- struct ion_heap *heap; ++ struct ion_buffer *buffer; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct dma_buf *dmabuf; + + pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, + len, heap_id_mask, flags); +- /* +- * traverse the list of heaps available in this system in priority +- * order. If the heap type is supported by the client, and matches the +- * request of the caller allocate from it. Repeat until allocate has +- * succeeded or all heaps have been tried +- */ +- len = PAGE_ALIGN(len); +- +- if (!len) +- return ERR_PTR(-EINVAL); +- +- down_read(&dev->lock); +- plist_for_each_entry(heap, &dev->heaps, node) { +- /* if the caller didn't specify this heap id */ +- if (!((1 << heap->id) & heap_id_mask)) +- continue; +- buffer = ion_buffer_create(heap, dev, len, flags); +- if (!IS_ERR(buffer)) +- break; +- } +- up_read(&dev->lock); +- +- if (!buffer) +- return ERR_PTR(-ENODEV); + ++ buffer = ion_buffer_alloc(internal_dev, len, heap_id_mask, flags); + if (IS_ERR(buffer)) + return ERR_CAST(buffer); + +@@ -401,7 +268,7 @@ static struct dma_buf *ion_alloc_dmabuf( + + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) +- _ion_buffer_destroy(buffer); ++ ion_buffer_destroy(internal_dev, buffer); + + return dmabuf; + } +Index: common/drivers/staging/android/ion/ion.h +=================================================================== +--- common.orig/drivers/staging/android/ion/ion.h ++++ common/drivers/staging/android/ion/ion.h +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + + #include "../uapi/ion.h" + +@@ -39,7 +38,6 @@ + */ + struct ion_buffer { + struct list_head list; +- struct ion_device *dev; + struct ion_heap *heap; + unsigned long flags; + unsigned long private_flags; +@@ -55,19 +53,6 @@ struct ion_buffer { + void ion_buffer_destroy(struct ion_buffer *buffer); + + /** +- * struct ion_device - the metadata of the ion device node +- * @dev: the actual misc device +- * @lock: rwsem protecting the tree of heaps and clients +- */ +-struct ion_device { +- struct miscdevice dev; +- struct rw_semaphore lock; +- struct plist_head heaps; +- struct dentry *debug_root; +- int heap_cnt; +-}; +- +-/** + * struct ion_heap_ops - ops to operate on a given heap + * @allocate: allocate memory + * @free: free memory +Index: common/drivers/staging/android/ion/ion_buffer.c +=================================================================== +--- /dev/null ++++ common/drivers/staging/android/ion/ion_buffer.c +@@ -0,0 +1,198 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * ION Memory Allocator - buffer interface ++ * ++ * Copyright (c) 2019, Google, Inc. ++ */ ++ ++#include ++#include ++ ++#include "ion_private.h" ++ ++/* this function should only be called while dev->lock is held */ ++static void ion_buffer_add(struct ion_device *dev, ++ struct ion_buffer *buffer) ++{ ++ struct rb_node **p = &dev->buffers.rb_node; ++ struct rb_node *parent = NULL; ++ struct ion_buffer *entry; ++ ++ while (*p) { ++ parent = *p; ++ entry = rb_entry(parent, struct ion_buffer, node); ++ ++ if (buffer < entry) { ++ p = &(*p)->rb_left; ++ } else if (buffer > entry) { ++ p = &(*p)->rb_right; ++ } else { ++ pr_err("%s: buffer already found.", __func__); ++ BUG(); ++ } ++ } ++ ++ rb_link_node(&buffer->node, parent, p); ++ rb_insert_color(&buffer->node, &dev->buffers); ++} ++ ++/* this function should only be called while dev->lock is held */ ++static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, ++ struct ion_device *dev, ++ unsigned long len, ++ unsigned long flags) ++{ ++ struct ion_buffer *buffer; ++ int ret; ++ ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (!buffer) ++ return ERR_PTR(-ENOMEM); ++ ++ buffer->heap = heap; ++ buffer->flags = flags; ++ buffer->size = len; ++ ++ ret = heap->ops->allocate(heap, buffer, len, flags); ++ ++ if (ret) { ++ if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) ++ goto err2; ++ ++ ion_heap_freelist_drain(heap, 0); ++ ret = heap->ops->allocate(heap, buffer, len, flags); ++ if (ret) ++ goto err2; ++ } ++ ++ if (!buffer->sg_table) { ++ WARN_ONCE(1, "This heap needs to set the sgtable"); ++ ret = -EINVAL; ++ goto err1; ++ } ++ ++ spin_lock(&heap->stat_lock); ++ heap->num_of_buffers++; ++ heap->num_of_alloc_bytes += len; ++ if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) ++ heap->alloc_bytes_wm = heap->num_of_alloc_bytes; ++ spin_unlock(&heap->stat_lock); ++ ++ INIT_LIST_HEAD(&buffer->attachments); ++ mutex_init(&buffer->lock); ++ mutex_lock(&dev->buffer_lock); ++ ion_buffer_add(dev, buffer); ++ mutex_unlock(&dev->buffer_lock); ++ return buffer; ++ ++err1: ++ heap->ops->free(buffer); ++err2: ++ kfree(buffer); ++ return ERR_PTR(ret); ++} ++ ++struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, ++ unsigned int heap_id_mask, ++ unsigned int flags) ++{ ++ struct ion_buffer *buffer = NULL; ++ struct ion_heap *heap; ++ ++ if (!dev || !len) { ++ return ERR_PTR(-EINVAL); ++ } ++ ++ /* ++ * traverse the list of heaps available in this system in priority ++ * order. If the heap type is supported by the client, and matches the ++ * request of the caller allocate from it. Repeat until allocate has ++ * succeeded or all heaps have been tried ++ */ ++ len = PAGE_ALIGN(len); ++ if (!len) ++ return ERR_PTR(-EINVAL); ++ ++ down_read(&dev->lock); ++ plist_for_each_entry(heap, &dev->heaps, node) { ++ /* if the caller didn't specify this heap id */ ++ if (!((1 << heap->id) & heap_id_mask)) ++ continue; ++ buffer = ion_buffer_create(heap, dev, len, flags); ++ if (!IS_ERR(buffer)) ++ break; ++ } ++ up_read(&dev->lock); ++ ++ if (!buffer) ++ return ERR_PTR(-ENODEV); ++ ++ if (IS_ERR(buffer)) ++ return ERR_CAST(buffer); ++ ++ return buffer; ++} ++ ++void ion_buffer_release(struct ion_buffer *buffer) ++{ ++ if (buffer->kmap_cnt > 0) { ++ pr_warn_once("%s: buffer still mapped in the kernel\n", ++ __func__); ++ buffer->heap->ops->unmap_kernel(buffer->heap, buffer); ++ } ++ buffer->heap->ops->free(buffer); ++ spin_lock(&buffer->heap->stat_lock); ++ buffer->heap->num_of_buffers--; ++ buffer->heap->num_of_alloc_bytes -= buffer->size; ++ spin_unlock(&buffer->heap->stat_lock); ++ ++ kfree(buffer); ++} ++ ++void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) ++{ ++ struct ion_heap *heap; ++ ++ if (!dev || !buffer) { ++ pr_warn("%s: invalid argument\n", __func__); ++ return; ++ } ++ ++ heap = buffer->heap; ++ mutex_lock(&dev->buffer_lock); ++ rb_erase(&buffer->node, &dev->buffers); ++ mutex_unlock(&dev->buffer_lock); ++ ++ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ++ ion_heap_freelist_add(heap, buffer); ++ else ++ ion_buffer_release(buffer); ++} ++ ++void *ion_buffer_kmap_get(struct ion_buffer *buffer) ++{ ++ void *vaddr; ++ ++ if (buffer->kmap_cnt) { ++ buffer->kmap_cnt++; ++ return buffer->vaddr; ++ } ++ vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); ++ if (WARN_ONCE(!vaddr, ++ "heap->ops->map_kernel should return ERR_PTR on error")) ++ return ERR_PTR(-EINVAL); ++ if (IS_ERR(vaddr)) ++ return vaddr; ++ buffer->vaddr = vaddr; ++ buffer->kmap_cnt++; ++ return vaddr; ++} ++ ++void ion_buffer_kmap_put(struct ion_buffer *buffer) ++{ ++ buffer->kmap_cnt--; ++ if (!buffer->kmap_cnt) { ++ buffer->heap->ops->unmap_kernel(buffer->heap, buffer); ++ buffer->vaddr = NULL; ++ } ++} +Index: common/drivers/staging/android/ion/ion_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_heap.c ++++ common/drivers/staging/android/ion/ion_heap.c +@@ -15,7 +15,7 @@ + #include + #include + +-#include "ion.h" ++#include "ion_private.h" + + void *ion_heap_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +@@ -198,7 +198,7 @@ static size_t _ion_heap_freelist_drain(s + buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; + total_drained += buffer->size; + spin_unlock(&heap->free_lock); +- ion_buffer_destroy(buffer); ++ ion_buffer_release(buffer); + spin_lock(&heap->free_lock); + } + spin_unlock(&heap->free_lock); +@@ -236,7 +236,7 @@ static int ion_heap_deferred_free(void * + list_del(&buffer->list); + heap->free_list_size -= buffer->size; + spin_unlock(&heap->free_lock); +- ion_buffer_destroy(buffer); ++ ion_buffer_release(buffer); + } + + return 0; +Index: common/drivers/staging/android/ion/ion_private.h +=================================================================== +--- /dev/null ++++ common/drivers/staging/android/ion/ion_private.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * ION Memory Allocator - Internal header ++ * ++ * Copyright (C) 2019 Google, Inc. ++ */ ++ ++#ifndef _ION_PRIVATE_H ++#define _ION_PRIVATE_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ion.h" ++ ++/** ++ * struct ion_device - the metadata of the ion device node ++ * @dev: the actual misc device ++ * @buffers: an rb tree of all the existing buffers ++ * @buffer_lock: lock protecting the tree of buffers ++ * @lock: rwsem protecting the tree of heaps and clients ++ */ ++struct ion_device { ++ struct miscdevice dev; ++ struct rb_root buffers; ++ struct mutex buffer_lock; ++ struct rw_semaphore lock; ++ struct plist_head heaps; ++ struct dentry *debug_root; ++ int heap_cnt; ++}; ++ ++/* ion_buffer manipulators */ ++extern struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, ++ unsigned int heap_id_mask, ++ unsigned int flags); ++extern void ion_buffer_release(struct ion_buffer *buffer); ++extern void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer); ++extern void *ion_buffer_kmap_get(struct ion_buffer *buffer); ++extern void ion_buffer_kmap_put(struct ion_buffer *buffer); ++ ++#endif /* _ION_PRIVATE_H */ diff --git a/patches/staging-ion-refactor-ion-s-dmabuf-manipulators-into-.patch b/patches/staging-ion-refactor-ion-s-dmabuf-manipulators-into-.patch new file mode 100644 index 000000000000..f64ced3e9949 --- /dev/null +++ b/patches/staging-ion-refactor-ion-s-dmabuf-manipulators-into-.patch @@ -0,0 +1,680 @@ +From b8550c6a14ad2988f0080db5d6ba9d76800e5657 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Wed, 7 Aug 2019 15:01:24 -0700 +Subject: staging: ion: refactor ion's dmabuf manipulators into + a separate file. + +This patch is preparatory work for making ion heaps modular. The patch +itself doesn't make any significant changes except for re-organizing the +buffer manipulator functions in a single file. This will be helpful +later when we specifically export some of these functions to be used by +a heap module. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: I52ecea78a179c936006a21beb7630009984cb22f +Co-developed-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/Makefile | 2 +- + drivers/staging/android/ion/ion.c | 254 +--------------------- + drivers/staging/android/ion/ion_buffer.c | 6 +- + drivers/staging/android/ion/ion_dma_buf.c | 252 +++++++++++++++++++++ + drivers/staging/android/ion/ion_private.h | 11 +- + include/linux/ion.h | 16 +- + 6 files changed, 289 insertions(+), 252 deletions(-) + create mode 100644 drivers/staging/android/ion/ion_dma_buf.c + +diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile +index da386dbf3ffd8..b6fab28167819 100644 +--- a/drivers/staging/android/ion/Makefile ++++ b/drivers/staging/android/ion/Makefile +@@ -1,4 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_heap.o ++obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o + obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o + obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o +diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c +index ef7c59269d3a3..0f5884f37411b 100644 +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -17,276 +17,38 @@ + #include + #include + #include +-#include + #include + #include + #include + #include + #include + #include +-#include + + #include "ion_private.h" + + static struct ion_device *internal_dev; + static int heap_id; + +-static struct sg_table *dup_sg_table(struct sg_table *table) +-{ +- struct sg_table *new_table; +- int ret, i; +- struct scatterlist *sg, *new_sg; +- +- new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); +- if (!new_table) +- return ERR_PTR(-ENOMEM); +- +- ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); +- if (ret) { +- kfree(new_table); +- return ERR_PTR(-ENOMEM); +- } +- +- new_sg = new_table->sgl; +- for_each_sg(table->sgl, sg, table->nents, i) { +- memcpy(new_sg, sg, sizeof(*sg)); +- new_sg->dma_address = 0; +- new_sg = sg_next(new_sg); +- } +- +- return new_table; +-} +- +-static void free_duped_table(struct sg_table *table) +-{ +- sg_free_table(table); +- kfree(table); +-} +- +-struct ion_dma_buf_attachment { +- struct device *dev; +- struct sg_table *table; +- struct list_head list; +-}; +- +-static int ion_dma_buf_attach(struct dma_buf *dmabuf, +- struct dma_buf_attachment *attachment) +-{ +- struct ion_dma_buf_attachment *a; +- struct sg_table *table; +- struct ion_buffer *buffer = dmabuf->priv; +- +- a = kzalloc(sizeof(*a), GFP_KERNEL); +- if (!a) +- return -ENOMEM; +- +- table = dup_sg_table(buffer->sg_table); +- if (IS_ERR(table)) { +- kfree(a); +- return -ENOMEM; +- } +- +- a->table = table; +- a->dev = attachment->dev; +- INIT_LIST_HEAD(&a->list); +- +- attachment->priv = a; +- +- mutex_lock(&buffer->lock); +- list_add(&a->list, &buffer->attachments); +- mutex_unlock(&buffer->lock); +- +- return 0; +-} +- +-static void ion_dma_buf_detatch(struct dma_buf *dmabuf, +- struct dma_buf_attachment *attachment) +-{ +- struct ion_dma_buf_attachment *a = attachment->priv; +- struct ion_buffer *buffer = dmabuf->priv; +- +- mutex_lock(&buffer->lock); +- list_del(&a->list); +- mutex_unlock(&buffer->lock); +- free_duped_table(a->table); +- +- kfree(a); +-} +- +-static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, +- enum dma_data_direction direction) +-{ +- struct ion_dma_buf_attachment *a = attachment->priv; +- struct sg_table *table; +- +- table = a->table; +- +- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, +- direction)) +- return ERR_PTR(-ENOMEM); +- +- return table; +-} +- +-static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, +- struct sg_table *table, +- enum dma_data_direction direction) +-{ +- dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); +-} +- +-static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- int ret = 0; +- +- if (!buffer->heap->ops->map_user) { +- pr_err("%s: this heap does not define a method for mapping to userspace\n", +- __func__); +- return -EINVAL; +- } +- +- if (!(buffer->flags & ION_FLAG_CACHED)) +- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +- +- mutex_lock(&buffer->lock); +- /* now map it to userspace */ +- ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); +- mutex_unlock(&buffer->lock); +- +- if (ret) +- pr_err("%s: failure mapping buffer to userspace\n", +- __func__); +- +- return ret; +-} +- +-static void ion_dma_buf_release(struct dma_buf *dmabuf) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- +- ion_buffer_destroy(internal_dev, buffer); +-} +- +-static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- +- return buffer->vaddr + offset * PAGE_SIZE; +-} +- +-static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, +- void *ptr) +-{ +-} +- +-static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, +- enum dma_data_direction direction) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- void *vaddr; +- struct ion_dma_buf_attachment *a; +- int ret = 0; +- +- /* +- * TODO: Move this elsewhere because we don't always need a vaddr +- */ +- if (buffer->heap->ops->map_kernel) { +- mutex_lock(&buffer->lock); +- vaddr = ion_buffer_kmap_get(buffer); +- if (IS_ERR(vaddr)) { +- ret = PTR_ERR(vaddr); +- goto unlock; +- } +- mutex_unlock(&buffer->lock); +- } +- +- mutex_lock(&buffer->lock); +- list_for_each_entry(a, &buffer->attachments, list) { +- dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, +- direction); +- } +- +-unlock: +- mutex_unlock(&buffer->lock); +- return ret; +-} +- +-static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, +- enum dma_data_direction direction) +-{ +- struct ion_buffer *buffer = dmabuf->priv; +- struct ion_dma_buf_attachment *a; +- +- if (buffer->heap->ops->map_kernel) { +- mutex_lock(&buffer->lock); +- ion_buffer_kmap_put(buffer); +- mutex_unlock(&buffer->lock); +- } +- +- mutex_lock(&buffer->lock); +- list_for_each_entry(a, &buffer->attachments, list) { +- dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, +- direction); +- } +- mutex_unlock(&buffer->lock); +- +- return 0; +-} +- +-static const struct dma_buf_ops dma_buf_ops = { +- .map_dma_buf = ion_map_dma_buf, +- .unmap_dma_buf = ion_unmap_dma_buf, +- .mmap = ion_mmap, +- .release = ion_dma_buf_release, +- .attach = ion_dma_buf_attach, +- .detach = ion_dma_buf_detatch, +- .begin_cpu_access = ion_dma_buf_begin_cpu_access, +- .end_cpu_access = ion_dma_buf_end_cpu_access, +- .map = ion_dma_buf_kmap, +- .unmap = ion_dma_buf_kunmap, +-}; +- +-static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, +- unsigned int flags) +-{ +- struct ion_buffer *buffer; +- DEFINE_DMA_BUF_EXPORT_INFO(exp_info); +- struct dma_buf *dmabuf; +- +- pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, +- len, heap_id_mask, flags); +- +- buffer = ion_buffer_alloc(internal_dev, len, heap_id_mask, flags); +- if (IS_ERR(buffer)) +- return ERR_CAST(buffer); +- +- exp_info.ops = &dma_buf_ops; +- exp_info.size = buffer->size; +- exp_info.flags = O_RDWR; +- exp_info.priv = buffer; +- +- dmabuf = dma_buf_export(&exp_info); +- if (IS_ERR(dmabuf)) +- ion_buffer_destroy(internal_dev, buffer); +- +- return dmabuf; +-} +- ++/* Entry into ION allocator for rest of the kernel */ + struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + unsigned int flags) + { +- return ion_alloc_dmabuf(len, heap_id_mask, flags); ++ return ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); + } + EXPORT_SYMBOL_GPL(ion_alloc); + ++int ion_free(struct ion_buffer *buffer) ++{ ++ return ion_buffer_destroy(internal_dev, buffer); ++} ++ + static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, + unsigned int flags) + { + int fd; + struct dma_buf *dmabuf; + +- dmabuf = ion_alloc_dmabuf(len, heap_id_mask, flags); ++ dmabuf = ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + +diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c +index 8b8dd1e216d42..c10ea6672f1a5 100644 +--- a/drivers/staging/android/ion/ion_buffer.c ++++ b/drivers/staging/android/ion/ion_buffer.c +@@ -149,13 +149,13 @@ void ion_buffer_release(struct ion_buffer *buffer) + kfree(buffer); + } + +-void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) ++int ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) + { + struct ion_heap *heap; + + if (!dev || !buffer) { + pr_warn("%s: invalid argument\n", __func__); +- return; ++ return -EINVAL; + } + + heap = buffer->heap; +@@ -167,6 +167,8 @@ void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) + ion_heap_freelist_add(heap, buffer); + else + ion_buffer_release(buffer); ++ ++ return 0; + } + + void *ion_buffer_kmap_get(struct ion_buffer *buffer) +diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c +new file mode 100644 +index 0000000000000..0de08e6f1af53 +--- /dev/null ++++ b/drivers/staging/android/ion/ion_dma_buf.c +@@ -0,0 +1,252 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * ION Memory Allocator - dmabuf interface ++ * ++ * Copyright (c) 2019, Google, Inc. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ion_private.h" ++ ++static struct sg_table *dup_sg_table(struct sg_table *table) ++{ ++ struct sg_table *new_table; ++ int ret, i; ++ struct scatterlist *sg, *new_sg; ++ ++ new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); ++ if (!new_table) ++ return ERR_PTR(-ENOMEM); ++ ++ ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); ++ if (ret) { ++ kfree(new_table); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ new_sg = new_table->sgl; ++ for_each_sg(table->sgl, sg, table->nents, i) { ++ memcpy(new_sg, sg, sizeof(*sg)); ++ new_sg->dma_address = 0; ++ new_sg = sg_next(new_sg); ++ } ++ ++ return new_table; ++} ++ ++static void free_duped_table(struct sg_table *table) ++{ ++ sg_free_table(table); ++ kfree(table); ++} ++ ++struct ion_dma_buf_attachment { ++ struct device *dev; ++ struct sg_table *table; ++ struct list_head list; ++}; ++ ++static int ion_dma_buf_attach(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++{ ++ struct ion_dma_buf_attachment *a; ++ struct sg_table *table; ++ struct ion_buffer *buffer = dmabuf->priv; ++ ++ a = kzalloc(sizeof(*a), GFP_KERNEL); ++ if (!a) ++ return -ENOMEM; ++ ++ table = dup_sg_table(buffer->sg_table); ++ if (IS_ERR(table)) { ++ kfree(a); ++ return -ENOMEM; ++ } ++ ++ a->table = table; ++ a->dev = attachment->dev; ++ INIT_LIST_HEAD(&a->list); ++ ++ attachment->priv = a; ++ ++ mutex_lock(&buffer->lock); ++ list_add(&a->list, &buffer->attachments); ++ mutex_unlock(&buffer->lock); ++ ++ return 0; ++} ++ ++static void ion_dma_buf_detatch(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++{ ++ struct ion_dma_buf_attachment *a = attachment->priv; ++ struct ion_buffer *buffer = dmabuf->priv; ++ ++ mutex_lock(&buffer->lock); ++ list_del(&a->list); ++ mutex_unlock(&buffer->lock); ++ free_duped_table(a->table); ++ ++ kfree(a); ++} ++ ++static struct sg_table *ion_dma_buf_map(struct dma_buf_attachment *attachment, ++ enum dma_data_direction direction) ++{ ++ struct ion_dma_buf_attachment *a = attachment->priv; ++ struct sg_table *table; ++ ++ table = a->table; ++ ++ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, ++ direction)) ++ return ERR_PTR(-ENOMEM); ++ ++ return table; ++} ++ ++static void ion_dma_buf_unmap(struct dma_buf_attachment *attachment, ++ struct sg_table *table, ++ enum dma_data_direction direction) ++{ ++ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); ++} ++ ++static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ int ret = 0; ++ ++ if (!buffer->heap->ops->map_user) { ++ pr_err("%s: this heap does not define a method for mapping to userspace\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ if (!(buffer->flags & ION_FLAG_CACHED)) ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++ ++ mutex_lock(&buffer->lock); ++ /* now map it to userspace */ ++ ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); ++ mutex_unlock(&buffer->lock); ++ ++ if (ret) ++ pr_err("%s: failure mapping buffer to userspace\n", ++ __func__); ++ ++ return ret; ++} ++ ++static void ion_dma_buf_release(struct dma_buf *dmabuf) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ ++ ion_free(buffer); ++} ++ ++static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ ++ return buffer->vaddr + offset * PAGE_SIZE; ++} ++ ++static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ void *vaddr; ++ struct ion_dma_buf_attachment *a; ++ int ret = 0; ++ ++ /* ++ * TODO: Move this elsewhere because we don't always need a vaddr ++ */ ++ if (buffer->heap->ops->map_kernel) { ++ mutex_lock(&buffer->lock); ++ vaddr = ion_buffer_kmap_get(buffer); ++ if (IS_ERR(vaddr)) { ++ ret = PTR_ERR(vaddr); ++ goto unlock; ++ } ++ mutex_unlock(&buffer->lock); ++ } ++ ++ mutex_lock(&buffer->lock); ++ list_for_each_entry(a, &buffer->attachments, list) { ++ dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, ++ direction); ++ } ++ ++unlock: ++ mutex_unlock(&buffer->lock); ++ return ret; ++} ++ ++static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct ion_buffer *buffer = dmabuf->priv; ++ struct ion_dma_buf_attachment *a; ++ ++ if (buffer->heap->ops->map_kernel) { ++ mutex_lock(&buffer->lock); ++ ion_buffer_kmap_put(buffer); ++ mutex_unlock(&buffer->lock); ++ } ++ ++ mutex_lock(&buffer->lock); ++ list_for_each_entry(a, &buffer->attachments, list) { ++ dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, ++ direction); ++ } ++ mutex_unlock(&buffer->lock); ++ ++ return 0; ++} ++ ++static const struct dma_buf_ops dma_buf_ops = { ++ .map_dma_buf = ion_dma_buf_map, ++ .unmap_dma_buf = ion_dma_buf_unmap, ++ .mmap = ion_dma_buf_mmap, ++ .release = ion_dma_buf_release, ++ .attach = ion_dma_buf_attach, ++ .detach = ion_dma_buf_detatch, ++ .begin_cpu_access = ion_dma_buf_begin_cpu_access, ++ .end_cpu_access = ion_dma_buf_end_cpu_access, ++ .map = ion_dma_buf_kmap, ++}; ++ ++struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, ++ unsigned int heap_id_mask, ++ unsigned int flags) ++{ ++ struct ion_buffer *buffer; ++ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); ++ struct dma_buf *dmabuf; ++ ++ pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, ++ len, heap_id_mask, flags); ++ ++ buffer = ion_buffer_alloc(dev, len, heap_id_mask, flags); ++ if (IS_ERR(buffer)) ++ return ERR_CAST(buffer); ++ ++ exp_info.ops = &dma_buf_ops; ++ exp_info.size = buffer->size; ++ exp_info.flags = O_RDWR; ++ exp_info.priv = buffer; ++ ++ dmabuf = dma_buf_export(&exp_info); ++ if (IS_ERR(dmabuf)) ++ ion_buffer_destroy(dev, buffer); ++ ++ return dmabuf; ++} +diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h +index e80692c885b43..b3c8b55788db1 100644 +--- a/drivers/staging/android/ion/ion_private.h ++++ b/drivers/staging/android/ion/ion_private.h +@@ -9,6 +9,7 @@ + #define _ION_PRIVATE_H + + #include ++#include + #include + #include + #include +@@ -40,8 +41,16 @@ extern struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, + unsigned int heap_id_mask, + unsigned int flags); + extern void ion_buffer_release(struct ion_buffer *buffer); +-extern void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer); ++extern int ion_buffer_destroy(struct ion_device *dev, ++ struct ion_buffer *buffer); + extern void *ion_buffer_kmap_get(struct ion_buffer *buffer); + extern void ion_buffer_kmap_put(struct ion_buffer *buffer); + ++/* ion dmabuf allocator */ ++extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, ++ unsigned int heap_id_mask, ++ unsigned int flags); ++extern int ion_free(struct ion_buffer *buffer); ++ ++ + #endif /* _ION_PRIVATE_H */ +diff --git a/include/linux/ion.h b/include/linux/ion.h +index 7bec77d98224c..66a694b875ca6 100644 +--- a/include/linux/ion.h ++++ b/include/linux/ion.h +@@ -10,8 +10,18 @@ + #include + + #ifdef CONFIG_ION +-/* +- * Allocates an ION buffer. ++ ++ ++/** ++ * ion_alloc - Allocates an ion buffer of given size from given heap ++ * ++ * @len: size of the buffer to be allocated. ++ * @heap_id_mask: a bitwise maks of heap ids to allocate from ++ * @flags: ION_BUFFER_XXXX flags for the new buffer. ++ * ++ * The function exports a dma_buf object for the new ion buffer internally ++ * and returns that to the caller. So, the buffer is ready to be used by other ++ * drivers immediately. Returns ERR_PTR in case of failure. + */ + struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + unsigned int flags); +@@ -22,5 +32,7 @@ static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + { + return ERR_PTR(-ENOMEM); + } ++ ++ + #endif /* CONFIG_ION */ + #endif /* _ION_KERNEL_H */ +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch b/patches/staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch new file mode 100644 index 000000000000..d0358e5ba8b5 --- /dev/null +++ b/patches/staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch @@ -0,0 +1,1075 @@ +From f5db87cf98f2894584d7e2f45d42adcb5a9b6275 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Thu, 8 Aug 2019 08:35:46 -0700 +Subject: staging: ion: refactor ion's heap API into + linux/ion.h + +Now that we know the APIs needed by system and cma heaps, +refactor and move all those into linux/ion.h. + +Unfortunately, the UAPI of ion is now split into linux/ion.h +and drivers/staging/android/uapi/ion.h since some of the UAPI +leaks into heap implementation (ion flags). It can all be moved +into linux/ion.h eventually for all android kernels. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: I73ea59b410c46a02e23f2da5c6bdc15182a50b32 +Co-developed-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + .../staging/android/ion/heaps/ion_cma_heap.c | 3 +- + .../android/ion/heaps/ion_system_heap.c | 2 +- + drivers/staging/android/ion/ion.c | 1 - + drivers/staging/android/ion/ion.h | 248 -------------- + drivers/staging/android/ion/ion_buffer.c | 37 ++- + drivers/staging/android/ion/ion_heap.c | 44 --- + drivers/staging/android/ion/ion_private.h | 3 +- + include/linux/ion.h | 312 +++++++++++++++++- + .../staging/android => include}/uapi/ion.h | 35 +- + 9 files changed, 367 insertions(+), 318 deletions(-) + delete mode 100644 drivers/staging/android/ion/ion.h + rename {drivers/staging/android => include}/uapi/ion.h (74%) + +Index: common/drivers/staging/android/ion/heaps/ion_cma_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/heaps/ion_cma_heap.c ++++ common/drivers/staging/android/ion/heaps/ion_cma_heap.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -14,8 +15,6 @@ + #include + #include + +-#include "../ion.h" +- + struct ion_cma_heap { + struct ion_heap heap; + struct cma *cma; +Index: common/drivers/staging/android/ion/heaps/ion_system_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/heaps/ion_system_heap.c ++++ common/drivers/staging/android/ion/heaps/ion_system_heap.c +@@ -9,12 +9,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + +-#include "../ion.h" + #include "ion_page_pool.h" + + #define NUM_ORDERS ARRAY_SIZE(orders) +Index: common/drivers/staging/android/ion/ion.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion.c ++++ common/drivers/staging/android/ion/ion.c +@@ -246,7 +246,6 @@ void ion_device_add_heap(struct ion_heap + pr_err("%s: Failed to register shrinker\n", __func__); + } + +- heap->dev = dev; + heap->num_of_buffers = 0; + heap->num_of_alloc_bytes = 0; + heap->alloc_bytes_wm = 0; +Index: common/drivers/staging/android/ion/ion.h +=================================================================== +--- common.orig/drivers/staging/android/ion/ion.h ++++ /dev/null +@@ -1,246 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * ION Memory Allocator kernel interface header +- * +- * Copyright (C) 2011 Google, Inc. +- */ +- +-#ifndef _ION_H +-#define _ION_H +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "../uapi/ion.h" +- +-/** +- * struct ion_buffer - metadata for a particular buffer +- * @list: element in list of deferred freeable buffers +- * @dev: back pointer to the ion_device +- * @heap: back pointer to the heap the buffer came from +- * @flags: buffer specific flags +- * @private_flags: internal buffer specific flags +- * @size: size of the buffer +- * @priv_virt: private data to the buffer representable as +- * a void * +- * @lock: protects the buffers cnt fields +- * @kmap_cnt: number of times the buffer is mapped to the kernel +- * @vaddr: the kernel mapping if kmap_cnt is not zero +- * @sg_table: the sg table for the buffer +- * @attachments: list of devices attached to this buffer +- */ +-struct ion_buffer { +- struct list_head list; +- struct ion_heap *heap; +- unsigned long flags; +- unsigned long private_flags; +- size_t size; +- void *priv_virt; +- struct mutex lock; +- int kmap_cnt; +- void *vaddr; +- struct sg_table *sg_table; +- struct list_head attachments; +-}; +- +-void ion_buffer_destroy(struct ion_buffer *buffer); +- +-/** +- * struct ion_heap_ops - ops to operate on a given heap +- * @allocate: allocate memory +- * @free: free memory +- * @map_kernel map memory to the kernel +- * @unmap_kernel unmap memory to the kernel +- * @map_user map memory to userspace +- * +- * allocate, phys, and map_user return 0 on success, -errno on error. +- * map_dma and map_kernel return pointer on success, ERR_PTR on +- * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in +- * the buffer's private_flags when called from a shrinker. In that +- * case, the pages being free'd must be truly free'd back to the +- * system, not put in a page pool or otherwise cached. +- */ +-struct ion_heap_ops { +- int (*allocate)(struct ion_heap *heap, +- struct ion_buffer *buffer, unsigned long len, +- unsigned long flags); +- void (*free)(struct ion_buffer *buffer); +- void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); +- void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); +- int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, +- struct vm_area_struct *vma); +- int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); +-}; +- +-/** +- * heap flags - flags between the heaps and core ion code +- */ +-#define ION_HEAP_FLAG_DEFER_FREE BIT(0) +- +-/** +- * private flags - flags internal to ion +- */ +-/* +- * Buffer is being freed from a shrinker function. Skip any possible +- * heap-specific caching mechanism (e.g. page pools). Guarantees that +- * any buffer storage that came from the system allocator will be +- * returned to the system allocator. +- */ +-#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0) +- +-/** +- * struct ion_heap - represents a heap in the system +- * @node: rb node to put the heap on the device's tree of heaps +- * @dev: back pointer to the ion_device +- * @type: type of heap +- * @ops: ops struct as above +- * @flags: flags +- * @id: id of heap, also indicates priority of this heap when +- * allocating. These are specified by platform data and +- * MUST be unique +- * @name: used for debugging +- * @shrinker: a shrinker for the heap +- * @free_list: free list head if deferred free is used +- * @free_list_size size of the deferred free list in bytes +- * @lock: protects the free list +- * @waitqueue: queue to wait on from deferred free thread +- * @task: task struct of deferred free thread +- * @num_of_buffers the number of currently allocated buffers +- * @num_of_alloc_bytes the number of allocated bytes +- * @alloc_bytes_wm the number of allocated bytes watermark +- * +- * Represents a pool of memory from which buffers can be made. In some +- * systems the only heap is regular system memory allocated via vmalloc. +- * On others, some blocks might require large physically contiguous buffers +- * that are allocated from a specially reserved heap. +- */ +-struct ion_heap { +- struct plist_node node; +- struct ion_device *dev; +- enum ion_heap_type type; +- struct ion_heap_ops *ops; +- unsigned long flags; +- unsigned int id; +- const char *name; +- +- /* deferred free support */ +- struct shrinker shrinker; +- struct list_head free_list; +- size_t free_list_size; +- spinlock_t free_lock; +- wait_queue_head_t waitqueue; +- struct task_struct *task; +- +- /* heap statistics */ +- u64 num_of_buffers; +- u64 num_of_alloc_bytes; +- u64 alloc_bytes_wm; +- +- /* protect heap statistics */ +- spinlock_t stat_lock; +-}; +- +-/** +- * ion_device_add_heap - adds a heap to the ion device +- * @heap: the heap to add +- */ +-void ion_device_add_heap(struct ion_heap *heap); +- +-/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. +- * +- * @buffer: ion_buffer to zero +- * +- * Returns 0 on success, negative error otherwise. +- */ +-int ion_buffer_zero(struct ion_buffer *buffer); +- +-/** +- * some helpers for common operations on buffers using the sg_table +- * and vaddr fields +- */ +-void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); +-void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); +-int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, +- struct vm_area_struct *vma); +-int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); +-int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, +- pgprot_t pgprot); +- +-/** +- * ion_heap_init_shrinker +- * @heap: the heap +- * +- * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op +- * this function will be called to setup a shrinker to shrink the freelists +- * and call the heap's shrink op. +- */ +-int ion_heap_init_shrinker(struct ion_heap *heap); +- +-/** +- * ion_heap_init_deferred_free -- initialize deferred free functionality +- * @heap: the heap +- * +- * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will +- * be called to setup deferred frees. Calls to free the buffer will +- * return immediately and the actual free will occur some time later +- */ +-int ion_heap_init_deferred_free(struct ion_heap *heap); +- +-/** +- * ion_heap_freelist_add - add a buffer to the deferred free list +- * @heap: the heap +- * @buffer: the buffer +- * +- * Adds an item to the deferred freelist. +- */ +-void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); +- +-/** +- * ion_heap_freelist_drain - drain the deferred free list +- * @heap: the heap +- * @size: amount of memory to drain in bytes +- * +- * Drains the indicated amount of memory from the deferred freelist immediately. +- * Returns the total amount freed. The total freed may be higher depending +- * on the size of the items in the list, or lower if there is insufficient +- * total memory on the freelist. +- */ +-size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); +- +-/** +- * ion_heap_freelist_shrink - drain the deferred free +- * list, skipping any heap-specific +- * pooling or caching mechanisms +- * +- * @heap: the heap +- * @size: amount of memory to drain in bytes +- * +- * Drains the indicated amount of memory from the deferred freelist immediately. +- * Returns the total amount freed. The total freed may be higher depending +- * on the size of the items in the list, or lower if there is insufficient +- * total memory on the freelist. +- * +- * Unlike with @ion_heap_freelist_drain, don't put any pages back into +- * page pools or otherwise cache the pages. Everything must be +- * genuinely free'd back to the system. If you're free'ing from a +- * shrinker you probably want to use this. Note that this relies on +- * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE +- * flag. +- */ +-size_t ion_heap_freelist_shrink(struct ion_heap *heap, +- size_t size); +- +-/** +- * ion_heap_freelist_size - returns the size of the freelist in bytes +- * @heap: the heap +- */ +-size_t ion_heap_freelist_size(struct ion_heap *heap); +- +-#endif /* _ION_H */ +Index: common/drivers/staging/android/ion/ion_buffer.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_buffer.c ++++ common/drivers/staging/android/ion/ion_buffer.c +@@ -92,6 +92,41 @@ err2: + return ERR_PTR(ret); + } + ++static int ion_clear_pages(struct page **pages, int num, pgprot_t pgprot) ++{ ++ void *addr = vm_map_ram(pages, num, -1, pgprot); ++ ++ if (!addr) ++ return -ENOMEM; ++ memset(addr, 0, PAGE_SIZE * num); ++ vm_unmap_ram(addr, num); ++ ++ return 0; ++} ++ ++static int ion_sglist_zero(struct scatterlist *sgl, unsigned int nents, ++ pgprot_t pgprot) ++{ ++ int p = 0; ++ int ret = 0; ++ struct sg_page_iter piter; ++ struct page *pages[32]; ++ ++ for_each_sg_page(sgl, &piter, nents, 0) { ++ pages[p++] = sg_page_iter_page(&piter); ++ if (p == ARRAY_SIZE(pages)) { ++ ret = ion_clear_pages(pages, p, pgprot); ++ if (ret) ++ return ret; ++ p = 0; ++ } ++ } ++ if (p) ++ ret = ion_clear_pages(pages, p, pgprot); ++ ++ return ret; ++} ++ + struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, + unsigned int heap_id_mask, + unsigned int flags) +@@ -147,7 +182,7 @@ int ion_buffer_zero(struct ion_buffer *b + else + pgprot = pgprot_writecombine(PAGE_KERNEL); + +- return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); ++ return ion_sglist_zero(table->sgl, table->nents, pgprot); + } + + void ion_buffer_release(struct ion_buffer *buffer) +Index: common/drivers/staging/android/ion/ion_heap.c +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_heap.c ++++ common/drivers/staging/android/ion/ion_heap.c +@@ -61,18 +61,6 @@ static unsigned long ion_heap_shrink_sca + return freed; + } + +-static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) +-{ +- void *addr = vm_map_ram(pages, num, -1, pgprot); +- +- if (!addr) +- return -ENOMEM; +- memset(addr, 0, PAGE_SIZE * num); +- vm_unmap_ram(addr, num); +- +- return 0; +-} +- + static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, + bool skip_pools) + { +@@ -211,38 +199,6 @@ int ion_heap_map_user(struct ion_heap *h + return 0; + } + +-int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, +- pgprot_t pgprot) +-{ +- int p = 0; +- int ret = 0; +- struct sg_page_iter piter; +- struct page *pages[32]; +- +- for_each_sg_page(sgl, &piter, nents, 0) { +- pages[p++] = sg_page_iter_page(&piter); +- if (p == ARRAY_SIZE(pages)) { +- ret = ion_heap_clear_pages(pages, p, pgprot); +- if (ret) +- return ret; +- p = 0; +- } +- } +- if (p) +- ret = ion_heap_clear_pages(pages, p, pgprot); +- +- return ret; +-} +- +-int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) +-{ +- struct scatterlist sg; +- +- sg_init_table(&sg, 1); +- sg_set_page(&sg, page, size, 0); +- return ion_heap_sglist_zero(&sg, 1, pgprot); +-} +- + void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) + { + spin_lock(&heap->free_lock); +Index: common/drivers/staging/android/ion/ion_private.h +=================================================================== +--- common.orig/drivers/staging/android/ion/ion_private.h ++++ common/drivers/staging/android/ion/ion_private.h +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -17,8 +18,6 @@ + #include + #include + +-#include "ion.h" +- + /** + * struct ion_device - the metadata of the ion device node + * @dev: the actual misc device +Index: common/include/linux/ion.h +=================================================================== +--- common.orig/include/linux/ion.h ++++ common/include/linux/ion.h +@@ -8,9 +8,264 @@ + + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * struct ion_buffer - metadata for a particular buffer ++ * @node: node in the ion_device buffers tree ++ * @list: element in list of deferred freeable buffers ++ * @heap: back pointer to the heap the buffer came from ++ * @flags: buffer specific flags ++ * @private_flags: internal buffer specific flags ++ * @size: size of the buffer ++ * @priv_virt: private data to the buffer representable as ++ * a void * ++ * @lock: protects the buffers cnt fields ++ * @kmap_cnt: number of times the buffer is mapped to the kernel ++ * @vaddr: the kernel mapping if kmap_cnt is not zero ++ * @sg_table: the sg table for the buffer ++ * @attachments: list of devices attached to this buffer ++ */ ++struct ion_buffer { ++ union { ++ struct rb_node node; ++ struct list_head list; ++ }; ++ struct ion_heap *heap; ++ unsigned long flags; ++ unsigned long private_flags; ++ size_t size; ++ void *priv_virt; ++ struct mutex lock; ++ int kmap_cnt; ++ void *vaddr; ++ struct sg_table *sg_table; ++ struct list_head attachments; ++}; ++ ++/** ++ * struct ion_heap_ops - ops to operate on a given heap ++ * @allocate: allocate memory ++ * @free: free memory ++ * @map_kernel map memory to the kernel ++ * @unmap_kernel unmap memory to the kernel ++ * @map_user map memory to userspace ++ * ++ * allocate, phys, and map_user return 0 on success, -errno on error. ++ * map_dma and map_kernel return pointer on success, ERR_PTR on ++ * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in ++ * the buffer's private_flags when called from a shrinker. In that ++ * case, the pages being free'd must be truly free'd back to the ++ * system, not put in a page pool or otherwise cached. ++ */ ++struct ion_heap_ops { ++ int (*allocate)(struct ion_heap *heap, ++ struct ion_buffer *buffer, unsigned long len, ++ unsigned long flags); ++ void (*free)(struct ion_buffer *buffer); ++ void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); ++ void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); ++ int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, ++ struct vm_area_struct *vma); ++ int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); ++}; ++ ++/** ++ * heap flags - flags between the heaps and core ion code ++ */ ++#define ION_HEAP_FLAG_DEFER_FREE BIT(0) ++ ++/** ++ * private flags - flags internal to ion ++ */ ++/* ++ * Buffer is being freed from a shrinker function. Skip any possible ++ * heap-specific caching mechanism (e.g. page pools). Guarantees that ++ * any buffer storage that came from the system allocator will be ++ * returned to the system allocator. ++ */ ++#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0) ++ ++/** ++ * struct ion_heap - represents a heap in the system ++ * @node: rb node to put the heap on the device's tree of heaps ++ * @type: type of heap ++ * @ops: ops struct as above ++ * @flags: flags ++ * @id: id of heap, also indicates priority of this heap when ++ * allocating. These are specified by platform data and ++ * MUST be unique ++ * @name: used for debugging ++ * @shrinker: a shrinker for the heap ++ * @free_list: free list head if deferred free is used ++ * @free_list_size size of the deferred free list in bytes ++ * @lock: protects the free list ++ * @waitqueue: queue to wait on from deferred free thread ++ * @task: task struct of deferred free thread ++ * @num_of_buffers the number of currently allocated buffers ++ * @num_of_alloc_bytes the number of allocated bytes ++ * @alloc_bytes_wm the number of allocated bytes watermark ++ * ++ * Represents a pool of memory from which buffers can be made. In some ++ * systems the only heap is regular system memory allocated via vmalloc. ++ * On others, some blocks might require large physically contiguous buffers ++ * that are allocated from a specially reserved heap. ++ */ ++struct ion_heap { ++ struct plist_node node; ++ enum ion_heap_type type; ++ struct ion_heap_ops *ops; ++ unsigned long flags; ++ unsigned int id; ++ const char *name; ++ ++ /* deferred free support */ ++ struct shrinker shrinker; ++ struct list_head free_list; ++ size_t free_list_size; ++ spinlock_t free_lock; ++ wait_queue_head_t waitqueue; ++ struct task_struct *task; ++ ++ /* heap statistics */ ++ u64 num_of_buffers; ++ u64 num_of_alloc_bytes; ++ u64 alloc_bytes_wm; ++ ++ /* protect heap statistics */ ++ spinlock_t stat_lock; ++}; + + #ifdef CONFIG_ION + ++/** ++ * ion_device_add_heap - adds a heap to the ion device ++ * ++ * @heap: the heap to add ++ */ ++void ion_device_add_heap(struct ion_heap *heap); ++ ++/** ++ * ion_heap_init_shrinker ++ * @heap: the heap ++ * ++ * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op ++ * this function will be called to setup a shrinker to shrink the freelists ++ * and call the heap's shrink op. ++ */ ++int ion_heap_init_shrinker(struct ion_heap *heap); ++ ++/** ++ * ion_heap_init_deferred_free -- initialize deferred free functionality ++ * @heap: the heap ++ * ++ * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will ++ * be called to setup deferred frees. Calls to free the buffer will ++ * return immediately and the actual free will occur some time later ++ */ ++int ion_heap_init_deferred_free(struct ion_heap *heap); ++ ++/** ++ * ion_heap_freelist_add - add a buffer to the deferred free list ++ * @heap: the heap ++ * @buffer: the buffer ++ * ++ * Adds an item to the deferred freelist. ++ */ ++void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); ++ ++/** ++ * ion_heap_freelist_drain - drain the deferred free list ++ * @heap: the heap ++ * @size: amount of memory to drain in bytes ++ * ++ * Drains the indicated amount of memory from the deferred freelist immediately. ++ * Returns the total amount freed. The total freed may be higher depending ++ * on the size of the items in the list, or lower if there is insufficient ++ * total memory on the freelist. ++ */ ++size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); ++ ++/** ++ * ion_heap_freelist_shrink - drain the deferred free ++ * list, skipping any heap-specific ++ * pooling or caching mechanisms ++ * ++ * @heap: the heap ++ * @size: amount of memory to drain in bytes ++ * ++ * Drains the indicated amount of memory from the deferred freelist immediately. ++ * Returns the total amount freed. The total freed may be higher depending ++ * on the size of the items in the list, or lower if there is insufficient ++ * total memory on the freelist. ++ * ++ * Unlike with @ion_heap_freelist_drain, don't put any pages back into ++ * page pools or otherwise cache the pages. Everything must be ++ * genuinely free'd back to the system. If you're free'ing from a ++ * shrinker you probably want to use this. Note that this relies on ++ * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE ++ * flag. ++ */ ++size_t ion_heap_freelist_shrink(struct ion_heap *heap, ++ size_t size); ++ ++/** ++ * ion_heap_freelist_size - returns the size of the freelist in bytes ++ * @heap: the heap ++ */ ++size_t ion_heap_freelist_size(struct ion_heap *heap); ++ ++/** ++ * ion_heap_map_kernel - map the ion_buffer in kernel virtual address space. ++ * ++ * @heap: the heap ++ * @buffer: buffer to be mapped ++ * ++ * Maps the buffer using vmap(). The function respects cache flags for the ++ * buffer and creates the page table entries accordingly. Returns virtual ++ * address at the beginning of the buffer or ERR_PTR. ++ */ ++void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); ++ ++/** ++ * ion_heap_unmap_kernel - unmap ion_buffer ++ * ++ * @buffer: buffer to be unmapped ++ * ++ * ION wrapper for vunmap() of the ion buffer. ++ */ ++void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); ++ ++/** ++ * ion_heap_map_user - map given ion buffer in provided vma ++ * ++ * @heap: the heap this buffer belongs to ++ * @buffer: Ion buffer to be mapped ++ * @vma: vma of the process where buffer should be mapped. ++ * ++ * Maps the buffer using remap_pfn_range() into specific process's vma starting ++ * with vma->vm_start. The vma size is expected to be >= ion buffer size. ++ * If not, a partial buffer mapping may be created. Returns 0 on success. ++ */ ++int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, ++ struct vm_area_struct *vma); ++ ++/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. ++ * ++ * @buffer: ion_buffer to zero ++ * ++ * Returns 0 on success, negative error otherwise. ++ */ ++int ion_buffer_zero(struct ion_buffer *buffer); + + /** + * ion_alloc - Allocates an ion buffer of given size from given heap +@@ -27,12 +282,67 @@ struct dma_buf *ion_alloc(size_t len, un + unsigned int flags); + + #else ++ ++static inline int ion_device_add_heap(struct ion_heap *heap) ++{ ++ return -ENODEV; ++} ++ ++static inline int ion_heap_init_shrinker(struct ion_heap *heap) ++{ ++ return -ENODEV; ++} ++ ++static inline int ion_heap_init_deferred_free(struct ion_heap *heap) ++{ ++ return -ENODEV; ++} ++ ++static inline void ion_heap_freelist_add(struct ion_heap *heap, ++ struct ion_buffer *buffer) {} ++ ++static inline size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) ++{ ++ return -ENODEV; ++} ++ ++static inline size_t ion_heap_freelist_shrink(struct ion_heap *heap, ++ size_t size) ++{ ++ return -ENODEV; ++} ++ ++static inline size_t ion_heap_freelist_size(struct ion_heap *heap) ++{ ++ return -ENODEV; ++} ++ ++static inline void *ion_heap_map_kernel(struct ion_heap *heap, ++ struct ion_buffer *buffer) ++{ ++ return ERR_PTR(-ENODEV); ++} ++ ++static inline void ion_heap_unmap_kernel(struct ion_heap *heap, ++ struct ion_buffer *buffer) {} ++ ++static inline int ion_heap_map_user(struct ion_heap *heap, ++ struct ion_buffer *buffer, ++ struct vm_area_struct *vma) ++{ ++ return -ENODEV; ++} ++ ++static inline int ion_buffer_zero(struct ion_buffer *buffer) ++{ ++ return -EINVAL; ++} ++ + static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, + unsigned int flags) + { + return ERR_PTR(-ENOMEM); + } + +- + #endif /* CONFIG_ION */ + #endif /* _ION_KERNEL_H */ +Index: common/drivers/staging/android/uapi/ion.h +=================================================================== +--- common.orig/drivers/staging/android/uapi/ion.h ++++ /dev/null +@@ -1,127 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +-/* +- * drivers/staging/android/uapi/ion.h +- * +- * Copyright (C) 2011 Google, Inc. +- */ +- +-#ifndef _UAPI_LINUX_ION_H +-#define _UAPI_LINUX_ION_H +- +-#include +-#include +- +-/** +- * enum ion_heap_types - list of all possible types of heaps +- * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc +- * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc +- * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved +- * carveout heap, allocations are physically +- * contiguous +- * @ION_HEAP_TYPE_DMA: memory allocated via DMA API +- * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask +- * is used to identify the heaps, so only 32 +- * total heap types are supported +- */ +-enum ion_heap_type { +- ION_HEAP_TYPE_SYSTEM, +- ION_HEAP_TYPE_SYSTEM_CONTIG, +- ION_HEAP_TYPE_CARVEOUT, +- ION_HEAP_TYPE_CHUNK, +- ION_HEAP_TYPE_DMA, +- ION_HEAP_TYPE_CUSTOM, /* +- * must be last so device specific heaps always +- * are at the end of this enum +- */ +-}; +- +-#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) +- +-/** +- * allocation flags - the lower 16 bits are used by core ion, the upper 16 +- * bits are reserved for use by the heaps themselves. +- */ +- +-/* +- * mappings of this buffer should be cached, ion will do cache maintenance +- * when the buffer is mapped for dma +- */ +-#define ION_FLAG_CACHED 1 +- +-/** +- * DOC: Ion Userspace API +- * +- * create a client by opening /dev/ion +- * most operations handled via following ioctls +- * +- */ +- +-/** +- * struct ion_allocation_data - metadata passed from userspace for allocations +- * @len: size of the allocation +- * @heap_id_mask: mask of heap ids to allocate from +- * @flags: flags passed to heap +- * @handle: pointer that will be populated with a cookie to use to +- * refer to this allocation +- * +- * Provided by userspace as an argument to the ioctl +- */ +-struct ion_allocation_data { +- __u64 len; +- __u32 heap_id_mask; +- __u32 flags; +- __u32 fd; +- __u32 unused; +-}; +- +-#define MAX_HEAP_NAME 32 +- +-/** +- * struct ion_heap_data - data about a heap +- * @name - first 32 characters of the heap name +- * @type - heap type +- * @heap_id - heap id for the heap +- */ +-struct ion_heap_data { +- char name[MAX_HEAP_NAME]; +- __u32 type; +- __u32 heap_id; +- __u32 reserved0; +- __u32 reserved1; +- __u32 reserved2; +-}; +- +-/** +- * struct ion_heap_query - collection of data about all heaps +- * @cnt - total number of heaps to be copied +- * @heaps - buffer to copy heap data +- */ +-struct ion_heap_query { +- __u32 cnt; /* Total number of heaps to be copied */ +- __u32 reserved0; /* align to 64bits */ +- __u64 heaps; /* buffer to be populated */ +- __u32 reserved1; +- __u32 reserved2; +-}; +- +-#define ION_IOC_MAGIC 'I' +- +-/** +- * DOC: ION_IOC_ALLOC - allocate memory +- * +- * Takes an ion_allocation_data struct and returns it with the handle field +- * populated with the opaque handle for the allocation. +- */ +-#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ +- struct ion_allocation_data) +- +-/** +- * DOC: ION_IOC_HEAP_QUERY - information about available heaps +- * +- * Takes an ion_heap_query structure and populates information about +- * available Ion heaps. +- */ +-#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ +- struct ion_heap_query) +- +-#endif /* _UAPI_LINUX_ION_H */ +Index: common/include/uapi/ion.h +=================================================================== +--- /dev/null ++++ common/include/uapi/ion.h +@@ -0,0 +1,126 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * drivers/staging/android/uapi/ion.h ++ * ++ * Copyright (C) 2011 Google, Inc. ++ */ ++ ++#ifndef _UAPI_LINUX_ION_H ++#define _UAPI_LINUX_ION_H ++ ++#include ++#include ++ ++/** ++ * enum ion_heap_types - list of all possible types of heaps ++ * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc ++ * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc ++ * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved ++ * carveout heap, allocations are physically ++ * contiguous ++ * @ION_HEAP_TYPE_DMA: memory allocated via DMA API ++ * @ION_HEAP_TYPE_MAX: helper for iterating over standard ++ * (not device specific) heaps ++ * @ION_NUM_HEAPS_IDS: helper for iterating over heaps, a bit mask ++ * is used to identify the heaps, so only 32 ++ * total heap types are supported ++ */ ++enum ion_heap_type { ++ ION_HEAP_TYPE_SYSTEM = (1 << 0), ++ ION_HEAP_TYPE_SYSTEM_CONTIG = (1 << 1), ++ ION_HEAP_TYPE_CARVEOUT = (1 << 2), ++ ION_HEAP_TYPE_CHUNK = (1 << 3), ++ ION_HEAP_TYPE_DMA = (1 << 4), ++ ION_HEAP_TYPE_MAX = (1 << 15), ++}; ++ ++#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) ++ ++/** ++ * allocation flags - the lower 16 bits are used by core ion, the upper 16 ++ * bits are reserved for use by the heaps themselves. ++ */ ++ ++/* ++ * mappings of this buffer should be cached, ion will do cache maintenance ++ * when the buffer is mapped for dma ++ */ ++#define ION_FLAG_CACHED 1 ++ ++/** ++ * DOC: Ion Userspace API ++ * ++ * create a client by opening /dev/ion ++ * most operations handled via following ioctls ++ * ++ */ ++ ++/** ++ * struct ion_allocation_data - metadata passed from userspace for allocations ++ * @len: size of the allocation ++ * @heap_id_mask: mask of heap ids to allocate from ++ * @flags: flags passed to heap ++ * @handle: pointer that will be populated with a cookie to use to ++ * refer to this allocation ++ * ++ * Provided by userspace as an argument to the ioctl ++ */ ++struct ion_allocation_data { ++ __u64 len; ++ __u32 heap_id_mask; ++ __u32 flags; ++ __u32 fd; ++ __u32 unused; ++}; ++ ++#define MAX_HEAP_NAME 32 ++ ++/** ++ * struct ion_heap_data - data about a heap ++ * @name - first 32 characters of the heap name ++ * @type - heap type ++ * @heap_id - heap id for the heap ++ */ ++struct ion_heap_data { ++ char name[MAX_HEAP_NAME]; ++ __u32 type; ++ __u32 heap_id; ++ __u32 reserved0; ++ __u32 reserved1; ++ __u32 reserved2; ++}; ++ ++/** ++ * struct ion_heap_query - collection of data about all heaps ++ * @cnt - total number of heaps to be copied ++ * @heaps - buffer to copy heap data ++ */ ++struct ion_heap_query { ++ __u32 cnt; /* Total number of heaps to be copied */ ++ __u32 reserved0; /* align to 64bits */ ++ __u64 heaps; /* buffer to be populated */ ++ __u32 reserved1; ++ __u32 reserved2; ++}; ++ ++#define ION_IOC_MAGIC 'I' ++ ++/** ++ * DOC: ION_IOC_ALLOC - allocate memory ++ * ++ * Takes an ion_allocation_data struct and returns it with the handle field ++ * populated with the opaque handle for the allocation. ++ */ ++#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ ++ struct ion_allocation_data) ++ ++/** ++ * DOC: ION_IOC_HEAP_QUERY - information about available heaps ++ * ++ * Takes an ion_heap_query structure and populates information about ++ * available Ion heaps. ++ */ ++#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ ++ struct ion_heap_query) ++ ++#endif /* _UAPI_LINUX_ION_H */ diff --git a/patches/staging-ion-refactor-ion-s-heap-manipulators-into-a-.patch b/patches/staging-ion-refactor-ion-s-heap-manipulators-into-a-.patch new file mode 100644 index 000000000000..4af567bffd09 --- /dev/null +++ b/patches/staging-ion-refactor-ion-s-heap-manipulators-into-a-.patch @@ -0,0 +1,401 @@ +From 556326db15ccb3552bdc7ac929e2b845c6c36c04 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Thu, 8 Aug 2019 07:52:27 -0700 +Subject: staging: ion: refactor ion's heap manipulators into a + separate file. + +This patch is preparatory work for making ion heaps modular. The patch +itself doesn't make any significant changes except for re-organizing the +heap manipulator functions in a single file. This will be helpful +later when we specifically export some of these functions to be used by +a heap module. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: I19205b4874a3bf52408f1fa14c3e145de1293fb4 +Co-developed-by: Isaac J. Manjarres +Signed-off-by: Sandeep Patil +--- + drivers/staging/android/ion/ion.h | 11 +- + drivers/staging/android/ion/ion_buffer.c | 17 ++ + drivers/staging/android/ion/ion_heap.c | 245 +++++++++--------- + drivers/staging/android/ion/ion_private.h | 1 - + drivers/staging/android/ion/ion_system_heap.c | 2 +- + 5 files changed, 144 insertions(+), 132 deletions(-) + +diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h +index ec20a9ea13f96..6b7727f5736ea 100644 +--- a/drivers/staging/android/ion/ion.h ++++ b/drivers/staging/android/ion/ion.h +@@ -155,6 +155,14 @@ struct ion_heap { + */ + void ion_device_add_heap(struct ion_heap *heap); + ++/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. ++ * ++ * @buffer: ion_buffer to zero ++ * ++ * Returns 0 on success, negative error otherwise. ++ */ ++int ion_buffer_zero(struct ion_buffer *buffer); ++ + /** + * some helpers for common operations on buffers using the sg_table + * and vaddr fields +@@ -163,8 +171,9 @@ void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); + void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); + int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + struct vm_area_struct *vma); +-int ion_heap_buffer_zero(struct ion_buffer *buffer); + int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); ++int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, ++ pgprot_t pgprot); + + /** + * ion_heap_init_shrinker +diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c +index c10ea6672f1a5..50c2dbc3ebecb 100644 +--- a/drivers/staging/android/ion/ion_buffer.c ++++ b/drivers/staging/android/ion/ion_buffer.c +@@ -133,6 +133,23 @@ struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, + return buffer; + } + ++int ion_buffer_zero(struct ion_buffer *buffer) ++{ ++ struct sg_table *table; ++ pgprot_t pgprot; ++ ++ if (!buffer) ++ return -EINVAL; ++ ++ table = buffer->sg_table; ++ if (buffer->flags & ION_FLAG_CACHED) ++ pgprot = PAGE_KERNEL; ++ else ++ pgprot = pgprot_writecombine(PAGE_KERNEL); ++ ++ return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); ++} ++ + void ion_buffer_release(struct ion_buffer *buffer) + { + if (buffer->kmap_cnt > 0) { +diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c +index 3b4f32b9cd2d7..39eb60e4842eb 100644 +--- a/drivers/staging/android/ion/ion_heap.c ++++ b/drivers/staging/android/ion/ion_heap.c +@@ -17,6 +17,120 @@ + + #include "ion_private.h" + ++static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct ion_heap *heap = container_of(shrinker, struct ion_heap, ++ shrinker); ++ int total = 0; ++ ++ total = ion_heap_freelist_size(heap) / PAGE_SIZE; ++ ++ if (heap->ops->shrink) ++ total += heap->ops->shrink(heap, sc->gfp_mask, 0); ++ ++ return total; ++} ++ ++static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ struct ion_heap *heap = container_of(shrinker, struct ion_heap, ++ shrinker); ++ int freed = 0; ++ int to_scan = sc->nr_to_scan; ++ ++ if (to_scan == 0) ++ return 0; ++ ++ /* ++ * shrink the free list first, no point in zeroing the memory if we're ++ * just going to reclaim it. Also, skip any possible page pooling. ++ */ ++ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ++ freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) / ++ PAGE_SIZE; ++ ++ to_scan -= freed; ++ if (to_scan <= 0) ++ return freed; ++ ++ if (heap->ops->shrink) ++ freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); ++ ++ return freed; ++} ++ ++static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) ++{ ++ void *addr = vm_map_ram(pages, num, -1, pgprot); ++ ++ if (!addr) ++ return -ENOMEM; ++ memset(addr, 0, PAGE_SIZE * num); ++ vm_unmap_ram(addr, num); ++ ++ return 0; ++} ++ ++static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, ++ bool skip_pools) ++{ ++ struct ion_buffer *buffer; ++ size_t total_drained = 0; ++ ++ if (ion_heap_freelist_size(heap) == 0) ++ return 0; ++ ++ spin_lock(&heap->free_lock); ++ if (size == 0) ++ size = heap->free_list_size; ++ ++ while (!list_empty(&heap->free_list)) { ++ if (total_drained >= size) ++ break; ++ buffer = list_first_entry(&heap->free_list, struct ion_buffer, ++ list); ++ list_del(&buffer->list); ++ heap->free_list_size -= buffer->size; ++ if (skip_pools) ++ buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; ++ total_drained += buffer->size; ++ spin_unlock(&heap->free_lock); ++ ion_buffer_release(buffer); ++ spin_lock(&heap->free_lock); ++ } ++ spin_unlock(&heap->free_lock); ++ ++ return total_drained; ++} ++ ++static int ion_heap_deferred_free(void *data) ++{ ++ struct ion_heap *heap = data; ++ ++ while (true) { ++ struct ion_buffer *buffer; ++ ++ wait_event_freezable(heap->waitqueue, ++ ion_heap_freelist_size(heap) > 0); ++ ++ spin_lock(&heap->free_lock); ++ if (list_empty(&heap->free_list)) { ++ spin_unlock(&heap->free_lock); ++ continue; ++ } ++ buffer = list_first_entry(&heap->free_list, struct ion_buffer, ++ list); ++ list_del(&buffer->list); ++ heap->free_list_size -= buffer->size; ++ spin_unlock(&heap->free_lock); ++ ion_buffer_release(buffer); ++ } ++ ++ return 0; ++} ++ + void *ion_heap_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) + { +@@ -97,20 +211,8 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + return 0; + } + +-static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) +-{ +- void *addr = vm_map_ram(pages, num, -1, pgprot); +- +- if (!addr) +- return -ENOMEM; +- memset(addr, 0, PAGE_SIZE * num); +- vm_unmap_ram(addr, num); +- +- return 0; +-} +- +-static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, +- pgprot_t pgprot) ++int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, ++ pgprot_t pgprot) + { + int p = 0; + int ret = 0; +@@ -132,19 +234,6 @@ static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, + return ret; + } + +-int ion_heap_buffer_zero(struct ion_buffer *buffer) +-{ +- struct sg_table *table = buffer->sg_table; +- pgprot_t pgprot; +- +- if (buffer->flags & ION_FLAG_CACHED) +- pgprot = PAGE_KERNEL; +- else +- pgprot = pgprot_writecombine(PAGE_KERNEL); +- +- return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); +-} +- + int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) + { + struct scatterlist sg; +@@ -174,38 +263,6 @@ size_t ion_heap_freelist_size(struct ion_heap *heap) + return size; + } + +-static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, +- bool skip_pools) +-{ +- struct ion_buffer *buffer; +- size_t total_drained = 0; +- +- if (ion_heap_freelist_size(heap) == 0) +- return 0; +- +- spin_lock(&heap->free_lock); +- if (size == 0) +- size = heap->free_list_size; +- +- while (!list_empty(&heap->free_list)) { +- if (total_drained >= size) +- break; +- buffer = list_first_entry(&heap->free_list, struct ion_buffer, +- list); +- list_del(&buffer->list); +- heap->free_list_size -= buffer->size; +- if (skip_pools) +- buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; +- total_drained += buffer->size; +- spin_unlock(&heap->free_lock); +- ion_buffer_release(buffer); +- spin_lock(&heap->free_lock); +- } +- spin_unlock(&heap->free_lock); +- +- return total_drained; +-} +- + size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) + { + return _ion_heap_freelist_drain(heap, size, false); +@@ -216,32 +273,6 @@ size_t ion_heap_freelist_shrink(struct ion_heap *heap, size_t size) + return _ion_heap_freelist_drain(heap, size, true); + } + +-static int ion_heap_deferred_free(void *data) +-{ +- struct ion_heap *heap = data; +- +- while (true) { +- struct ion_buffer *buffer; +- +- wait_event_freezable(heap->waitqueue, +- ion_heap_freelist_size(heap) > 0); +- +- spin_lock(&heap->free_lock); +- if (list_empty(&heap->free_list)) { +- spin_unlock(&heap->free_lock); +- continue; +- } +- buffer = list_first_entry(&heap->free_list, struct ion_buffer, +- list); +- list_del(&buffer->list); +- heap->free_list_size -= buffer->size; +- spin_unlock(&heap->free_lock); +- ion_buffer_release(buffer); +- } +- +- return 0; +-} +- + int ion_heap_init_deferred_free(struct ion_heap *heap) + { + struct sched_param param = { .sched_priority = 0 }; +@@ -260,50 +291,6 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) + return 0; + } + +-static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, +- struct shrink_control *sc) +-{ +- struct ion_heap *heap = container_of(shrinker, struct ion_heap, +- shrinker); +- int total = 0; +- +- total = ion_heap_freelist_size(heap) / PAGE_SIZE; +- +- if (heap->ops->shrink) +- total += heap->ops->shrink(heap, sc->gfp_mask, 0); +- +- return total; +-} +- +-static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, +- struct shrink_control *sc) +-{ +- struct ion_heap *heap = container_of(shrinker, struct ion_heap, +- shrinker); +- int freed = 0; +- int to_scan = sc->nr_to_scan; +- +- if (to_scan == 0) +- return 0; +- +- /* +- * shrink the free list first, no point in zeroing the memory if we're +- * just going to reclaim it. Also, skip any possible page pooling. +- */ +- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) +- freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) / +- PAGE_SIZE; +- +- to_scan -= freed; +- if (to_scan <= 0) +- return freed; +- +- if (heap->ops->shrink) +- freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); +- +- return freed; +-} +- + int ion_heap_init_shrinker(struct ion_heap *heap) + { + heap->shrinker.count_objects = ion_heap_shrink_count; +diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h +index b3c8b55788db1..9c8f482cd9d2f 100644 +--- a/drivers/staging/android/ion/ion_private.h ++++ b/drivers/staging/android/ion/ion_private.h +@@ -52,5 +52,4 @@ extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, + unsigned int flags); + extern int ion_free(struct ion_buffer *buffer); + +- + #endif /* _ION_PRIVATE_H */ +diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c +index fbf5f39c22dbc..66a2b8e8b51ee 100644 +--- a/drivers/staging/android/ion/ion_system_heap.c ++++ b/drivers/staging/android/ion/ion_system_heap.c +@@ -161,7 +161,7 @@ static void ion_system_heap_free(struct ion_buffer *buffer) + + /* zero the buffer before goto page pool */ + if (!(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) +- ion_heap_buffer_zero(buffer); ++ ion_buffer_zero(buffer); + + for_each_sg(table->sgl, sg, table->nents, i) + free_buffer_page(sys_heap, buffer, sg_page(sg)); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-split-system-and-system-contig-heaps.patch b/patches/staging-ion-split-system-and-system-contig-heaps.patch new file mode 100644 index 000000000000..8d77b46d0479 --- /dev/null +++ b/patches/staging-ion-split-system-and-system-contig-heaps.patch @@ -0,0 +1,300 @@ +From 2880fe57a6080ad641a2816002f22a925a5cc856 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Thu, 8 Aug 2019 08:50:56 -0700 +Subject: staging: ion: split system and system-contig heaps + +This will allows us to build and load them both as individual +kernel modules. + +Bug: 133508579 +Test: ion-unit-tests + +Change-Id: I8bdada5531fbf148e4d097e94e406a232874913a +Signed-off-by: Sandeep Patil +--- + arch/arm64/configs/gki_defconfig | 2 + + arch/x86/configs/gki_defconfig | 2 + + drivers/staging/android/ion/heaps/Kconfig | 8 ++ + drivers/staging/android/ion/heaps/Makefile | 1 + + .../ion/heaps/ion_system_contig_heap.c | 111 ++++++++++++++++++ + .../android/ion/heaps/ion_system_heap.c | 95 --------------- + 6 files changed, 124 insertions(+), 95 deletions(-) + create mode 100644 drivers/staging/android/ion/heaps/ion_system_contig_heap.c + +diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig +index 539f42574383e..73acbe383203d 100644 +--- a/arch/arm64/configs/gki_defconfig ++++ b/arch/arm64/configs/gki_defconfig +@@ -349,6 +349,8 @@ CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ANDROID_VSOC=y + CONFIG_ION=y ++CONFIG_ION_SYSTEM_HEAP=y ++CONFIG_ION_SYSTEM_CONTIG_HEAP=y + CONFIG_COMMON_CLK_SCPI=y + CONFIG_HWSPINLOCK=y + CONFIG_MAILBOX=y +diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig +index 2d5f55d7b9669..ae3d165a79c3a 100644 +--- a/arch/x86/configs/gki_defconfig ++++ b/arch/x86/configs/gki_defconfig +@@ -289,6 +289,8 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + CONFIG_STAGING=y + CONFIG_ASHMEM=y + CONFIG_ION=y ++CONFIG_ION_SYSTEM_HEAP=y ++CONFIG_ION_SYSTEM_CONTIG_HEAP=y + CONFIG_PM_DEVFREQ=y + CONFIG_ANDROID=y + CONFIG_ANDROID_BINDER_IPC=y +diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig +index 7affa91ecabbe..f1c7a6b79c014 100644 +--- a/drivers/staging/android/ion/heaps/Kconfig ++++ b/drivers/staging/android/ion/heaps/Kconfig +@@ -6,6 +6,14 @@ config ION_SYSTEM_HEAP + Choose this option to enable the Ion system heap. The system heap + is backed by pages from the buddy allocator. If in doubt, say Y. + ++config ION_SYSTEM_CONTIG_HEAP ++ bool "Ion system contig heap" ++ depends on ION ++ help ++ Choose this option to enable Ion system contig heap. The system contig heap ++ is backed by the pages from buddy allocator that are guaranteed to be physically ++ contiguous. If in doubt, say Y. ++ + config ION_CMA_HEAP + bool "Ion CMA heap support" + depends on ION && DMA_CMA +diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile +index 127912629f0b0..e2ee931100d0b 100644 +--- a/drivers/staging/android/ion/heaps/Makefile ++++ b/drivers/staging/android/ion/heaps/Makefile +@@ -1,3 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o ++obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o + obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o +diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +new file mode 100644 +index 0000000000000..3a07ef931c2ee +--- /dev/null ++++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c +@@ -0,0 +1,111 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * ION Memory Allocator system contig heap exporter ++ * ++ * Copyright (C) 2019 Google, Inc. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ion_system_contig_heap_allocate(struct ion_heap *heap, ++ struct ion_buffer *buffer, ++ unsigned long len, ++ unsigned long flags) ++{ ++ int order = get_order(len); ++ struct page *page; ++ struct sg_table *table; ++ unsigned long i; ++ int ret; ++ ++ page = alloc_pages(GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN, order); ++ if (!page) ++ return -ENOMEM; ++ ++ split_page(page, order); ++ ++ len = PAGE_ALIGN(len); ++ for (i = len >> PAGE_SHIFT; i < (1 << order); i++) ++ __free_page(page + i); ++ ++ table = kmalloc(sizeof(*table), GFP_KERNEL); ++ if (!table) { ++ ret = -ENOMEM; ++ goto free_pages; ++ } ++ ++ ret = sg_alloc_table(table, 1, GFP_KERNEL); ++ if (ret) ++ goto free_table; ++ ++ sg_set_page(table->sgl, page, len, 0); ++ ++ buffer->sg_table = table; ++ ++ return 0; ++ ++free_table: ++ kfree(table); ++free_pages: ++ for (i = 0; i < len >> PAGE_SHIFT; i++) ++ __free_page(page + i); ++ ++ return ret; ++} ++ ++static void ion_system_contig_heap_free(struct ion_buffer *buffer) ++{ ++ struct sg_table *table = buffer->sg_table; ++ struct page *page = sg_page(table->sgl); ++ unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; ++ unsigned long i; ++ ++ for (i = 0; i < pages; i++) ++ __free_page(page + i); ++ sg_free_table(table); ++ kfree(table); ++} ++ ++static struct ion_heap_ops kmalloc_ops = { ++ .allocate = ion_system_contig_heap_allocate, ++ .free = ion_system_contig_heap_free, ++ .map_kernel = ion_heap_map_kernel, ++ .unmap_kernel = ion_heap_unmap_kernel, ++ .map_user = ion_heap_map_user, ++}; ++ ++static struct ion_heap *__ion_system_contig_heap_create(void) ++{ ++ struct ion_heap *heap; ++ ++ heap = kzalloc(sizeof(*heap), GFP_KERNEL); ++ if (!heap) ++ return ERR_PTR(-ENOMEM); ++ heap->ops = &kmalloc_ops; ++ heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; ++ heap->name = "ion_system_contig_heap"; ++ ++ return heap; ++} ++ ++static int ion_system_contig_heap_create(void) ++{ ++ struct ion_heap *heap; ++ ++ heap = __ion_system_contig_heap_create(); ++ if (IS_ERR(heap)) ++ return PTR_ERR(heap); ++ ++ ion_device_add_heap(heap); ++ ++ return 0; ++} ++device_initcall(ion_system_contig_heap_create); ++ +diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c +index 3d072dd015bae..df4f5010fa820 100644 +--- a/drivers/staging/android/ion/heaps/ion_system_heap.c ++++ b/drivers/staging/android/ion/heaps/ion_system_heap.c +@@ -281,98 +281,3 @@ static int ion_system_heap_create(void) + return 0; + } + device_initcall(ion_system_heap_create); +- +-static int ion_system_contig_heap_allocate(struct ion_heap *heap, +- struct ion_buffer *buffer, +- unsigned long len, +- unsigned long flags) +-{ +- int order = get_order(len); +- struct page *page; +- struct sg_table *table; +- unsigned long i; +- int ret; +- +- page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order); +- if (!page) +- return -ENOMEM; +- +- split_page(page, order); +- +- len = PAGE_ALIGN(len); +- for (i = len >> PAGE_SHIFT; i < (1 << order); i++) +- __free_page(page + i); +- +- table = kmalloc(sizeof(*table), GFP_KERNEL); +- if (!table) { +- ret = -ENOMEM; +- goto free_pages; +- } +- +- ret = sg_alloc_table(table, 1, GFP_KERNEL); +- if (ret) +- goto free_table; +- +- sg_set_page(table->sgl, page, len, 0); +- +- buffer->sg_table = table; +- +- return 0; +- +-free_table: +- kfree(table); +-free_pages: +- for (i = 0; i < len >> PAGE_SHIFT; i++) +- __free_page(page + i); +- +- return ret; +-} +- +-static void ion_system_contig_heap_free(struct ion_buffer *buffer) +-{ +- struct sg_table *table = buffer->sg_table; +- struct page *page = sg_page(table->sgl); +- unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; +- unsigned long i; +- +- for (i = 0; i < pages; i++) +- __free_page(page + i); +- sg_free_table(table); +- kfree(table); +-} +- +-static struct ion_heap_ops kmalloc_ops = { +- .allocate = ion_system_contig_heap_allocate, +- .free = ion_system_contig_heap_free, +- .map_kernel = ion_heap_map_kernel, +- .unmap_kernel = ion_heap_unmap_kernel, +- .map_user = ion_heap_map_user, +-}; +- +-static struct ion_heap *__ion_system_contig_heap_create(void) +-{ +- struct ion_heap *heap; +- +- heap = kzalloc(sizeof(*heap), GFP_KERNEL); +- if (!heap) +- return ERR_PTR(-ENOMEM); +- heap->ops = &kmalloc_ops; +- heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; +- heap->name = "ion_system_contig_heap"; +- +- return heap; +-} +- +-static int ion_system_contig_heap_create(void) +-{ +- struct ion_heap *heap; +- +- heap = __ion_system_contig_heap_create(); +- if (IS_ERR(heap)) +- return PTR_ERR(heap); +- +- ion_device_add_heap(heap); +- +- return 0; +-} +-device_initcall(ion_system_contig_heap_create); +-- +2.23.0.444.g18eeb5a265-goog + diff --git a/patches/staging-ion-uapi-match-the-existing-heap-type-enums.patch b/patches/staging-ion-uapi-match-the-existing-heap-type-enums.patch new file mode 100644 index 000000000000..f1e8bb07739d --- /dev/null +++ b/patches/staging-ion-uapi-match-the-existing-heap-type-enums.patch @@ -0,0 +1,50 @@ +From 513ece9b1d28d64ed58a42f28080f9980f2b7bd1 Mon Sep 17 00:00:00 2001 +From: Sandeep Patil +Date: Mon, 9 Sep 2019 08:34:43 -0700 +Subject: staging: ion: uapi: match the existing heap type + enums + +Change the enup order for ion heap types to match how it was before so +as to not break any userspace code that depends on them. + +Bug: 140507100 +Test: ion-unit-tests + +Change-Id: Id68c50a9bd3eda2ce46bc88a326a120c52d1110f +Signed-off-by: Sandeep Patil +--- + include/uapi/linux/ion.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h +index 09dbbfaf37185..ad773e5fa4d29 100644 +--- a/include/uapi/linux/ion.h ++++ b/include/uapi/linux/ion.h +@@ -31,8 +31,8 @@ + enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM = 0, + ION_HEAP_TYPE_SYSTEM_CONTIG = 1, +- ION_HEAP_TYPE_CHUNK = 2, +- ION_HEAP_TYPE_CARVEOUT = 3, ++ ION_HEAP_TYPE_CARVEOUT = 2, ++ ION_HEAP_TYPE_CHUNK = 3, + ION_HEAP_TYPE_DMA = 4, + /* reserved range for future standard heap types */ + ION_HEAP_TYPE_CUSTOM = 16, +@@ -61,10 +61,10 @@ enum ion_heap_type { + enum ion_heap_id { + ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM), + ION_HEAP_SYSTEM_CONTIG = (ION_HEAP_SYSTEM << 1), +- ION_HEAP_CHUNK = (ION_HEAP_SYSTEM_CONTIG << 1), +- ION_HEAP_CARVEOUT_START = (ION_HEAP_CHUNK << 1), ++ ION_HEAP_CARVEOUT_START = (ION_HEAP_SYSTEM_CONTIG << 1), + ION_HEAP_CARVEOUT_END = (ION_HEAP_CARVEOUT_START << 4), +- ION_HEAP_DMA_START = (ION_HEAP_CARVEOUT_END << 1), ++ ION_HEAP_CHUNK = (ION_HEAP_CARVEOUT_END << 1), ++ ION_HEAP_DMA_START = (ION_HEAP_CHUNK << 1), + ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7), + ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1), + ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 15), +-- +2.23.0.444.g18eeb5a265-goog +