https://source.android.com/docs/security/bulletin/2022-10-01
CVE-2022-1786
CVE-2022-20421
CVE-2022-20422
CVE-2022-20423
CVE-2022-20409

* tag 'ASB-2022-10-01_13-5.10': (68 commits)
  UPSTREAM: crypto: jitter - add oversampling of noise source
  ANDROID: Update the ABI representation
  FROMGIT: f2fs: support recording stop_checkpoint reason into super_block
  ANDROID: Update the ABI representation
  ANDROID: Fix for kernelci !CONFIG_SMP break-breaks
  ANDROID: fuse-bpf: set error_in to ENOENT in negative lookup
  ANDROID: fuse-bpf: Add ability to run ranges of tests to fuse_test
  BACKPORT: NFC: netlink: fix sleep in atomic bug when firmware download timeout
  ANDROID: KVM: arm64: Initialize ptr auth in protected mode
  ANDROID: cgroup: Add vendor hook for rebuild_root_domains_bypass
  FROMGIT: KVM: arm64: Ignore kvm-arm.mode if !is_hyp_mode_available()
  ANDROID: Update the ABI symbol list and xml
  UPSTREAM: wifi: mac80211_hwsim: use 32-bit skb cookie
  UPSTREAM: wifi: mac80211_hwsim: add back erroneously removed cast
  UPSTREAM: wifi: mac80211_hwsim: fix race condition in pending packet
  ANDROID: Update the ABI representation
  ANDROID: sched: Fix off-by-one with cpupri MAX_RT_PRIO evaluation
  Revert "ANDROID: workqueue: add vendor hook for wq lockup information"
  UPSTREAM: kernel/irq: export irq_gc_set_wake
  ANDROID: Update the ABI representation
  ...

Change-Id: I0e90348befd683d679799deb2b2f0bf738dbc99f

Conflicts:
	sound/soc/codecs/hdmi-codec.c
This commit is contained in:
Tao Huang
2022-11-14 19:57:02 +08:00
99 changed files with 6542 additions and 2672 deletions

View File

@@ -19,8 +19,27 @@ package(
load("//build/kernel/kleaf:common_kernels.bzl", "define_common_kernels")
# This uses android/abi_gki_aarch64* in kmi_configs. If the list of
# glob(["android/abi_gki_aarch64*"]) differs from
# KMI_SYMBOL_LIST + ADDITIONAL_KMI_SYMBOL_LISTS in build.config.gki.aarch64,
# or TRIM_NONLISTED_KMI changes, override kmi_configs here.
define_common_kernels()
_aarch64_additional_kmi_symbol_lists = [
# keep sorted
"android/abi_gki_aarch64_core",
"android/abi_gki_aarch64_db845c",
"android/abi_gki_aarch64_fips140",
"android/abi_gki_aarch64_generic",
"android/abi_gki_aarch64_hikey960",
"android/abi_gki_aarch64_type_visibility",
"android/abi_gki_aarch64_virtual_device",
]
define_common_kernels(target_configs = {
# Sync with build.config.gki.aarch64
"kernel_aarch64": {
"kmi_symbol_list": "android/abi_gki_aarch64",
"additional_kmi_symbol_lists": _aarch64_additional_kmi_symbol_lists,
"abi_definition": "android/abi_gki_aarch64.xml",
},
"kernel_aarch64_debug": {
"kmi_symbol_list": "android/abi_gki_aarch64",
"additional_kmi_symbol_lists": _aarch64_additional_kmi_symbol_lists,
"abi_definition": "android/abi_gki_aarch64.xml",
},
})

View File

@@ -342,6 +342,11 @@ discard_unit=%s Control discard unit, the argument can be "block", "segment"
default, it is helpful for large sized SMR or ZNS devices to
reduce memory cost by getting rid of fs metadata supports small
discard.
memory=%s Control memory mode. This supports "normal" and "low" modes.
"low" mode is introduced to support low memory devices.
Because of the nature of low memory devices, in this mode, f2fs
will try to save memory sometimes by sacrificing performance.
"normal" mode is the default mode and same as before.
======================== ============================================================
Debugfs Entries

File diff suppressed because it is too large Load Diff

View File

@@ -54,7 +54,6 @@
cpumask_next
cpu_number
__cpu_online_mask
crc32_le
debugfs_create_dir
debugfs_create_file
debugfs_create_u32
@@ -185,7 +184,6 @@
free_irq
generic_handle_irq
get_device
get_random_bytes
gic_nonsecure_priorities
gpiochip_add_data_with_key
gpiochip_add_pin_range
@@ -419,7 +417,6 @@
preempt_schedule_notrace
prepare_to_wait_event
printk
pskb_expand_head
put_device
__put_task_struct
qcom_smem_state_register
@@ -505,7 +502,6 @@
simple_read_from_buffer
single_open
single_release
skb_clone
skb_dequeue
skb_pull
skb_push
@@ -553,6 +549,7 @@
strlen
strncmp
strncpy
strnlen
strpbrk
strsep
__sw_hweight32
@@ -655,9 +652,11 @@
cfg80211_vendor_cmd_reply
cpu_latency_qos_add_request
cpu_latency_qos_remove_request
crc32_le
device_get_mac_address
device_set_wakeup_enable
firmware_request_nowarn
get_random_bytes
guid_gen
idr_for_each
ieee80211_alloc_hw_nm
@@ -710,11 +709,13 @@
init_uts_ns
__kfifo_alloc
__kfifo_free
ktime_get_with_offset
__local_bh_enable_ip
memmove
__nla_parse
nla_put
param_ops_ulong
pskb_expand_head
regulatory_hint
rfc1042_header
skb_copy
@@ -751,44 +752,6 @@
devm_clk_bulk_get_optional
iommu_map
# required by ax88179_178a.ko
eth_platform_get_mac_address
ethtool_op_get_link
ethtool_op_get_ts_info
eth_validate_addr
generic_mii_ioctl
mii_ethtool_get_link_ksettings
mii_ethtool_gset
mii_ethtool_set_link_ksettings
mii_nway_restart
netdev_err
netdev_info
netdev_warn
netif_carrier_on
usb_deregister
usbnet_disconnect
usbnet_get_endpoints
usbnet_get_msglevel
usbnet_get_stats64
usbnet_link_change
usbnet_nway_reset
usbnet_open
usbnet_probe
usbnet_read_cmd
usbnet_read_cmd_nopm
usbnet_resume
usbnet_set_msglevel
usbnet_skb_return
usbnet_start_xmit
usbnet_stop
usbnet_suspend
usbnet_tx_timeout
usbnet_update_max_qlen
usbnet_write_cmd
usbnet_write_cmd_async
usbnet_write_cmd_nopm
usb_register_driver
# required by bam_dma.ko
dma_async_device_register
dma_async_device_unregister
@@ -1303,9 +1266,6 @@
usb_put_hcd
usb_remove_hcd
# required by pdr_interface.ko
strnlen
# required by phy-qcom-qmp.ko
of_clk_get_by_name
__of_reset_control_get
@@ -1489,6 +1449,7 @@
refcount_dec_and_mutex_lock
release_sock
sk_alloc
skb_clone
skb_copy_bits
skb_copy_datagram_iter
skb_free_datagram
@@ -1577,7 +1538,9 @@
snd_ctl_add
snd_ctl_new1
snd_pcm_add_chmap_ctls
snd_pcm_create_iec958_consumer_hw_params
snd_pcm_create_iec958_consumer_default
snd_pcm_fill_iec958_consumer
snd_pcm_fill_iec958_consumer_hw_params
snd_pcm_hw_constraint_eld
# required by snd-soc-qcom-common.ko
@@ -1701,3 +1664,42 @@
# required by wcd934x.ko
mfd_add_devices
mfd_remove_devices
# preserved by --additions-only
eth_platform_get_mac_address
ethtool_op_get_link
ethtool_op_get_ts_info
eth_validate_addr
generic_mii_ioctl
mii_ethtool_get_link_ksettings
mii_ethtool_gset
mii_ethtool_set_link_ksettings
mii_nway_restart
netdev_err
netdev_info
netdev_warn
netif_carrier_on
snd_pcm_create_iec958_consumer_hw_params
usb_deregister
usbnet_disconnect
usbnet_get_endpoints
usbnet_get_msglevel
usbnet_get_stats64
usbnet_link_change
usbnet_nway_reset
usbnet_open
usbnet_probe
usbnet_read_cmd
usbnet_read_cmd_nopm
usbnet_resume
usbnet_set_msglevel
usbnet_skb_return
usbnet_start_xmit
usbnet_stop
usbnet_suspend
usbnet_tx_timeout
usbnet_update_max_qlen
usbnet_write_cmd
usbnet_write_cmd_async
usbnet_write_cmd_nopm
usb_register_driver

View File

@@ -78,6 +78,7 @@
__bitmap_set
bitmap_to_arr32
__bitmap_weight
__bitmap_xor
blk_abort_request
blk_alloc_queue
blk_check_plugged
@@ -628,6 +629,7 @@
drm_add_modes_noedid
drm_atomic_add_affected_connectors
drm_atomic_add_affected_planes
drm_atomic_bridge_chain_disable
drm_atomic_commit
drm_atomic_get_connector_state
drm_atomic_get_crtc_state
@@ -753,6 +755,7 @@
drm_mode_object_find
drm_mode_object_get
drm_mode_object_put
drm_mode_parse_command_line_for_connector
drm_mode_probed_add
drm_modeset_acquire_fini
drm_modeset_acquire_init
@@ -963,6 +966,7 @@
gpiod_get_raw_value_cansleep
gpiod_get_value
gpiod_get_value_cansleep
gpiod_set_debounce
gpiod_set_raw_value
gpiod_set_raw_value_cansleep
gpiod_set_value
@@ -1051,6 +1055,7 @@
__init_swait_queue_head
init_task
init_timer_key
init_user_ns
init_wait_entry
__init_waitqueue_head
input_alloc_absinfo
@@ -1092,6 +1097,7 @@
iommu_device_sysfs_remove
iommu_device_unlink
iommu_device_unregister
iommu_dma_enable_best_fit_algo
iommu_domain_alloc
iommu_domain_free
iommu_fwspec_add_ids
@@ -1373,6 +1379,7 @@
nr_cpu_ids
nr_irqs
ns_capable
ns_capable_noaudit
nsec_to_clock_t
ns_to_timespec64
__num_online_cpus
@@ -2237,6 +2244,7 @@
__traceiter_android_vh_cpu_idle_exit
__traceiter_android_vh_dump_throttled_rt_tasks
__traceiter_android_vh_dup_task_struct
__traceiter_android_vh_early_resume_begin
__traceiter_android_vh_enable_thermal_genl_check
__traceiter_android_vh_ep_create_wakeup_source
__traceiter_android_vh_get_user_pages
@@ -2249,6 +2257,8 @@
__traceiter_android_vh_of_i2c_get_board_info
__traceiter_android_vh_pagecache_get_page
__traceiter_android_vh_pin_user_pages
__traceiter_android_vh_rebuild_root_domains_bypass
__traceiter_android_vh_resume_end
__traceiter_android_vh_rmqueue
__traceiter_android_vh_sched_setaffinity_early
__traceiter_android_vh_scheduler_tick
@@ -2351,6 +2361,7 @@
__tracepoint_android_vh_cpu_idle_exit
__tracepoint_android_vh_dump_throttled_rt_tasks
__tracepoint_android_vh_dup_task_struct
__tracepoint_android_vh_early_resume_begin
__tracepoint_android_vh_enable_thermal_genl_check
__tracepoint_android_vh_ep_create_wakeup_source
__tracepoint_android_vh_get_user_pages
@@ -2363,6 +2374,8 @@
__tracepoint_android_vh_of_i2c_get_board_info
__tracepoint_android_vh_pagecache_get_page
__tracepoint_android_vh_pin_user_pages
__tracepoint_android_vh_rebuild_root_domains_bypass
__tracepoint_android_vh_resume_end
__tracepoint_android_vh_rmqueue
__tracepoint_android_vh_sched_setaffinity_early
__tracepoint_android_vh_scheduler_tick
@@ -2666,6 +2679,7 @@
xa_find
xa_find_after
xa_get_mark
__xa_insert
xa_load
xa_set_mark
xa_store

View File

@@ -0,0 +1,5 @@
[abi_symbol_list]
# for type visibility
GKI_struct_blk_mq_alloc_data
GKI_struct_cgroup_taskset

View File

@@ -76,10 +76,10 @@ CPPFLAGS_vmlinux.lds += -DTEXT_OFFSET="$(TEXT_OFFSET)"
CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)"
compress-$(CONFIG_KERNEL_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO) = lzo
compress-$(CONFIG_KERNEL_LZMA) = lzma
compress-$(CONFIG_KERNEL_XZ) = xzkern
compress-$(CONFIG_KERNEL_LZ4) = lz4
compress-$(CONFIG_KERNEL_LZO) = lzo_with_size
compress-$(CONFIG_KERNEL_LZMA) = lzma_with_size
compress-$(CONFIG_KERNEL_XZ) = xzkern_with_size
compress-$(CONFIG_KERNEL_LZ4) = lz4_with_size
libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o

View File

@@ -919,7 +919,7 @@ static void do_handle_IPI(int ipinr)
break;
case IPI_CPU_STOP:
trace_android_vh_ipi_stop_rcuidle(get_irq_regs());
trace_android_vh_ipi_stop(get_irq_regs());
local_cpu_stop();
break;

View File

@@ -2286,6 +2286,16 @@ static int __init early_kvm_mode_cfg(char *arg)
if (!arg)
return -EINVAL;
if (strcmp(arg, "none") == 0) {
kvm_mode = KVM_MODE_NONE;
return 0;
}
if (!is_hyp_mode_available()) {
pr_warn_once("KVM is not available. Ignoring kvm-arm.mode\n");
return 0;
}
if (strcmp(arg, "protected") == 0) {
if (!is_kernel_in_hyp_mode())
kvm_mode = KVM_MODE_PROTECTED;
@@ -2300,11 +2310,6 @@ static int __init early_kvm_mode_cfg(char *arg)
return 0;
}
if (strcmp(arg, "none") == 0) {
kvm_mode = KVM_MODE_NONE;
return 0;
}
return -EINVAL;
}
early_param("kvm-arm.mode", early_kvm_mode_cfg);

View File

@@ -414,6 +414,15 @@ static int set_host_vcpus(struct shadow_vcpu_state *shadow_vcpus, int nr_vcpus,
return 0;
}
static int init_ptrauth(struct kvm_vcpu *shadow_vcpu)
{
int ret = 0;
if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, shadow_vcpu->arch.features) ||
test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, shadow_vcpu->arch.features))
ret = kvm_vcpu_enable_ptrauth(shadow_vcpu);
return ret;
}
static int init_shadow_structs(struct kvm *kvm, struct kvm_shadow_vm *vm,
struct kvm_vcpu **vcpu_array, int nr_vcpus)
{
@@ -438,6 +447,10 @@ static int init_shadow_structs(struct kvm *kvm, struct kvm_shadow_vm *vm,
if (ret)
return ret;
ret = init_ptrauth(shadow_vcpu);
if (ret)
return ret;
if (test_bit(KVM_ARM_VCPU_SVE, shadow_vcpu->arch.features)) {
size_t sve_state_size;
void *sve_state;
@@ -851,14 +864,7 @@ void pkvm_reset_vcpu(struct kvm_vcpu *vcpu)
WARN_ON(!reset_state->reset);
if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features)) {
/*
* This call should not fail since we've already checked for
* feature support on initialization.
*/
WARN_ON(kvm_vcpu_enable_ptrauth(vcpu));
}
init_ptrauth(vcpu);
/* Reset core registers */
memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));

View File

@@ -30,9 +30,11 @@ $(obj)/vmlinux.bin: vmlinux FORCE
suffix-$(CONFIG_KERNEL_GZIP) := gzip
suffix-$(CONFIG_KERNEL_LZO) := lzo
compress-$(CONFIG_KERNEL_GZIP) := gzip
compress-$(CONFIG_KERNEL_LZO) := lzo_with_size
$(obj)/vmlinux.bin.$(suffix-y): $(obj)/vmlinux.bin FORCE
$(call if_changed,$(suffix-y))
$(call if_changed,$(compress-y))
LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300-linux -T
OBJCOPYFLAGS := -O binary

View File

@@ -71,12 +71,12 @@ $(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
$(call if_changed,objcopy)
tool_$(CONFIG_KERNEL_GZIP) = gzip
tool_$(CONFIG_KERNEL_BZIP2) = bzip2
tool_$(CONFIG_KERNEL_LZ4) = lz4
tool_$(CONFIG_KERNEL_LZMA) = lzma
tool_$(CONFIG_KERNEL_LZO) = lzo
tool_$(CONFIG_KERNEL_XZ) = xzkern
tool_$(CONFIG_KERNEL_ZSTD) = zstd22
tool_$(CONFIG_KERNEL_BZIP2) = bzip2_with_size
tool_$(CONFIG_KERNEL_LZ4) = lz4_with_size
tool_$(CONFIG_KERNEL_LZMA) = lzma_with_size
tool_$(CONFIG_KERNEL_LZO) = lzo_with_size
tool_$(CONFIG_KERNEL_XZ) = xzkern_with_size
tool_$(CONFIG_KERNEL_ZSTD) = zstd22_with_size
targets += vmlinux.bin.z
$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE

View File

@@ -73,15 +73,15 @@ suffix-$(CONFIG_KERNEL_XZ) := xz
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
$(call if_changed,bzip2)
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
$(call if_changed,lz4)
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
$(call if_changed,lzma)
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
$(call if_changed,lzo)
$(call if_changed,lzo_with_size)
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
$(call if_changed,xzkern)
$(call if_changed,xzkern_with_size)
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)

View File

@@ -49,15 +49,15 @@ suffix-$(CONFIG_KERNEL_XZ) := .xz
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lz4)
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzo)
$(call if_changed,lzo_with_size)
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,xzkern)
$(call if_changed,xzkern_with_size)
OBJCOPYFLAGS_piggy.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.bin.compressed
$(obj)/piggy.o: $(obj)/vmlinux.bin$(suffix-y) FORCE

View File

@@ -58,13 +58,13 @@ vmlinux.bin.all-y := $(obj)/vmlinux.bin
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,xzkern)
$(call if_changed,xzkern_with_size)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzo)
$(call if_changed,lzo_with_size)
OBJCOPYFLAGS += -R .empty_zero_page

View File

@@ -125,17 +125,17 @@ vmlinux.bin.all-$(CONFIG_X86_NEED_RELOCS) += $(obj)/vmlinux.relocs
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
$(call if_changed,bzip2)
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzma)
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
$(call if_changed,xzkern)
$(call if_changed,xzkern_with_size)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lzo)
$(call if_changed,lzo_with_size)
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
$(call if_changed,lz4)
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.zst: $(vmlinux.bin.all-y) FORCE
$(call if_changed,zstd22)
$(call if_changed,zstd22_with_size)
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2

View File

@@ -7289,7 +7289,7 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_skip_emulated_instruction);
static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r)
static bool kvm_vcpu_check_code_breakpoint(struct kvm_vcpu *vcpu, int *r)
{
if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) &&
(vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) {
@@ -7358,25 +7358,23 @@ static bool is_vmware_backdoor_opcode(struct x86_emulate_ctxt *ctxt)
}
/*
* Decode to be emulated instruction. Return EMULATION_OK if success.
* Decode an instruction for emulation. The caller is responsible for handling
* code breakpoints. Note, manually detecting code breakpoints is unnecessary
* (and wrong) when emulating on an intercepted fault-like exception[*], as
* code breakpoints have higher priority and thus have already been done by
* hardware.
*
* [*] Except #MC, which is higher priority, but KVM should never emulate in
* response to a machine check.
*/
int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
void *insn, int insn_len)
{
int r = EMULATION_OK;
struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
int r;
init_emulate_ctxt(vcpu);
/*
* We will reenter on the same instruction since we do not set
* complete_userspace_io. This does not handle watchpoints yet,
* those would be handled in the emulate_ops.
*/
if (!(emulation_type & EMULTYPE_SKIP) &&
kvm_vcpu_check_breakpoint(vcpu, &r))
return r;
ctxt->ud = emulation_type & EMULTYPE_TRAP_UD;
r = x86_decode_insn(ctxt, insn, insn_len);
@@ -7411,6 +7409,15 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
kvm_clear_exception_queue(vcpu);
/*
* Return immediately if RIP hits a code breakpoint, such #DBs
* are fault-like and are higher priority than any faults on
* the code fetch itself.
*/
if (!(emulation_type & EMULTYPE_SKIP) &&
kvm_vcpu_check_code_breakpoint(vcpu, &r))
return r;
r = x86_decode_emulated_instruction(vcpu, emulation_type,
insn, insn_len);
if (r != EMULATION_OK) {

View File

@@ -39,3 +39,4 @@ obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
obj-$(CONFIG_BLK_PM) += blk-pm.o
obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o blk-crypto.o
obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o
obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o

24
block/vendor_hooks.c Normal file
View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-only
/* vendor_hook.c
*
* Copyright 2022 Google LLC
*/
#include "blk.h"
#include "blk-mq-tag.h"
#include "blk-mq.h"
#include <linux/blk-mq.h>
#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <linux/tracepoint.h>
#include <trace/hooks/block.h>
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_alloc_rqs);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_rq_ctx_init);
/*
* For type visibility
*/
const struct blk_mq_alloc_data *GKI_struct_blk_mq_alloc_data;
EXPORT_SYMBOL_GPL(GKI_struct_blk_mq_alloc_data);

View File

@@ -7,11 +7,11 @@ Image.lz4
Image.gz
"
# Sync with BUILD.bazel
ABI_DEFINITION=android/abi_gki_aarch64.xml
# Update BUILD.bazel, define_common_kernels() if the list differs from
# android/abi_gki_aarch64* in the filesystem.
KMI_SYMBOL_LIST=android/abi_gki_aarch64
ADDITIONAL_KMI_SYMBOL_LISTS="
android/abi_gki_aarch64_type_visibility
android/abi_gki_aarch64_core
android/abi_gki_aarch64_fips140
android/abi_gki_aarch64_generic

View File

@@ -5,5 +5,7 @@
BUILD_SYSTEM_DLKM=1
MODULES_LIST=${ROOT_DIR}/${KERNEL_DIR}/android/gki_system_dlkm_modules
BUILD_GKI_CERTIFICATION_TOOLS=1
BUILD_GKI_ARTIFACTS=1
BUILD_GKI_BOOT_IMG_SIZE=67108864

View File

@@ -117,6 +117,22 @@ struct rand_data {
#define JENT_EHEALTH 9 /* Health test failed during initialization */
#define JENT_ERCT 10 /* RCT failed during initialization */
/*
* The output n bits can receive more than n bits of min entropy, of course,
* but the fixed output of the conditioning function can only asymptotically
* approach the output size bits of min entropy, not attain that bound. Random
* maps will tend to have output collisions, which reduces the creditable
* output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound).
*
* The value "64" is justified in Appendix A.4 of the current 90C draft,
* and aligns with NIST's in "epsilon" definition in this document, which is
* that a string can be considered "full entropy" if you can bound the min
* entropy in each bit of output to at least 1-epsilon, where epsilon is
* required to be <= 2^(-32).
*/
#define JENT_ENTROPY_SAFETY_FACTOR 64
#include <linux/fips.h>
#include "jitterentropy.h"
/***************************************************************************
@@ -546,7 +562,10 @@ static int jent_measure_jitter(struct rand_data *ec)
*/
static void jent_gen_entropy(struct rand_data *ec)
{
unsigned int k = 0;
unsigned int k = 0, safety_factor = 0;
if (fips_enabled)
safety_factor = JENT_ENTROPY_SAFETY_FACTOR;
/* priming of the ->prev_time value */
jent_measure_jitter(ec);
@@ -560,7 +579,7 @@ static void jent_gen_entropy(struct rand_data *ec)
* We multiply the loop value with ->osr to obtain the
* oversampling rate requested by the caller
*/
if (++k >= (DATA_SIZE_BITS * ec->osr))
if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
break;
}
}

View File

@@ -5,6 +5,28 @@
*
* Copyright 2020 Google LLC
*/
#ifndef __GENKSYMS__
#include <uapi/linux/hdreg.h>
#include <net/addrconf.h>
#include <linux/fsverity.h>
#include <linux/ipc_namespace.h>
#include <linux/key-type.h>
#include <linux/mtd/mtd.h>
#include <linux/pr.h>
#include <linux/time_namespace.h>
#include <net/macsec.h>
#include <net/netfilter/nf_log.h>
#include <net/raw.h>
#include <net/smc.h>
#include <../drivers/net/wireless/intel/ipw2x00/libipw.h>
#include <../fs/mount.h>
#include <../fs/kernfs/kernfs-internal.h>
#include <../kernel/audit.h>
#include <../net/can/af_can.h>
#include <../net/tipc/bearer.h>
#include <../net/xdp/xsk_queue.h>
#include <../security/keys/internal.h>
#endif
#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
@@ -19,7 +41,6 @@
#include <trace/hooks/topology.h>
#include <trace/hooks/mpam.h>
#include <trace/hooks/gic.h>
#include <trace/hooks/wqlockup.h>
#include <trace/hooks/debug.h>
#include <trace/hooks/sysrqcrash.h>
#include <trace/hooks/printk.h>
@@ -40,8 +61,9 @@
#include <trace/hooks/iommu.h>
#include <trace/hooks/thermal.h>
#include <trace/hooks/ufshcd.h>
#include <trace/hooks/block.h>
#ifdef __GENKSYMS__
#include <trace/hooks/cgroup.h>
#endif
#include <trace/hooks/workqueue.h>
#include <trace/hooks/sys.h>
#include <trace/hooks/traps.h>
@@ -83,7 +105,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_select_task_rq_fair);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_select_task_rq_rt);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_select_task_rq_dl);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_select_fallback_rq);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_refrigerator);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_scheduler_tick);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_enqueue_task);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_task);
@@ -126,7 +147,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mpam_set);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_busiest_group);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_resume);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_wq_lockup_pool);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ipi_stop);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sysrq_crash);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dump_throttled_rt_tasks);
@@ -228,8 +248,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_uclamp_eff_get);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_uclamp_task_util);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_uclamp_rq_util_with);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpufreq_transition);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_set_task);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_syscall_prctl_finished);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_create_worker);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_tick);
@@ -248,8 +266,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_insert);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_delete);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_replace);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_lookup);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_alloc_rqs);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_rq_ctx_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_commit_creds);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_creds);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_override_creds);
@@ -296,7 +312,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_swappiness);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_slab_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_psi_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_psi_group);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpuset_fork);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_cpus_allowed_comm);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_setaffinity_early);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_task);
@@ -314,7 +329,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_is_initialized);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_inactive_ratio);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_update_topology_flags_workfn);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_of_i2c_get_board_info);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_attach);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_dirty_limits);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_oom_check_panic);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterruptible_tasks);
@@ -395,3 +409,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmput);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_early_resume_begin);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_reclaim_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_failure_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rebuild_root_domains_bypass);

View File

@@ -1252,6 +1252,7 @@ bad:
static struct target_type verity_target = {
.name = "verity",
.version = {1, 7, 0},
.features = DM_TARGET_IMMUTABLE,
.module = THIS_MODULE,
.ctr = verity_ctr,
.dtr = verity_dtr,

View File

@@ -597,7 +597,7 @@ struct mac80211_hwsim_data {
bool ps_poll_pending;
struct dentry *debugfs;
uintptr_t pending_cookie;
atomic_t pending_cookie;
struct sk_buff_head pending; /* packets pending */
/*
* Only radios in the same group can communicate together (the
@@ -1273,8 +1273,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
goto nla_put_failure;
/* We create a cookie to identify this skb */
data->pending_cookie++;
cookie = data->pending_cookie;
cookie = atomic_inc_return(&data->pending_cookie);
info->rate_driver_data[0] = (void *)cookie;
if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
goto nla_put_failure;
@@ -3511,6 +3510,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
const u8 *src;
unsigned int hwsim_flags;
int i;
unsigned long flags;
bool found = false;
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
@@ -3538,18 +3538,20 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
}
/* look for the skb matching the cookie passed back from user */
spin_lock_irqsave(&data2->pending.lock, flags);
skb_queue_walk_safe(&data2->pending, skb, tmp) {
u64 skb_cookie;
uintptr_t skb_cookie;
txi = IEEE80211_SKB_CB(skb);
skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];
skb_cookie = (uintptr_t)txi->rate_driver_data[0];
if (skb_cookie == ret_skb_cookie) {
skb_unlink(skb, &data2->pending);
__skb_unlink(skb, &data2->pending);
found = true;
break;
}
}
spin_unlock_irqrestore(&data2->pending.lock, flags);
/* not found */
if (!found)

View File

@@ -4553,7 +4553,7 @@ static int ufshcd_complete_dev_init(struct ufs_hba *hba)
QUERY_FLAG_IDN_FDEVICEINIT, 0, &flag_res);
if (!flag_res)
break;
usleep_range(5000, 10000);
usleep_range(500, 1000);
} while (ktime_before(ktime_get(), timeout));
if (err) {

View File

@@ -770,12 +770,9 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
/* wake up the caller thread for sync decompression */
if (sync) {
unsigned long flags;
spin_lock_irqsave(&io->u.wait.lock, flags);
if (!atomic_add_return(bios, &io->pending_bios))
wake_up_locked(&io->u.wait);
spin_unlock_irqrestore(&io->u.wait.lock, flags);
complete(&io->u.done);
return;
}
@@ -1186,7 +1183,7 @@ jobqueue_init(struct super_block *sb,
} else {
fg_out:
q = fgq;
init_waitqueue_head(&fgq->u.wait);
init_completion(&fgq->u.done);
atomic_set(&fgq->pending_bios, 0);
}
q->sb = sb;
@@ -1360,8 +1357,7 @@ static void z_erofs_runqueue(struct super_block *sb,
return;
/* wait until all bios are completed */
io_wait_event(io[JQ_SUBMIT].u.wait,
!atomic_read(&io[JQ_SUBMIT].pending_bios));
wait_for_completion_io(&io[JQ_SUBMIT].u.done);
/* handle synchronous decompress queue in the caller context */
z_erofs_decompress_queue(&io[JQ_SUBMIT], pagepool);

View File

@@ -89,7 +89,7 @@ struct z_erofs_decompressqueue {
z_erofs_next_pcluster_t head;
union {
wait_queue_head_t wait;
struct completion done;
struct work_struct work;
} u;
};

View File

@@ -26,12 +26,16 @@
static struct kmem_cache *ino_entry_slab;
struct kmem_cache *f2fs_inode_entry_slab;
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
unsigned char reason)
{
f2fs_build_fault_attr(sbi, 0, 0);
set_ckpt_flags(sbi, CP_ERROR_FLAG);
if (!end_io)
if (!end_io) {
f2fs_flush_merged_writes(sbi);
f2fs_handle_stop(sbi, reason);
}
}
/*
@@ -122,7 +126,7 @@ retry:
if (PTR_ERR(page) == -EIO &&
++count <= DEFAULT_RETRY_IO_COUNT)
goto retry;
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
}
return page;
}
@@ -1895,15 +1899,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi)
{
struct ckpt_req_control *cprc = &sbi->cprc_info;
struct task_struct *ckpt_task;
if (cprc->f2fs_issue_ckpt) {
struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt;
if (!cprc->f2fs_issue_ckpt)
return;
cprc->f2fs_issue_ckpt = NULL;
kthread_stop(ckpt_task);
ckpt_task = cprc->f2fs_issue_ckpt;
cprc->f2fs_issue_ckpt = NULL;
kthread_stop(ckpt_task);
flush_remained_ckpt_reqs(sbi, NULL);
}
f2fs_flush_ckpt_thread(sbi);
}
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
{
struct ckpt_req_control *cprc = &sbi->cprc_info;
flush_remained_ckpt_reqs(sbi, NULL);
/* Let's wait for the previous dispatched checkpoint. */
while (atomic_read(&cprc->queued_ckpt))
io_schedule_timeout(DEFAULT_IO_TIMEOUT);
}
void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)

View File

@@ -728,14 +728,19 @@ out:
return ret;
}
void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
bool pre_alloc);
static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,
bool bypass_destroy_callback, bool pre_alloc);
void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode);
struct f2fs_inode_info *fi = F2FS_I(dic->inode);
const struct f2fs_compress_ops *cops =
f2fs_cops[fi->i_compress_algorithm];
bool bypass_callback = false;
int ret;
int i;
trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx,
dic->cluster_size, fi->i_compress_algorithm);
@@ -745,41 +750,10 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
goto out_end_io;
}
dic->tpages = page_array_alloc(dic->inode, dic->cluster_size);
if (!dic->tpages) {
ret = -ENOMEM;
goto out_end_io;
}
for (i = 0; i < dic->cluster_size; i++) {
if (dic->rpages[i]) {
dic->tpages[i] = dic->rpages[i];
continue;
}
dic->tpages[i] = f2fs_compress_alloc_page();
if (!dic->tpages[i]) {
ret = -ENOMEM;
goto out_end_io;
}
}
if (cops->init_decompress_ctx) {
ret = cops->init_decompress_ctx(dic);
if (ret)
goto out_end_io;
}
dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size);
if (!dic->rbuf) {
ret = -ENOMEM;
goto out_destroy_decompress_ctx;
}
dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages);
if (!dic->cbuf) {
ret = -ENOMEM;
goto out_vunmap_rbuf;
ret = f2fs_prepare_decomp_mem(dic, false);
if (ret) {
bypass_callback = true;
goto out_release;
}
dic->clen = le32_to_cpu(dic->cbuf->clen);
@@ -787,7 +761,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) {
ret = -EFSCORRUPTED;
goto out_vunmap_cbuf;
goto out_release;
}
ret = cops->decompress_pages(dic);
@@ -808,17 +782,13 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
}
}
out_vunmap_cbuf:
vm_unmap_ram(dic->cbuf, dic->nr_cpages);
out_vunmap_rbuf:
vm_unmap_ram(dic->rbuf, dic->cluster_size);
out_destroy_decompress_ctx:
if (cops->destroy_decompress_ctx)
cops->destroy_decompress_ctx(dic);
out_release:
f2fs_release_decomp_mem(dic, bypass_callback, false);
out_end_io:
trace_f2fs_decompress_pages_end(dic->inode, dic->cluster_idx,
dic->clen, ret);
f2fs_decompress_end_io(dic, ret);
f2fs_decompress_end_io(dic, ret, in_task);
}
/*
@@ -828,7 +798,7 @@ out_end_io:
* (or in the case of a failure, cleans up without actually decompressing).
*/
void f2fs_end_read_compressed_page(struct page *page, bool failed,
block_t blkaddr)
block_t blkaddr, bool in_task)
{
struct decompress_io_ctx *dic =
(struct decompress_io_ctx *)page_private(page);
@@ -838,12 +808,12 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed,
if (failed)
WRITE_ONCE(dic->failed, true);
else if (blkaddr)
else if (blkaddr && in_task)
f2fs_cache_compressed_page(sbi, page,
dic->inode->i_ino, blkaddr);
if (atomic_dec_and_test(&dic->remaining_pages))
f2fs_decompress_cluster(dic);
f2fs_decompress_cluster(dic, in_task);
}
static bool is_page_in_cluster(struct compress_ctx *cc, pgoff_t index)
@@ -1551,16 +1521,85 @@ destroy_out:
return err;
}
static void f2fs_free_dic(struct decompress_io_ctx *dic);
static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi,
bool pre_alloc)
{
return pre_alloc ^ f2fs_low_mem_mode(sbi);
}
static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
bool pre_alloc)
{
const struct f2fs_compress_ops *cops =
f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
int i;
if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
return 0;
dic->tpages = page_array_alloc(dic->inode, dic->cluster_size);
if (!dic->tpages)
return -ENOMEM;
for (i = 0; i < dic->cluster_size; i++) {
if (dic->rpages[i]) {
dic->tpages[i] = dic->rpages[i];
continue;
}
dic->tpages[i] = f2fs_compress_alloc_page();
if (!dic->tpages[i])
return -ENOMEM;
}
dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size);
if (!dic->rbuf)
return -ENOMEM;
dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages);
if (!dic->cbuf)
return -ENOMEM;
if (cops->init_decompress_ctx) {
int ret = cops->init_decompress_ctx(dic);
if (ret)
return ret;
}
return 0;
}
static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,
bool bypass_destroy_callback, bool pre_alloc)
{
const struct f2fs_compress_ops *cops =
f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
return;
if (!bypass_destroy_callback && cops->destroy_decompress_ctx)
cops->destroy_decompress_ctx(dic);
if (dic->cbuf)
vm_unmap_ram(dic->cbuf, dic->nr_cpages);
if (dic->rbuf)
vm_unmap_ram(dic->rbuf, dic->cluster_size);
}
static void f2fs_free_dic(struct decompress_io_ctx *dic,
bool bypass_destroy_callback);
struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
{
struct decompress_io_ctx *dic;
pgoff_t start_idx = start_idx_of_cluster(cc);
int i;
struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode);
int i, ret;
dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO,
false, F2FS_I_SB(cc->inode));
dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, false, sbi);
if (!dic)
return ERR_PTR(-ENOMEM);
@@ -1586,32 +1625,43 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
dic->nr_rpages = cc->cluster_size;
dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages);
if (!dic->cpages)
if (!dic->cpages) {
ret = -ENOMEM;
goto out_free;
}
for (i = 0; i < dic->nr_cpages; i++) {
struct page *page;
page = f2fs_compress_alloc_page();
if (!page)
if (!page) {
ret = -ENOMEM;
goto out_free;
}
f2fs_set_compressed_page(page, cc->inode,
start_idx + i + 1, dic);
dic->cpages[i] = page;
}
ret = f2fs_prepare_decomp_mem(dic, true);
if (ret)
goto out_free;
return dic;
out_free:
f2fs_free_dic(dic);
return ERR_PTR(-ENOMEM);
f2fs_free_dic(dic, true);
return ERR_PTR(ret);
}
static void f2fs_free_dic(struct decompress_io_ctx *dic)
static void f2fs_free_dic(struct decompress_io_ctx *dic,
bool bypass_destroy_callback)
{
int i;
f2fs_release_decomp_mem(dic, bypass_destroy_callback, true);
if (dic->tpages) {
for (i = 0; i < dic->cluster_size; i++) {
if (dic->rpages[i])
@@ -1636,17 +1686,33 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic)
kmem_cache_free(dic_entry_slab, dic);
}
static void f2fs_put_dic(struct decompress_io_ctx *dic)
static void f2fs_late_free_dic(struct work_struct *work)
{
if (refcount_dec_and_test(&dic->refcnt))
f2fs_free_dic(dic);
struct decompress_io_ctx *dic =
container_of(work, struct decompress_io_ctx, free_work);
f2fs_free_dic(dic, false);
}
static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task)
{
if (refcount_dec_and_test(&dic->refcnt)) {
if (in_task) {
f2fs_free_dic(dic, false);
} else {
INIT_WORK(&dic->free_work, f2fs_late_free_dic);
queue_work(F2FS_I_SB(dic->inode)->post_read_wq,
&dic->free_work);
}
}
}
/*
* Update and unlock the cluster's pagecache pages, and release the reference to
* the decompress_io_ctx that was being held for I/O completion.
*/
static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
bool in_task)
{
int i;
@@ -1667,7 +1733,7 @@ static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
unlock_page(rpage);
}
f2fs_put_dic(dic);
f2fs_put_dic(dic, in_task);
}
static void f2fs_verify_cluster(struct work_struct *work)
@@ -1684,14 +1750,15 @@ static void f2fs_verify_cluster(struct work_struct *work)
SetPageError(rpage);
}
__f2fs_decompress_end_io(dic, false);
__f2fs_decompress_end_io(dic, false, true);
}
/*
* This is called when a compressed cluster has been decompressed
* (or failed to be read and/or decompressed).
*/
void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
bool in_task)
{
if (!failed && dic->need_verity) {
/*
@@ -1703,7 +1770,7 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
INIT_WORK(&dic->verity_work, f2fs_verify_cluster);
fsverity_enqueue_verify_work(&dic->verity_work);
} else {
__f2fs_decompress_end_io(dic, failed);
__f2fs_decompress_end_io(dic, failed, in_task);
}
}
@@ -1712,12 +1779,12 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
*
* This is called when the page is no longer needed and can be freed.
*/
void f2fs_put_page_dic(struct page *page)
void f2fs_put_page_dic(struct page *page, bool in_task)
{
struct decompress_io_ctx *dic =
(struct decompress_io_ctx *)page_private(page);
f2fs_put_dic(dic);
f2fs_put_dic(dic, in_task);
}
/*

View File

@@ -122,7 +122,7 @@ struct bio_post_read_ctx {
block_t fs_blkaddr;
};
static void f2fs_finish_read_bio(struct bio *bio)
static void f2fs_finish_read_bio(struct bio *bio, bool in_task)
{
struct bio_vec *bv;
struct bvec_iter_all iter_all;
@@ -136,8 +136,9 @@ static void f2fs_finish_read_bio(struct bio *bio)
if (f2fs_is_compressed_page(page)) {
if (bio->bi_status)
f2fs_end_read_compressed_page(page, true, 0);
f2fs_put_page_dic(page);
f2fs_end_read_compressed_page(page, true, 0,
in_task);
f2fs_put_page_dic(page, in_task);
continue;
}
@@ -194,7 +195,7 @@ static void f2fs_verify_bio(struct work_struct *work)
fsverity_verify_bio(bio);
}
f2fs_finish_read_bio(bio);
f2fs_finish_read_bio(bio, true);
}
/*
@@ -206,7 +207,7 @@ static void f2fs_verify_bio(struct work_struct *work)
* can involve reading verity metadata pages from the file, and these verity
* metadata pages may be encrypted and/or compressed.
*/
static void f2fs_verify_and_finish_bio(struct bio *bio)
static void f2fs_verify_and_finish_bio(struct bio *bio, bool in_task)
{
struct bio_post_read_ctx *ctx = bio->bi_private;
@@ -214,7 +215,7 @@ static void f2fs_verify_and_finish_bio(struct bio *bio)
INIT_WORK(&ctx->work, f2fs_verify_bio);
fsverity_enqueue_verify_work(&ctx->work);
} else {
f2fs_finish_read_bio(bio);
f2fs_finish_read_bio(bio, in_task);
}
}
@@ -227,7 +228,8 @@ static void f2fs_verify_and_finish_bio(struct bio *bio)
* that the bio includes at least one compressed page. The actual decompression
* is done on a per-cluster basis, not a per-bio basis.
*/
static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx)
static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx,
bool in_task)
{
struct bio_vec *bv;
struct bvec_iter_all iter_all;
@@ -240,7 +242,7 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx)
/* PG_error was set if decryption failed. */
if (f2fs_is_compressed_page(page))
f2fs_end_read_compressed_page(page, PageError(page),
blkaddr);
blkaddr, in_task);
else
all_compressed = false;
@@ -265,15 +267,16 @@ static void f2fs_post_read_work(struct work_struct *work)
fscrypt_decrypt_bio(ctx->bio);
if (ctx->enabled_steps & STEP_DECOMPRESS)
f2fs_handle_step_decompress(ctx);
f2fs_handle_step_decompress(ctx, true);
f2fs_verify_and_finish_bio(ctx->bio);
f2fs_verify_and_finish_bio(ctx->bio, true);
}
static void f2fs_read_end_io(struct bio *bio)
{
struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio));
struct bio_post_read_ctx *ctx;
bool intask = in_task();
iostat_update_and_unbind_ctx(bio, 0);
ctx = bio->bi_private;
@@ -284,16 +287,29 @@ static void f2fs_read_end_io(struct bio *bio)
}
if (bio->bi_status) {
f2fs_finish_read_bio(bio);
f2fs_finish_read_bio(bio, intask);
return;
}
if (ctx && (ctx->enabled_steps & (STEP_DECRYPT | STEP_DECOMPRESS))) {
INIT_WORK(&ctx->work, f2fs_post_read_work);
queue_work(ctx->sbi->post_read_wq, &ctx->work);
} else {
f2fs_verify_and_finish_bio(bio);
if (ctx) {
unsigned int enabled_steps = ctx->enabled_steps &
(STEP_DECRYPT | STEP_DECOMPRESS);
/*
* If we have only decompression step between decompression and
* decrypt, we don't need post processing for this.
*/
if (enabled_steps == STEP_DECOMPRESS &&
!f2fs_low_mem_mode(sbi)) {
f2fs_handle_step_decompress(ctx, intask);
} else if (enabled_steps) {
INIT_WORK(&ctx->work, f2fs_post_read_work);
queue_work(ctx->sbi->post_read_wq, &ctx->work);
return;
}
}
f2fs_verify_and_finish_bio(bio, intask);
}
static void f2fs_write_end_io(struct bio *bio)
@@ -320,7 +336,8 @@ static void f2fs_write_end_io(struct bio *bio)
mempool_free(page, sbi->write_io_dummy);
if (unlikely(bio->bi_status))
f2fs_stop_checkpoint(sbi, true);
f2fs_stop_checkpoint(sbi, true,
STOP_CP_REASON_WRITE_FAIL);
continue;
}
@@ -336,7 +353,8 @@ static void f2fs_write_end_io(struct bio *bio)
if (unlikely(bio->bi_status)) {
mapping_set_error(page->mapping, -EIO);
if (type == F2FS_WB_CP_DATA)
f2fs_stop_checkpoint(sbi, true);
f2fs_stop_checkpoint(sbi, true,
STOP_CP_REASON_WRITE_FAIL);
}
f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
@@ -2228,7 +2246,7 @@ skip_reading_dnode:
if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
if (atomic_dec_and_test(&dic->remaining_pages))
f2fs_decompress_cluster(dic);
f2fs_decompress_cluster(dic, true);
continue;
}
@@ -2246,7 +2264,7 @@ submit_and_realloc:
page->index, for_write);
if (IS_ERR(bio)) {
ret = PTR_ERR(bio);
f2fs_decompress_end_io(dic, ret);
f2fs_decompress_end_io(dic, ret, true);
f2fs_put_dnode(&dn);
*bio_ret = NULL;
return ret;
@@ -2533,7 +2551,7 @@ bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio)
return true;
/* if this is cold file, we should overwrite to avoid fragmentation */
if (file_is_cold(inode))
if (file_is_cold(inode) && !is_inode_flag_set(inode, FI_OPU_WRITE))
return true;
return check_inplace_update_policy(inode, fio);

View File

@@ -159,6 +159,7 @@ struct f2fs_mount_info {
int fsync_mode; /* fsync policy */
int fs_mode; /* fs mode: LFS or ADAPTIVE */
int bggc_mode; /* bggc mode: off, on or sync */
int memory_mode; /* memory mode */
int discard_unit; /*
* discard command's offset/size should
* be aligned to this unit: block,
@@ -1369,6 +1370,13 @@ enum {
DISCARD_UNIT_SECTION, /* basic discard unit is section */
};
enum {
MEMORY_MODE_NORMAL, /* memory mode for normal devices */
MEMORY_MODE_LOW, /* memory mode for low memry devices */
};
static inline int f2fs_test_bit(unsigned int nr, char *addr);
static inline void f2fs_set_bit(unsigned int nr, char *addr);
static inline void f2fs_clear_bit(unsigned int nr, char *addr);
@@ -1589,6 +1597,7 @@ struct decompress_io_ctx {
void *private; /* payload buffer for specified decompression algorithm */
void *private2; /* extra payload buffer */
struct work_struct verity_work; /* work to verify the decompressed pages */
struct work_struct free_work; /* work for late free this structure itself */
};
#define NULL_CLUSTER ((unsigned int)(~0))
@@ -1721,7 +1730,6 @@ struct f2fs_sb_info {
unsigned int gc_mode; /* current GC state */
unsigned int next_victim_seg[2]; /* next segment in victim section */
spinlock_t gc_urgent_high_lock;
bool gc_urgent_high_limited; /* indicates having limited trial count */
unsigned int gc_urgent_high_remaining; /* remaining trial count for GC_URGENT_HIGH */
/* for skip statistic */
@@ -3512,6 +3520,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
int f2fs_quota_sync(struct super_block *sb, int type);
loff_t max_file_blocks(struct inode *inode);
void f2fs_quota_off_umount(struct super_block *sb);
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason);
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
int f2fs_sync_fs(struct super_block *sb, int sync);
int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
@@ -3676,7 +3685,9 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi)
/*
* checkpoint.c
*/
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
unsigned char reason);
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index);
@@ -4181,9 +4192,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page);
bool f2fs_is_compress_backend_ready(struct inode *inode);
int f2fs_init_compress_mempool(void);
void f2fs_destroy_compress_mempool(void);
void f2fs_decompress_cluster(struct decompress_io_ctx *dic);
void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task);
void f2fs_end_read_compressed_page(struct page *page, bool failed,
block_t blkaddr);
block_t blkaddr, bool in_task);
bool f2fs_cluster_is_empty(struct compress_ctx *cc);
bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
bool f2fs_all_cluster_page_loaded(struct compress_ctx *cc, struct pagevec *pvec,
@@ -4202,8 +4213,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
unsigned nr_pages, sector_t *last_block_in_bio,
bool is_readahead, bool for_write);
struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed);
void f2fs_put_page_dic(struct page *page);
void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
bool in_task);
void f2fs_put_page_dic(struct page *page, bool in_task);
unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn);
int f2fs_init_compress_ctx(struct compress_ctx *cc);
void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse);
@@ -4249,13 +4261,14 @@ static inline struct page *f2fs_compress_control_page(struct page *page)
}
static inline int f2fs_init_compress_mempool(void) { return 0; }
static inline void f2fs_destroy_compress_mempool(void) { }
static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { }
static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic,
bool in_task) { }
static inline void f2fs_end_read_compressed_page(struct page *page,
bool failed, block_t blkaddr)
bool failed, block_t blkaddr, bool in_task)
{
WARN_ON_ONCE(1);
}
static inline void f2fs_put_page_dic(struct page *page)
static inline void f2fs_put_page_dic(struct page *page, bool in_task)
{
WARN_ON_ONCE(1);
}
@@ -4427,6 +4440,11 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
}
static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi)
{
return F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW;
}
static inline bool f2fs_may_compress(struct inode *inode)
{
if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||

View File

@@ -2294,7 +2294,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
if (ret) {
if (ret == -EROFS) {
ret = 0;
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false,
STOP_CP_REASON_SHUTDOWN);
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
trace_f2fs_shutdown(sbi, in, ret);
}
@@ -2307,7 +2308,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
ret = freeze_bdev(sb->s_bdev);
if (ret)
goto out;
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
thaw_bdev(sb->s_bdev);
break;
@@ -2316,16 +2317,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
ret = f2fs_sync_fs(sb, 1);
if (ret)
goto out;
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
break;
case F2FS_GOING_DOWN_NOSYNC:
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
break;
case F2FS_GOING_DOWN_METAFLUSH:
f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
break;
case F2FS_GOING_DOWN_NEED_FSCK:

View File

@@ -70,7 +70,8 @@ static int gc_thread_func(void *data)
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false,
STOP_CP_REASON_FAULT_INJECT);
}
if (!sb_start_write_trylock(sbi->sb)) {
@@ -93,14 +94,10 @@ static int gc_thread_func(void *data)
*/
if (sbi->gc_mode == GC_URGENT_HIGH) {
spin_lock(&sbi->gc_urgent_high_lock);
if (sbi->gc_urgent_high_limited) {
if (!sbi->gc_urgent_high_remaining) {
sbi->gc_urgent_high_limited = false;
spin_unlock(&sbi->gc_urgent_high_lock);
sbi->gc_mode = GC_NORMAL;
continue;
}
if (sbi->gc_urgent_high_remaining) {
sbi->gc_urgent_high_remaining--;
if (!sbi->gc_urgent_high_remaining)
sbi->gc_mode = GC_NORMAL;
}
spin_unlock(&sbi->gc_urgent_high_lock);
}
@@ -1655,7 +1652,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
segno, type, GET_SUM_TYPE((&sum->footer)));
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false,
STOP_CP_REASON_CORRUPTED_SUMMARY);
goto skip;
}

View File

@@ -700,7 +700,8 @@ retry:
cond_resched();
goto retry;
} else if (err != -ENOENT) {
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false,
STOP_CP_REASON_UPDATE_INODE);
}
return;
}

View File

@@ -498,7 +498,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
{
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_FAULT_INJECT);
}
/* balance_fs_bg is able to be pending */
@@ -809,7 +809,8 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi)
} while (ret && --count);
if (ret) {
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false,
STOP_CP_REASON_FLUSH_FAIL);
break;
}

View File

@@ -160,6 +160,7 @@ enum {
Opt_gc_merge,
Opt_nogc_merge,
Opt_discard_unit,
Opt_memory_mode,
Opt_err,
};
@@ -237,6 +238,7 @@ static match_table_t f2fs_tokens = {
{Opt_gc_merge, "gc_merge"},
{Opt_nogc_merge, "nogc_merge"},
{Opt_discard_unit, "discard_unit=%s"},
{Opt_memory_mode, "memory=%s"},
{Opt_err, NULL},
};
@@ -307,10 +309,10 @@ static void f2fs_destroy_casefold_cache(void) { }
static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
{
block_t limit = min((sbi->user_block_count << 1) / 1000,
block_t limit = min((sbi->user_block_count >> 3),
sbi->user_block_count - sbi->reserved_blocks);
/* limit is 0.2% */
/* limit is 12.5% */
if (test_opt(sbi, RESERVE_ROOT) &&
F2FS_OPTION(sbi).root_reserved_blocks > limit &&
F2FS_OPTION(sbi).root_reserved_blocks > MIN_ROOT_RESERVED_BLOCKS) {
@@ -1247,6 +1249,22 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
}
kfree(name);
break;
case Opt_memory_mode:
name = match_strdup(&args[0]);
if (!name)
return -ENOMEM;
if (!strcmp(name, "normal")) {
F2FS_OPTION(sbi).memory_mode =
MEMORY_MODE_NORMAL;
} else if (!strcmp(name, "low")) {
F2FS_OPTION(sbi).memory_mode =
MEMORY_MODE_LOW;
} else {
kfree(name);
return -EINVAL;
}
kfree(name);
break;
default:
f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value",
p);
@@ -1674,9 +1692,8 @@ static int f2fs_freeze(struct super_block *sb)
if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY))
return -EINVAL;
/* ensure no checkpoint required */
if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
return -EINVAL;
/* Let's flush checkpoints and stop the thread. */
f2fs_flush_ckpt_thread(F2FS_SB(sb));
/* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
@@ -2032,6 +2049,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION)
seq_printf(seq, ",discard_unit=%s", "section");
if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_NORMAL)
seq_printf(seq, ",memory=%s", "normal");
else if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW)
seq_printf(seq, ",memory=%s", "low");
return 0;
}
@@ -2054,6 +2076,7 @@ static void default_options(struct f2fs_sb_info *sbi)
F2FS_OPTION(sbi).compress_ext_cnt = 0;
F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS;
F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON;
F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL;
sbi->sb->s_flags &= ~SB_INLINECRYPT;
@@ -2174,6 +2197,9 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
f2fs_up_write(&sbi->gc_lock);
f2fs_sync_fs(sbi->sb, 1);
/* Let's ensure there's no pending checkpoint anymore */
f2fs_flush_ckpt_thread(sbi);
}
static int f2fs_remount(struct super_block *sb, int *flags, char *data)
@@ -2340,6 +2366,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
f2fs_stop_ckpt_thread(sbi);
need_restart_ckpt = true;
} else {
/* Flush if the prevous checkpoint, if exists. */
f2fs_flush_ckpt_thread(sbi);
err = f2fs_start_ckpt_thread(sbi);
if (err) {
f2fs_err(sbi,
@@ -3836,6 +3865,26 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
return err;
}
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason)
{
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
int err;
f2fs_bug_on(sbi, reason >= MAX_STOP_REASON);
f2fs_down_write(&sbi->sb_lock);
if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1))
raw_super->s_stop_reason[reason]++;
err = f2fs_commit_super(sbi, false);
if (err)
f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d",
reason, err);
f2fs_up_write(&sbi->sb_lock);
}
static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
{
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);

View File

@@ -513,7 +513,6 @@ out:
if (!strcmp(a->attr.name, "gc_urgent_high_remaining")) {
spin_lock(&sbi->gc_urgent_high_lock);
sbi->gc_urgent_high_limited = t != 0;
sbi->gc_urgent_high_remaining = t;
spin_unlock(&sbi->gc_urgent_high_lock);

View File

@@ -23,6 +23,9 @@ struct fuse_bpf_aio_req {
static struct kmem_cache *fuse_bpf_aio_request_cachep;
static void fuse_stat_to_attr(struct fuse_conn *fc, struct inode *inode,
struct kstat *stat, struct fuse_attr *attr);
static void fuse_file_accessed(struct file *dst_file, struct file *src_file)
{
struct inode *dst_inode;
@@ -181,8 +184,10 @@ void *fuse_open_finalize(struct fuse_bpf_args *fa,
struct fuse_file *ff = file->private_data;
struct fuse_open_out *foo = fa->out_args[0].value;
if (ff)
if (ff) {
ff->fh = foo->fh;
ff->nodeid = get_fuse_inode(inode)->nodeid;
}
return 0;
}
@@ -1153,6 +1158,9 @@ int fuse_lookup_backing(struct fuse_bpf_args *fa, struct inode *dir,
struct dentry *dir_backing_entry = dir_fuse_entry->backing_path.dentry;
struct inode *dir_backing_inode = dir_backing_entry->d_inode;
struct dentry *backing_entry;
struct fuse_entry_out *feo = (void *)fa->out_args[0].value;
struct kstat stat;
int err;
/* TODO this will not handle lookups over mount points */
inode_lock_nested(dir_backing_inode, I_MUTEX_PARENT);
@@ -1165,10 +1173,23 @@ int fuse_lookup_backing(struct fuse_bpf_args *fa, struct inode *dir,
fuse_entry->backing_path = (struct path) {
.dentry = backing_entry,
.mnt = dir_fuse_entry->backing_path.mnt,
.mnt = mntget(dir_fuse_entry->backing_path.mnt),
};
mntget(fuse_entry->backing_path.mnt);
if (d_is_negative(backing_entry)) {
fa->error_in = -ENOENT;
return 0;
}
err = vfs_getattr(&fuse_entry->backing_path, &stat,
STATX_BASIC_STATS, 0);
if (err) {
path_put_init(&fuse_entry->backing_path);
return err;
}
fuse_stat_to_attr(get_fuse_conn(dir),
backing_entry->d_inode, &stat, &feo->attr);
return 0;
}

View File

@@ -1592,6 +1592,10 @@ static int incfs_setattr(struct dentry *dentry, struct iattr *ia)
if (ia->ia_valid & ATTR_SIZE)
return -EINVAL;
if ((ia->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
(ia->ia_valid & ATTR_MODE))
return -EINVAL;
if (!di)
return -EINVAL;
backing_dentry = di->backing_path.dentry;

View File

@@ -1244,30 +1244,33 @@ unsigned int round_pipe_size(unsigned long size)
/*
* Resize the pipe ring to a number of slots.
*
* Note the pipe can be reduced in capacity, but only if the current
* occupancy doesn't exceed nr_slots; if it does, EBUSY will be
* returned instead.
*/
int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
{
struct pipe_buffer *bufs;
unsigned int head, tail, mask, n;
/*
* We can shrink the pipe, if arg is greater than the ring occupancy.
* Since we don't expect a lot of shrink+grow operations, just free and
* allocate again like we would do for growing. If the pipe currently
* contains more buffers than arg, then return busy.
*/
mask = pipe->ring_size - 1;
head = pipe->head;
tail = pipe->tail;
n = pipe_occupancy(pipe->head, pipe->tail);
if (nr_slots < n)
return -EBUSY;
bufs = kcalloc(nr_slots, sizeof(*bufs),
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
if (unlikely(!bufs))
return -ENOMEM;
spin_lock_irq(&pipe->rd_wait.lock);
mask = pipe->ring_size - 1;
head = pipe->head;
tail = pipe->tail;
n = pipe_occupancy(head, tail);
if (nr_slots < n) {
spin_unlock_irq(&pipe->rd_wait.lock);
kfree(bufs);
return -EBUSY;
}
/*
* The pipe array wraps around, so just start the new one at zero
* and adjust the indices.
@@ -1299,6 +1302,8 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
pipe->tail = tail;
pipe->head = head;
spin_unlock_irq(&pipe->rd_wait.lock);
/* This might have made more room for writers */
wake_up_interruptible(&pipe->wr_wait);
return 0;

View File

@@ -73,6 +73,20 @@ struct f2fs_device {
__le32 total_segments;
} __packed;
/* reason of stop_checkpoint */
enum stop_cp_reason {
STOP_CP_REASON_SHUTDOWN,
STOP_CP_REASON_FAULT_INJECT,
STOP_CP_REASON_META_PAGE,
STOP_CP_REASON_WRITE_FAIL,
STOP_CP_REASON_CORRUPTED_SUMMARY,
STOP_CP_REASON_UPDATE_INODE,
STOP_CP_REASON_FLUSH_FAIL,
STOP_CP_REASON_MAX,
};
#define MAX_STOP_REASON 32
struct f2fs_super_block {
__le32 magic; /* Magic Number */
__le16 major_ver; /* Major Version */
@@ -116,7 +130,8 @@ struct f2fs_super_block {
__u8 hot_ext_count; /* # of hot file extension */
__le16 s_encoding; /* Filename charset encoding */
__le16 s_encoding_flags; /* Filename charset encoding flags */
__u8 reserved[306]; /* valid reserved region */
__u8 s_stop_reason[MAX_STOP_REASON]; /* stop checkpoint reason */
__u8 reserved[274]; /* valid reserved region */
__le32 crc; /* checksum of superblock */
} __packed;

View File

@@ -10,7 +10,6 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct binder_alloc;
struct binder_proc;
struct binder_thread;
@@ -18,18 +17,7 @@ struct binder_transaction;
struct task_struct;
struct seq_file;
struct binder_transaction_data;
#else
/* struct binder_alloc */
#include <../drivers/android/binder_alloc.h>
/* struct binder_proc, struct binder_thread, struct binder_transaction */
#include <../drivers/android/binder_internal.h>
/* struct task_struct */
#include <linux/sched.h>
/* struct seq_file */
#include <linux/seq_file.h>
/* struct binder_transaction_data */
#include <uapi/linux/android/binder.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_binder_transaction_init,
TP_PROTO(struct binder_transaction *t),
TP_ARGS(t));

View File

@@ -9,18 +9,9 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct blk_mq_tags;
struct blk_mq_alloc_data;
struct blk_mq_tag_set;
#else
/* struct blk_mq_tags */
#include <../block/blk-mq-tag.h>
/* struct blk_mq_alloc_data */
#include <../block/blk-mq.h>
/* struct blk_mq_tag_set */
#include <linux/blk-mq.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_blk_alloc_rqs,
TP_PROTO(size_t *rq_size, struct blk_mq_tag_set *set,

View File

@@ -7,18 +7,10 @@
#define _TRACE_HOOK_CGROUP_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct cgroup_taskset;
struct cgroup_subsys;
struct task_struct;
#else
/* Including ../kernel/cgroup/cgroup-internal.h breaks builds. */
struct cgroup_taskset;
/* struct cgroup_subsys */
#include <linux/cgroup-defs.h>
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_cgroup_set_task,
TP_PROTO(int ret, struct task_struct *task),
TP_ARGS(ret, task));

View File

@@ -6,10 +6,15 @@
#if !defined(_TRACE_HOOK_CPUFREQ_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_CPUFREQ_H
#include <linux/cpufreq.h>
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
#include <linux/cpufreq.h>
#endif
struct cpufreq_policy;
struct task_struct;
DECLARE_HOOK(android_vh_show_max_freq,
TP_PROTO(struct cpufreq_policy *policy, unsigned int *max_freq),
TP_ARGS(policy, max_freq));

View File

@@ -9,12 +9,7 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct cpuidle_device;
#else
/* struct cpuidle_device */
#include <linux/cpuidle.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_cpu_idle_enter,
TP_PROTO(int *state, struct cpuidle_device *dev),

View File

@@ -10,12 +10,8 @@
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct cpuidle_device;
#else
/* struct cpuidle_device */
#include <linux/cpuidle.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_cpuidle_psci_enter,
TP_PROTO(struct cpuidle_device *dev, bool s2idle),
TP_ARGS(dev, s2idle));

View File

@@ -10,15 +10,9 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct cred;
struct task_struct;
#else
/* struct cred */
#include <linux/cred.h>
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_commit_creds,
TP_PROTO(const struct task_struct *task, const struct cred *new),
TP_ARGS(task, new));

View File

@@ -9,21 +9,11 @@
#include <trace/hooks/vendor_hooks.h>
#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
#ifdef __GENKSYMS__
struct pt_regs;
#else
/* struct pt_regs */
#include <asm/ptrace.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_ipi_stop,
TP_PROTO(struct pt_regs *regs),
TP_ARGS(regs))
#else
#define trace_android_vh_ipi_stop(regs)
#define trace_android_vh_ipi_stop_rcuidle(regs)
#endif
#endif /* _TRACE_HOOK_DEBUG_H */
/* This part must be outside protection */

View File

@@ -10,21 +10,11 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct mutex;
struct rt_mutex;
struct rw_semaphore;
struct task_struct;
#else
/* struct mutex */
#include <linux/mutex.h>
/* struct rt_mutex */
#include <linux/rtmutex.h>
/* struct rw_semaphore */
#include <linux/rwsem.h>
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_mutex_wait_start,
TP_PROTO(struct mutex *lock),
TP_ARGS(lock));

View File

@@ -10,12 +10,8 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct pt_regs;
#else
/* struct pt_regs */
#include <asm/ptrace.h>
#endif /* __GENKSYMS__ */
DECLARE_RESTRICTED_HOOK(android_rvh_die_kernel_fault,
TP_PROTO(struct pt_regs *regs, unsigned int esr, unsigned long addr, const char *msg),
TP_ARGS(regs, esr, addr, msg), 1);

View File

@@ -7,12 +7,7 @@
#define _TRACE_HOOK_FIPS140_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct crypto_aes_ctx;
#else
/* struct crypto_aes_ctx */
#include <crypto/aes.h>
#endif /* __GENKSYMS__ */
/*
* These hooks exist only for the benefit of the FIPS140 crypto module, which

View File

@@ -6,11 +6,14 @@
#if !defined(_TRACE_HOOK_FTRACE_DUMP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_FTRACE_DUMP_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
#include <linux/trace_seq.h>
#include <linux/trace_events.h>
#endif
#include <trace/hooks/vendor_hooks.h>
struct trace_seq;
DECLARE_HOOK(android_vh_ftrace_oops_enter,
TP_PROTO(bool *ftrace_check),

View File

@@ -9,15 +9,9 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct cpumask;
struct irq_data;
#else
/* struct cpumask */
#include <linux/cpumask.h>
/* struct irq_data */
#include <linux/irq.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_gic_v3_affinity_init,
TP_PROTO(int irq, u32 offset, u64 *affinity),
TP_ARGS(irq, offset, affinity));

View File

@@ -8,15 +8,16 @@
#define _TRACE_HOOK_GPIOLIB_H
#include <trace/hooks/vendor_hooks.h>
#include "../drivers/gpio/gpiolib.h"
#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
#ifdef __GENKSYMS__
#include "../drivers/gpio/gpiolib.h"
#endif
struct gpio_device;
DECLARE_HOOK(android_vh_gpio_block_read,
TP_PROTO(struct gpio_device *gdev, bool *block_gpio_read),
TP_ARGS(gdev, block_gpio_read));
#else
#define trace_android_vh_gpio_block_read(gdev, block_gpio_read)
#endif
#endif /* _TRACE_HOOK_GPIOLIB_H */
/* This part must be outside protection */

View File

@@ -7,12 +7,7 @@
#define _TRACE_HOOK_GUP_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct page;
#else
/* struct page */
#include <linux/mm_types.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_try_grab_compound_head,
TP_PROTO(struct page *page, int refs, unsigned int flags, bool *ret),

View File

@@ -11,7 +11,6 @@
#include <trace/hooks/vendor_hooks.h>
#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
DECLARE_RESTRICTED_HOOK(android_rvh_iommu_setup_dma_ops,
TP_PROTO(struct device *dev, u64 dma_base, u64 size),
TP_ARGS(dev, dma_base, size), 1);
@@ -23,13 +22,6 @@ DECLARE_HOOK(android_vh_iommu_alloc_iova,
DECLARE_HOOK(android_vh_iommu_free_iova,
TP_PROTO(dma_addr_t iova, size_t size),
TP_ARGS(iova, size));
#else
#define trace_android_rvh_iommu_setup_dma_ops(dev, dma_base, size)
#define trace_android_vh_iommu_alloc_iova(dev, iova, size)
#define trace_android_vh_iommu_free_iova(iova, size)
#endif
#endif /* _TRACE_HOOK_IOMMU_H */

View File

@@ -9,13 +9,8 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct printk_record;
struct printk_ringbuffer;
#else
/* struct printk_record, struct printk_ringbuffer */
#include <../kernel/printk/printk_ringbuffer.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_logbuf,
TP_PROTO(struct printk_ringbuffer *rb, struct printk_record *r),

View File

@@ -8,32 +8,23 @@
#define _TRACE_HOOK_MM_H
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/oom.h>
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
#include <linux/mm.h>
#include <linux/oom.h>
#endif
struct oom_control;
struct cma;
struct acr_info;
struct compact_control;
struct slabinfo;
struct cgroup_subsys_state;
struct mem_cgroup;
#else
/* struct compact_control */
#include <../mm/internal.h>
/* struct slabinfo */
#include <../mm/slab.h>
/* struct cgroup_subsys_state */
#include <linux/cgroup-defs.h>
/* struct acr_info */
#include <linux/gfp.h>
/* struct mem_cgroup */
#include <linux/memcontrol.h>
#endif /* __GENKSYMS__ */
struct cma;
struct acr_info;
struct vm_unmapped_area_info;
DECLARE_RESTRICTED_HOOK(android_rvh_set_skip_swapcache_flags,
TP_PROTO(gfp_t *flags),

View File

@@ -9,18 +9,9 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct sdhci_host;
struct mmc_card;
struct mmc_host;
#else
/* struct sdhci_host */
#include <../drivers/mmc/host/sdhci.h>
/* struct mmc_card */
#include <linux/mmc/card.h>
/* struct mmc_host */
#include <linux/mmc/host.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_mmc_blk_reset,
TP_PROTO(struct mmc_host *host, int err, bool *allow),

View File

@@ -10,12 +10,8 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct task_struct;
#else
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_mpam_set,
TP_PROTO(struct task_struct *prev, struct task_struct *next),
TP_ARGS(prev, next));

View File

@@ -8,24 +8,12 @@
#define _TRACE_HOOK_NET_VH_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct packet_type;
struct sk_buff;
struct list_head;
struct nf_conn;
struct sock;
#else
/* struct packet_type */
#include <linux/netdevice.h>
/* struct sk_buff */
#include <linux/skbuff.h>
/* struct list_head */
#include <linux/types.h>
/* struct nf_conn */
#include <net/netfilter/nf_conntrack.h>
/* struct sock */
#include <net/sock.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_ptype_head,
TP_PROTO(const struct packet_type *pt, struct list_head *vendor_pt),
TP_ARGS(pt, vendor_pt));

View File

@@ -6,6 +6,9 @@
#if !defined(_TRACE_HOOK_PCI_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_PCI_H
#include <trace/hooks/vendor_hooks.h>
struct pci_dev;
/*
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality

View File

@@ -10,12 +10,8 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct generic_pm_domain;
#else
/* struct generic_pm_domain */
#include <linux/pm_domain.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_allow_domain_state,
TP_PROTO(struct generic_pm_domain *genpd, uint32_t idx, bool *allow),
TP_ARGS(genpd, idx, allow))

View File

@@ -10,17 +10,14 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
enum freq_qos_req_type;
/* needed for enum freq_qos_req_types */
#include <linux/pm_qos.h>
struct freq_constraints;
struct freq_qos_request;
struct task_struct;
#else
/* enum freq_qos_req_type, struct freq_constraints, struct freq_qos_request */
#include <linux/pm_qos.h>
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_try_to_freeze_todo,
TP_PROTO(unsigned int todo, unsigned int elapsed_msecs, bool wq_busy),
TP_ARGS(todo, elapsed_msecs, wq_busy));

View File

@@ -9,15 +9,9 @@
#include <trace/hooks/vendor_hooks.h>
#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS)
#ifdef __GENKSYMS__
struct psi_group;
struct psi_trigger;
#else
/* struct psi_group, struct psi_trigger */
#include <linux/psi_types.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_psi_event,
TP_PROTO(struct psi_trigger *t),
TP_ARGS(t));
@@ -26,11 +20,6 @@ DECLARE_HOOK(android_vh_psi_group,
TP_PROTO(struct psi_group *group),
TP_ARGS(group));
#else
#define trace_android_vh_psi_event(t)
#define trace_android_vh_psi_group(group)
#endif
#endif /* _TRACE_HOOK_PSI_H */
/* This part must be outside protection */

View File

@@ -9,12 +9,7 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct rproc;
#else
/* struct rproc */
#include <linux/remoteproc.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_rproc_recovery,
TP_PROTO(struct rproc *rproc),

View File

@@ -9,13 +9,9 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct rw_semaphore;
struct rwsem_waiter;
#else
/* struct rw_semaphore, struct rwsem_waiter */
#include <linux/rwsem.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_rwsem_init,
TP_PROTO(struct rw_semaphore *sem),
TP_ARGS(sem));

View File

@@ -9,7 +9,6 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct cgroup_taskset;
struct cgroup_subsys_state;
struct cpufreq_policy;
@@ -18,20 +17,7 @@ enum uclamp_id;
struct sched_entity;
struct task_struct;
struct uclamp_se;
#else
/* Including ../kernel/cgroup/cgroup-internal.h breaks builds. */
struct cgroup_taskset;
/* struct cgroup_subsys_state */
#include <linux/cgroup-defs.h>
/* struct cpufreq_policy */
#include <linux/cpufreq.h>
/* struct em_perf_domain */
#include <linux/energy_model.h>
/* enum uclamp_id, struct sched_entity, struct task_struct, struct uclamp_se */
#include <linux/sched.h>
/* Only defined with CONFIG_UCLAMP_TASK, so declare unconditionally. */
struct uclamp_se;
#endif /* __GENKSYMS__ */
DECLARE_RESTRICTED_HOOK(android_rvh_select_task_rq_fair,
TP_PROTO(struct task_struct *p, int prev_cpu, int sd_flag, int wake_flags, int *new_cpu),
TP_ARGS(p, prev_cpu, sd_flag, wake_flags, new_cpu), 1);
@@ -406,6 +392,10 @@ DECLARE_HOOK(android_vh_pidfd_open,
DECLARE_HOOK(android_vh_mmput,
TP_PROTO(void *unused),
TP_ARGS(unused));
DECLARE_HOOK(android_vh_rebuild_root_domains_bypass,
TP_PROTO(bool tasks_frozen, bool *bypass),
TP_ARGS(tasks_frozen, bypass));
/* macro versions of hooks are no longer required */
#endif /* _TRACE_HOOK_SCHED_H */

View File

@@ -7,12 +7,8 @@
#define _TRACE_HOOK_SHMEM_FS_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct page;
#else
/* struct page */
#include <linux/mm_types.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_shmem_alloc_page,
TP_PROTO(struct page **page),
TP_ARGS(page));

View File

@@ -7,12 +7,8 @@
#define _TRACE_HOOK_SIGNAL_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct task_struct;
#else
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_do_send_sig_info,
TP_PROTO(int sig, struct task_struct *killer, struct task_struct *dst),
TP_ARGS(sig, killer, dst));

View File

@@ -10,12 +10,8 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct pt_regs;
#else
/* struct pt_regs */
#include <asm/ptrace.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_watchdog_timer_softlockup,
TP_PROTO(int duration, struct pt_regs *regs, bool is_panic),
TP_ARGS(duration, regs, is_panic));

View File

@@ -7,12 +7,8 @@
#define _TRACE_HOOK_SYS_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct task_struct;
#else
/* struct task_struct */
#include <linux/sched.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_syscall_prctl_finished,
TP_PROTO(int option, struct task_struct *task),
TP_ARGS(option, task));

View File

@@ -10,15 +10,9 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct file;
union bpf_attr;
#else
/* struct file */
#include <linux/fs.h>
/* union bpf_attr */
#include <uapi/linux/bpf.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_check_mmap_file,
TP_PROTO(const struct file *file, unsigned long prot,
unsigned long flag, unsigned long ret),

View File

@@ -10,12 +10,8 @@
#include <trace/hooks/vendor_hooks.h>
#include <linux/cpufreq.h>
#ifdef __GENKSYMS__
struct thermal_zone_device;
#else
/* struct thermal_zone_device */
#include <linux/thermal.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_enable_thermal_genl_check,
TP_PROTO(int event, int tz_id, int *enable_thermal_genl),
TP_ARGS(event, tz_id, enable_thermal_genl));

View File

@@ -8,7 +8,12 @@
#define _TRACE_HOOK_TOPOLOGY_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
#include <linux/cpumask.h>
#endif
struct cpumask;
DECLARE_HOOK(android_vh_arch_set_freq_scale,
TP_PROTO(const struct cpumask *cpus, unsigned long freq,

View File

@@ -10,12 +10,8 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct pt_regs;
#else
/* struct pt_regs */
#include <asm/ptrace.h>
#endif /* __GENKSYMS__ */
DECLARE_RESTRICTED_HOOK(android_rvh_do_undefinstr,
TP_PROTO(struct pt_regs *regs, bool user),
TP_ARGS(regs, user),

View File

@@ -9,20 +9,11 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct ufs_hba;
struct ufshcd_lrb;
struct uic_command;
struct request;
struct scsi_device;
#else
/* struct ufs_hba, struct ufshcd_lrb, struct uic_command */
#include <../drivers/scsi/ufs/ufshcd.h>
/* struct request */
#include <linux/blkdev.h>
/* struct scsi_device */
#include <scsi/scsi_device.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_ufs_fill_prdt,
TP_PROTO(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,

View File

@@ -5,8 +5,14 @@
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_USB_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_USB_H
#include <linux/usb.h>
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
#include <linux/usb.h>
#endif
struct usb_device;
/*
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality

View File

@@ -7,12 +7,8 @@
#define _TRACE_HOOK_USER_H
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct user_struct;
#else
/* struct user_struct */
#include <linux/sched/user.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_alloc_uid,
TP_PROTO(struct user_struct *user),
TP_ARGS(user));

View File

@@ -9,7 +9,6 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct v4l2_subdev;
struct v4l2_subdev_pad_config;
struct v4l2_subdev_format;
@@ -17,14 +16,7 @@ struct v4l2_subdev_frame_interval;
struct v4l2_subdev_selection;
struct v4l2_fmtdesc;
struct v4l2_format;
#else
/* struct v4l2_subdev, struct v4l2_subdev_pad_config */
#include <media/v4l2-subdev.h>
/* struct v4l2_subdev_format, struct v4l2_subdev_frame_interval, struct v4l2_subdev_selection */
#include <uapi/linux/v4l2-subdev.h>
/* struct v4l2_fmtdesc, struct v4l2_format */
#include <uapi/linux/videodev2.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_clear_reserved_fmt_fields,
TP_PROTO(struct v4l2_format *fmt, int *ret),
TP_ARGS(fmt, ret));

View File

@@ -9,15 +9,9 @@
#include <trace/hooks/vendor_hooks.h>
#ifdef __GENKSYMS__
struct media_link;
struct media_link_desc;
#else
/* struct media_link */
#include <media/media-entity.h>
/* struct media_link_desc */
#include <uapi/linux/media.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_media_device_setup_link,
TP_PROTO(struct media_link *link, struct media_link_desc *linkd, int *ret),
TP_ARGS(link, linkd, ret));

View File

@@ -10,12 +10,8 @@
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
#ifdef __GENKSYMS__
struct worker;
#else
/* struct worker */
#include <../kernel/workqueue_internal.h>
#endif /* __GENKSYMS__ */
DECLARE_HOOK(android_vh_create_worker,
TP_PROTO(struct worker *worker, struct workqueue_attrs *attrs),
TP_ARGS(worker, attrs));

View File

@@ -1,21 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM wqlockup
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_WQLOCKUP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_WQLOCKUP_H
#include <trace/hooks/vendor_hooks.h>
/*
* Following tracepoints are not exported in tracefs and provide a
* mechanism for vendor modules to hook and extend functionality
*/
DECLARE_HOOK(android_vh_wq_lockup_pool,
TP_PROTO(int cpu, unsigned long pool_ts),
TP_ARGS(cpu, pool_ts));
/* macro versions of hooks are no longer required */
#endif /* _TRACE_HOOK_WQLOCKUP_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@@ -6,3 +6,4 @@ obj-$(CONFIG_CGROUP_PIDS) += pids.o
obj-$(CONFIG_CGROUP_RDMA) += rdma.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_CGROUP_DEBUG) += debug.o
obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o

View File

@@ -941,6 +941,12 @@ static void rebuild_root_domains(void)
{
struct cpuset *cs = NULL;
struct cgroup_subsys_state *pos_css;
bool bypass = false;
trace_android_vh_rebuild_root_domains_bypass(cpuhp_tasks_frozen, &bypass);
if (bypass)
return;
lockdep_assert_held(&cpuset_mutex);
lockdep_assert_cpus_held();

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0-only
/* vendor_hook.c
*
* Android Vendor Hook Support
*
* Copyright 2022 Google LLC
*/
#ifndef __GENKSYMS__
#include "cgroup-internal.h"
#else
/*
* Needed to preserve CRC for cgroup-related hooks
*/
#include <linux/cpufreq.h>
#include <../drivers/gpio/gpiolib.h>
#endif
#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <linux/tracepoint.h>
#include <trace/hooks/cgroup.h>
/*
* Export tracepoints that act as a bare tracehook (ie: have no trace event
* associated with them) to allow external modules to probe them.
*/
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_set_task);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpuset_fork);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_refrigerator);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_attach);
/*
* For type visibility
*/
const struct cgroup_taskset *GKI_struct_cgroup_taskset;
EXPORT_SYMBOL_GPL(GKI_struct_cgroup_taskset);

View File

@@ -440,7 +440,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
BUG_ON(!irqs_disabled());
system_state = SYSTEM_SUSPEND;
trace_android_vh_early_resume_begin(NULL);
error = syscore_suspend();
if (!error) {
*wakeup = pm_wakeup_pending();
@@ -450,6 +449,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
error = suspend_ops->enter(state);
trace_suspend_resume(TPS("machine_suspend"),
state, false);
trace_android_vh_early_resume_begin(NULL);
} else if (*wakeup) {
error = -EBUSY;
}

View File

@@ -150,7 +150,7 @@ int cpupri_find_fitness(struct cpupri *cp, struct task_struct *p,
{
int task_pri = convert_prio(p->prio);
int idx, cpu;
bool drop_nopreempts = task_pri <= MAX_RT_PRIO;
bool drop_nopreempts = task_pri <= MAX_RT_PRIO + 1;
BUG_ON(task_pri >= CPUPRI_NR_PRIORITIES);

View File

@@ -34,6 +34,27 @@ MODULE_LICENSE("GPL");
#define WATCH_QUEUE_NOTE_SIZE 128
#define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
/*
* This must be called under the RCU read-lock, which makes
* sure that the wqueue still exists. It can then take the lock,
* and check that the wqueue hasn't been destroyed, which in
* turn makes sure that the notification pipe still exists.
*/
static inline bool lock_wqueue(struct watch_queue *wqueue)
{
spin_lock_bh(&wqueue->lock);
if (unlikely(wqueue->defunct)) {
spin_unlock_bh(&wqueue->lock);
return false;
}
return true;
}
static inline void unlock_wqueue(struct watch_queue *wqueue)
{
spin_unlock_bh(&wqueue->lock);
}
static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
@@ -69,6 +90,10 @@ static const struct pipe_buf_operations watch_queue_pipe_buf_ops = {
/*
* Post a notification to a watch queue.
*
* Must be called with the RCU lock for reading, and the
* watch_queue lock held, which guarantees that the pipe
* hasn't been released.
*/
static bool post_one_notification(struct watch_queue *wqueue,
struct watch_notification *n)
@@ -85,9 +110,6 @@ static bool post_one_notification(struct watch_queue *wqueue,
spin_lock_irq(&pipe->rd_wait.lock);
if (wqueue->defunct)
goto out;
mask = pipe->ring_size - 1;
head = pipe->head;
tail = pipe->tail;
@@ -203,7 +225,10 @@ void __post_watch_notification(struct watch_list *wlist,
if (security_post_notification(watch->cred, cred, n) < 0)
continue;
post_one_notification(wqueue, n);
if (lock_wqueue(wqueue)) {
post_one_notification(wqueue, n);
unlock_wqueue(wqueue);;
}
}
rcu_read_unlock();
@@ -463,11 +488,12 @@ int add_watch_to_object(struct watch *watch, struct watch_list *wlist)
return -EAGAIN;
}
spin_lock_bh(&wqueue->lock);
kref_get(&wqueue->usage);
kref_get(&watch->usage);
hlist_add_head(&watch->queue_node, &wqueue->watches);
spin_unlock_bh(&wqueue->lock);
if (lock_wqueue(wqueue)) {
kref_get(&wqueue->usage);
kref_get(&watch->usage);
hlist_add_head(&watch->queue_node, &wqueue->watches);
unlock_wqueue(wqueue);
}
hlist_add_head(&watch->list_node, &wlist->watchers);
return 0;
@@ -521,20 +547,15 @@ found:
wqueue = rcu_dereference(watch->queue);
/* We don't need the watch list lock for the next bit as RCU is
* protecting *wqueue from deallocation.
*/
if (wqueue) {
if (lock_wqueue(wqueue)) {
post_one_notification(wqueue, &n.watch);
spin_lock_bh(&wqueue->lock);
if (!hlist_unhashed(&watch->queue_node)) {
hlist_del_init_rcu(&watch->queue_node);
put_watch(watch);
}
spin_unlock_bh(&wqueue->lock);
unlock_wqueue(wqueue);
}
if (wlist->release_watch) {

View File

@@ -55,7 +55,6 @@
#include "workqueue_internal.h"
#include <trace/hooks/wqlockup.h>
#include <trace/hooks/workqueue.h>
/* events/workqueue.h uses default TRACE_INCLUDE_PATH */
#undef TRACE_INCLUDE_PATH
@@ -5855,7 +5854,6 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
pr_cont_pool_info(pool);
pr_cont(" stuck for %us!\n",
jiffies_to_msecs(now - pool_ts) / 1000);
trace_android_vh_wq_lockup_pool(pool->cpu, pool_ts);
}
}

View File

@@ -54,6 +54,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(neigh_event_send_dead);
EXPORT_TRACEPOINT_SYMBOL_GPL(neigh_cleanup_and_release);
EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
EXPORT_TRACEPOINT_SYMBOL_GPL(consume_skb);
EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll);

View File

@@ -1244,7 +1244,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
struct sk_buff *msg;
void *hdr;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (!msg)
return -ENOMEM;
@@ -1260,7 +1260,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
genlmsg_end(msg, hdr);
genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
return 0;

View File

@@ -414,20 +414,31 @@ printf "%08x\n" $$dec_size | \
)
quiet_cmd_bzip2 = BZIP2 $@
cmd_bzip2 = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
cmd_bzip2 = cat $(real-prereqs) | $(KBZIP2) -9 > $@
quiet_cmd_bzip2_with_size = BZIP2 $@
cmd_bzip2_with_size = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
# Lzma
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@
quiet_cmd_lzma_with_size = LZMA $@
cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
quiet_cmd_lzo = LZO $@
cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@
quiet_cmd_lzo_with_size = LZO $@
cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
quiet_cmd_lz4 = LZ4 $@
cmd_lz4 = { cat $(real-prereqs) | \
$(LZ4) -l -12 --favor-decSpeed stdin stdout; \
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -12 --favor-decSpeed stdin stdout > $@
quiet_cmd_lz4_with_size = LZ4 $@
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -12 --favor-decSpeed stdin stdout; \
$(size_append); } > $@
quiet_cmd_lz4c = LZ4C $@
@@ -475,7 +486,10 @@ quiet_cmd_uimage = UIMAGE $@
# big dictionary would increase the memory usage too much in the multi-call
# decompression mode. A BCJ filter isn't used either.
quiet_cmd_xzkern = XZKERN $@
cmd_xzkern = { cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh; \
cmd_xzkern = cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh > $@
quiet_cmd_xzkern_with_size = XZKERN $@
cmd_xzkern_with_size = { cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh; \
$(size_append); } > $@
quiet_cmd_xzmisc = XZMISC $@
@@ -501,7 +515,10 @@ quiet_cmd_zstd = ZSTD $@
cmd_zstd = { cat $(real-prereqs) | $(ZSTD) -19; $(size_append); } > $@
quiet_cmd_zstd22 = ZSTD22 $@
cmd_zstd22 = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@
cmd_zstd22 = cat $(real-prereqs) | $(ZSTD) -22 --ultra > $@
quiet_cmd_zstd22_with_size = ZSTD22 $@
cmd_zstd22_with_size = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@
# ASM offsets
# ---------------------------------------------------------------------------

View File

@@ -1911,7 +1911,117 @@ out:
return result;
}
static int parse_options(int argc, char *const *argv)
static int bpf_test_lookup_postfilter(const char *mount_dir)
{
const char *file1_name = "file1";
const char *file2_name = "file2";
const char *file3_name = "file3";
int result = TEST_FAILURE;
int bpf_fd = -1;
int src_fd = -1;
int fuse_dev = -1;
int file_fd = -1;
int pid = -1;
int status;
TEST(file_fd = s_creat(s_path(s(ft_src), s(file1_name)), 0777),
file_fd != -1);
TESTSYSCALL(close(file_fd));
TEST(file_fd = s_creat(s_path(s(ft_src), s(file2_name)), 0777),
file_fd != -1);
TESTSYSCALL(close(file_fd));
file_fd = -1;
TESTEQUAL(install_elf_bpf("test_bpf.bpf", "test_lookup_postfilter",
&bpf_fd, NULL, NULL), 0);
TEST(src_fd = open(ft_src, O_DIRECTORY | O_RDONLY | O_CLOEXEC),
src_fd != -1);
TESTEQUAL(mount_fuse(mount_dir, bpf_fd, src_fd, &fuse_dev), 0);
FUSE_ACTION
int fd = -1;
TESTEQUAL(s_open(s_path(s(mount_dir), s(file1_name)), O_RDONLY),
-1);
TESTEQUAL(errno, ENOENT);
TEST(fd = s_open(s_path(s(mount_dir), s(file2_name)), O_RDONLY),
fd != -1);
TESTSYSCALL(close(fd));
TESTEQUAL(s_open(s_path(s(mount_dir), s(file3_name)), O_RDONLY),
-1);
FUSE_DAEMON
struct fuse_in_header *in_header =
(struct fuse_in_header *)bytes_in;
struct fuse_entry_out *feo;
struct fuse_entry_bpf_out *febo;
TESTFUSELOOKUP(file1_name, FUSE_POSTFILTER);
TESTFUSEOUTERROR(-ENOENT);
TESTFUSELOOKUP(file2_name, FUSE_POSTFILTER);
feo = (struct fuse_entry_out *) (bytes_in +
sizeof(struct fuse_in_header) + strlen(file2_name) + 1);
febo = (struct fuse_entry_bpf_out *) ((char *)feo +
sizeof(*feo));
TESTFUSEOUT2(fuse_entry_out, *feo, fuse_entry_bpf_out, *febo);
TESTFUSELOOKUP(file3_name, FUSE_POSTFILTER);
TESTEQUAL(in_header->error_in, -ENOENT);
TESTFUSEOUTERROR(-ENOENT);
FUSE_DONE
result = TEST_SUCCESS;
out:
close(file_fd);
close(fuse_dev);
umount(mount_dir);
close(src_fd);
close(bpf_fd);
return result;
}
static void parse_range(const char *ranges, bool *run_test, size_t tests)
{
size_t i;
char *range;
for (i = 0; i < tests; ++i)
run_test[i] = false;
range = strtok(optarg, ",");
while (range) {
char *dash = strchr(range, '-');
if (dash) {
size_t start = 1, end = tests;
char *end_ptr;
if (dash > range) {
start = strtol(range, &end_ptr, 10);
if (*end_ptr != '-' || start <= 0 || start > tests)
ksft_exit_fail_msg("Bad range\n");
}
if (dash[1]) {
end = strtol(dash + 1, &end_ptr, 10);
if (*end_ptr || end <= start || end > tests)
ksft_exit_fail_msg("Bad range\n");
}
for (i = start; i <= end; ++i)
run_test[i - 1] = true;
} else {
char *end;
long value = strtol(range, &end, 10);
if (*end || value <= 0 || value > tests)
ksft_exit_fail_msg("Bad range\n");
run_test[value - 1] = true;
}
range = strtok(NULL, ",");
}
}
static int parse_options(int argc, char *const *argv, bool *run_test,
size_t tests)
{
signed char c;
@@ -1922,7 +2032,7 @@ static int parse_options(int argc, char *const *argv)
break;
case 't':
test_options.test = strtol(optarg, NULL, 10);
parse_range(optarg, run_test, tests);
break;
case 'v':
@@ -1941,7 +2051,8 @@ struct test_case {
const char *name;
};
static void run_one_test(const char *mount_dir, struct test_case *test_case)
static void run_one_test(const char *mount_dir,
const struct test_case *test_case)
{
ksft_print_msg("Running %s\n", test_case->name);
if (test_case->pfunc(mount_dir) == TEST_SUCCESS)
@@ -1957,37 +2068,11 @@ int main(int argc, char *argv[])
int i;
int fd, count;
if (parse_options(argc, argv))
ksft_exit_fail_msg("Bad options\n");
// Seed randomness pool for testing on QEMU
// NOTE - this abuses the concept of randomness - do *not* ever do this
// on a machine for production use - the device will think it has good
// randomness when it does not.
fd = open("/dev/urandom", O_WRONLY | O_CLOEXEC);
count = 4096;
for (int i = 0; i < 128; ++i)
ioctl(fd, RNDADDTOENTCNT, &count);
close(fd);
ksft_print_header();
if (geteuid() != 0)
ksft_print_msg("Not a root, might fail to mount.\n");
if (tracing_on() != TEST_SUCCESS)
ksft_exit_fail_msg("Can't turn on tracing\n");
src_dir = setup_mount_dir(ft_src);
mount_dir = setup_mount_dir(ft_dst);
if (src_dir == NULL || mount_dir == NULL)
ksft_exit_fail_msg("Can't create a mount dir\n");
#define MAKE_TEST(test) \
{ \
test, #test \
}
struct test_case cases[] = {
const struct test_case cases[] = {
MAKE_TEST(basic_test),
MAKE_TEST(bpf_test_real),
MAKE_TEST(bpf_test_partial),
@@ -2017,27 +2102,51 @@ int main(int argc, char *argv[])
MAKE_TEST(bpf_test_lseek),
MAKE_TEST(bpf_test_readdirplus_not_overriding_backing),
MAKE_TEST(bpf_test_no_readdirplus_without_nodeid),
MAKE_TEST(bpf_test_revalidate_handle_backing_fd)
MAKE_TEST(bpf_test_revalidate_handle_backing_fd),
MAKE_TEST(bpf_test_lookup_postfilter),
};
#undef MAKE_TEST
if (test_options.test) {
if (test_options.test <= 0 ||
test_options.test > ARRAY_SIZE(cases))
ksft_exit_fail_msg("Invalid test\n");
bool run_test[ARRAY_SIZE(cases)];
ksft_set_plan(1);
delete_dir_tree(mount_dir, false);
delete_dir_tree(src_dir, false);
run_one_test(mount_dir, &cases[test_options.test - 1]);
} else {
ksft_set_plan(ARRAY_SIZE(cases));
for (i = 0; i < ARRAY_SIZE(cases); ++i) {
for (int i = 0; i < ARRAY_SIZE(cases); ++i)
run_test[i] = true;
if (parse_options(argc, argv, run_test, ARRAY_SIZE(cases)))
ksft_exit_fail_msg("Bad options\n");
// Seed randomness pool for testing on QEMU
// NOTE - this abuses the concept of randomness - do *not* ever do this
// on a machine for production use - the device will think it has good
// randomness when it does not.
fd = open("/dev/urandom", O_WRONLY | O_CLOEXEC);
count = 4096;
for (int i = 0; i < 128; ++i)
ioctl(fd, RNDADDTOENTCNT, &count);
close(fd);
ksft_print_header();
if (geteuid() != 0)
ksft_print_msg("Not a root, might fail to mount.\n");
if (tracing_on() != TEST_SUCCESS)
ksft_exit_fail_msg("Can't turn on tracing\n");
src_dir = setup_mount_dir(ft_src);
mount_dir = setup_mount_dir(ft_dst);
if (src_dir == NULL || mount_dir == NULL)
ksft_exit_fail_msg("Can't create a mount dir\n");
ksft_set_plan(ARRAY_SIZE(run_test));
for (i = 0; i < ARRAY_SIZE(run_test); ++i)
if (run_test[i]) {
delete_dir_tree(mount_dir, false);
delete_dir_tree(src_dir, false);
run_one_test(mount_dir, &cases[i]);
}
}
} else
ksft_cnt.ksft_xskip++;
umount2(mount_dir, MNT_FORCE);
delete_dir_tree(mount_dir, true);

View File

@@ -524,3 +524,16 @@ int readdirplus_test(struct fuse_bpf_args *fa)
}
return FUSE_BPF_BACKING;
}
SEC("test_lookup_postfilter")
int lookuppostfilter_test(struct fuse_bpf_args *fa)
{
switch(fa->opcode) {
case FUSE_LOOKUP | FUSE_PREFILTER:
return FUSE_BPF_BACKING | FUSE_BPF_POST_FILTER;
case FUSE_LOOKUP | FUSE_POSTFILTER:
return FUSE_BPF_USER_FILTER;
default:
return FUSE_BPF_BACKING;
}
}

View File

@@ -40,7 +40,6 @@ static int test_case_fail;
struct _test_options {
int file;
int test;
bool verbose;
};

View File

@@ -3,11 +3,6 @@
# kbuild file for usr/ - including initramfs image
#
# cmd_bzip2, cmd_lzma, cmd_lzo, cmd_lz4 from scripts/Makefile.lib appends the
# size at the end of the compressed file, which unfortunately does not work
# with unpack_to_rootfs(). Make size_append no-op.
override size_append := :
compress-y := shipped
compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP) := gzip
compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2