CC: clang-built-linux(a)googlegroups.com CC: kbuild-all(a)lists.01.org CC: linux-kernel(a)vger.kernel.org TO: Jing Zhang CC: Paolo Bonzini CC: David Matlack CC: Ricardo Koller CC: Krish Sadhukhan CC: Fuad Tabba tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 36a21d51725af2ce0700c6ebcb6b9594aac658a6 commit: cb082bfab59a224a49ae803fed52cd03e8d6b5e0 KVM: stats: Add fd-based API to read binary stats data date: 7 weeks ago :::::: branch date: 23 hours ago :::::: commit date: 7 weeks ago config: x86_64-randconfig-c001-20210806 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 42b9c2a17a0b63cccf3ac197a82f91b28e53e643) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cb082bfab59a224a49ae803fed52cd03e8d6b5e0 git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git fetch --no-tags linus master git checkout cb082bfab59a224a49ae803fed52cd03e8d6b5e0 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot clang-analyzer warnings: (new ones prefixed by >>) ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:206:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:207:34: warning: Value stored to 'c' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct dtv_frontend_properties *c = &fe->dtv_property_cache; ^ ~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:207:34: note: Value stored to 'c' during its initialization is never read struct dtv_frontend_properties *c = &fe->dtv_property_cache; ^ ~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:220:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:220:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:236:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:236:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:252:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:252:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:253:34: warning: Value stored to 'c' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct dtv_frontend_properties *c = &fe->dtv_property_cache; ^ ~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:253:34: note: Value stored to 'c' during its initialization is never read struct dtv_frontend_properties *c = &fe->dtv_property_cache; ^ ~~~~~~~~~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:270:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:270:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:297:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:297:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:323:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:323:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:413:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:413:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:425:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:425:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:439:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:439:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:455:21: warning: Value stored to 'client' during its initialization is never read [clang-analyzer-deadcode.DeadStores] struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ drivers/media/dvb-frontends/cxd2820r_core.c:455:21: note: Value stored to 'client' during its initialization is never read struct i2c_client *client = priv->client[0]; ^~~~~~ ~~~~~~~~~~~~~~~ Suppressed 2 warnings (2 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 5 warnings generated. Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 6 warnings generated. arch/x86/kvm/../../../virt/kvm/eventfd.c:385:2: warning: Value stored to 'ret' is never read [clang-analyzer-deadcode.DeadStores] ret = 0; ^ ~ arch/x86/kvm/../../../virt/kvm/eventfd.c:385:2: note: Value stored to 'ret' is never read ret = 0; ^ ~ Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 5 warnings generated. Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 5 warnings generated. Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 6 warnings generated. Suppressed 6 warnings (5 in non-user code, 1 with check filters). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 7 warnings generated. >> arch/x86/kvm/../../../virt/kvm/binary_stats.c:139:3: warning: Value stored to 'remain' is never read [clang-analyzer-deadcode.DeadStores] remain -= copylen; ^ ~~~~~~~ arch/x86/kvm/../../../virt/kvm/binary_stats.c:139:3: note: Value stored to 'remain' is never read remain -= copylen; ^ ~~~~~~~ >> arch/x86/kvm/../../../virt/kvm/binary_stats.c:141:3: warning: Value stored to 'dest' is never read [clang-analyzer-deadcode.DeadStores] dest += copylen; ^ ~~~~~~~ arch/x86/kvm/../../../virt/kvm/binary_stats.c:141:3: note: Value stored to 'dest' is never read dest += copylen; ^ ~~~~~~~ Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 5 warnings generated. Suppressed 5 warnings (5 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 7 warnings generated. Suppressed 7 warnings (7 in non-user code). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 7 warnings generated. arch/x86/kvm/emulate.c:1521:9: warning: 2nd function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage] return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc)); ^ arch/x86/kvm/emulate.c:3671:6: note: Assuming field 'modrm_reg' is not equal to VCPU_SREG_CS if (ctxt->modrm_reg == VCPU_SREG_CS || ctxt->modrm_reg > VCPU_SREG_GS) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:3671:6: note: Left side of '||' is false arch/x86/kvm/emulate.c:3671:41: note: Assuming field 'modrm_reg' is <= VCPU_SREG_GS if (ctxt->modrm_reg == VCPU_SREG_CS || ctxt->modrm_reg > VCPU_SREG_GS) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:3671:2: note: Taking false branch if (ctxt->modrm_reg == VCPU_SREG_CS || ctxt->modrm_reg > VCPU_SREG_GS) ^ arch/x86/kvm/emulate.c:3674:6: note: Assuming field 'modrm_reg' is not equal to VCPU_SREG_SS if (ctxt->modrm_reg == VCPU_SREG_SS) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:3674:2: note: Taking false branch if (ctxt->modrm_reg == VCPU_SREG_SS) ^ arch/x86/kvm/emulate.c:3679:9: note: Calling 'load_segment_descriptor' return load_segment_descriptor(ctxt, sel, ctxt->modrm_reg); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1727:6: note: 'seg' is not equal to VCPU_SREG_SS if (seg == VCPU_SREG_SS && selector == 3 && ^~~ arch/x86/kvm/emulate.c:1727:26: note: Left side of '&&' is false if (seg == VCPU_SREG_SS && selector == 3 && ^ arch/x86/kvm/emulate.c:1731:9: note: Calling '__load_segment_descriptor' return __load_segment_descriptor(ctxt, selector, seg, cpl, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1547:23: note: Assuming the condition is false bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ ^~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1548:2: note: 'desc_addr' declared without an initial value ulong desc_addr; ^~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1555:6: note: Assuming field 'mode' is not equal to X86EMUL_MODE_REAL if (ctxt->mode == X86EMUL_MODE_REAL) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1555:2: note: Taking false branch if (ctxt->mode == X86EMUL_MODE_REAL) { ^ arch/x86/kvm/emulate.c:1561:13: note: 'seg' is <= VCPU_SREG_GS } else if (seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86) { ^~~ arch/x86/kvm/emulate.c:1561:13: note: Left side of '&&' is true arch/x86/kvm/emulate.c:1561:36: note: Assuming field 'mode' is not equal to X86EMUL_MODE_VM86 } else if (seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1561:9: note: Taking false branch } else if (seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86) { ^ arch/x86/kvm/emulate.c:1575:6: note: 'seg' is not equal to VCPU_SREG_TR if (seg == VCPU_SREG_TR && (selector & (1 << 2))) ^~~ arch/x86/kvm/emulate.c:1575:26: note: Left side of '&&' is false if (seg == VCPU_SREG_TR && (selector & (1 << 2))) ^ arch/x86/kvm/emulate.c:1579:6: note: 'null_selector' is false if (null_selector) { ^~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1579:2: note: Taking false branch if (null_selector) { ^ arch/x86/kvm/emulate.c:1603:8: note: Calling 'read_segment_descriptor' ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1517:7: note: Calling 'get_descriptor_ptr' rc = get_descriptor_ptr(ctxt, selector, desc_addr_p); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1491:6: note: Assuming the condition is true if (dt.size < index * 8 + 7) ^~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1491:2: note: Taking true branch if (dt.size < index * 8 + 7) ^ arch/x86/kvm/emulate.c:1517:7: note: Returning from 'get_descriptor_ptr' rc = get_descriptor_ptr(ctxt, selector, desc_addr_p); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1518:6: note: Assuming 'rc' is equal to X86EMUL_CONTINUE if (rc != X86EMUL_CONTINUE) ^~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/emulate.c:1518:2: note: Taking false branch if (rc != X86EMUL_CONTINUE) ^ vim +/remain +139 arch/x86/kvm/../../../virt/kvm/binary_stats.c cb082bfab59a224 Jing Zhang 2021-06-18 12 cb082bfab59a224 Jing Zhang 2021-06-18 13 /** cb082bfab59a224 Jing Zhang 2021-06-18 14 * kvm_stats_read() - Common function to read from the binary statistics cb082bfab59a224 Jing Zhang 2021-06-18 15 * file descriptor. cb082bfab59a224 Jing Zhang 2021-06-18 16 * cb082bfab59a224 Jing Zhang 2021-06-18 17 * @id: identification string of the stats cb082bfab59a224 Jing Zhang 2021-06-18 18 * @header: stats header for a vm or a vcpu cb082bfab59a224 Jing Zhang 2021-06-18 19 * @desc: start address of an array of stats descriptors for a vm or a vcpu cb082bfab59a224 Jing Zhang 2021-06-18 20 * @stats: start address of stats data block for a vm or a vcpu cb082bfab59a224 Jing Zhang 2021-06-18 21 * @size_stats: the size of stats data block pointed by @stats cb082bfab59a224 Jing Zhang 2021-06-18 22 * @user_buffer: start address of userspace buffer cb082bfab59a224 Jing Zhang 2021-06-18 23 * @size: requested read size from userspace cb082bfab59a224 Jing Zhang 2021-06-18 24 * @offset: the start position from which the content will be read for the cb082bfab59a224 Jing Zhang 2021-06-18 25 * corresponding vm or vcp file descriptor cb082bfab59a224 Jing Zhang 2021-06-18 26 * cb082bfab59a224 Jing Zhang 2021-06-18 27 * The file content of a vm/vcpu file descriptor is now defined as below: cb082bfab59a224 Jing Zhang 2021-06-18 28 * +-------------+ cb082bfab59a224 Jing Zhang 2021-06-18 29 * | Header | cb082bfab59a224 Jing Zhang 2021-06-18 30 * +-------------+ cb082bfab59a224 Jing Zhang 2021-06-18 31 * | id string | cb082bfab59a224 Jing Zhang 2021-06-18 32 * +-------------+ cb082bfab59a224 Jing Zhang 2021-06-18 33 * | Descriptors | cb082bfab59a224 Jing Zhang 2021-06-18 34 * +-------------+ cb082bfab59a224 Jing Zhang 2021-06-18 35 * | Stats Data | cb082bfab59a224 Jing Zhang 2021-06-18 36 * +-------------+ cb082bfab59a224 Jing Zhang 2021-06-18 37 * Although this function allows userspace to read any amount of data (as long cb082bfab59a224 Jing Zhang 2021-06-18 38 * as in the limit) from any position, the typical usage would follow below cb082bfab59a224 Jing Zhang 2021-06-18 39 * steps: cb082bfab59a224 Jing Zhang 2021-06-18 40 * 1. Read header from offset 0. Get the offset of descriptors and stats data cb082bfab59a224 Jing Zhang 2021-06-18 41 * and some other necessary information. This is a one-time work for the cb082bfab59a224 Jing Zhang 2021-06-18 42 * lifecycle of the corresponding vm/vcpu stats fd. cb082bfab59a224 Jing Zhang 2021-06-18 43 * 2. Read id string from its offset. This is a one-time work for the lifecycle cb082bfab59a224 Jing Zhang 2021-06-18 44 * of the corresponding vm/vcpu stats fd. cb082bfab59a224 Jing Zhang 2021-06-18 45 * 3. Read descriptors from its offset and discover all the stats by parsing cb082bfab59a224 Jing Zhang 2021-06-18 46 * descriptors. This is a one-time work for the lifecycle of the cb082bfab59a224 Jing Zhang 2021-06-18 47 * corresponding vm/vcpu stats fd. cb082bfab59a224 Jing Zhang 2021-06-18 48 * 4. Periodically read stats data from its offset using pread. cb082bfab59a224 Jing Zhang 2021-06-18 49 * cb082bfab59a224 Jing Zhang 2021-06-18 50 * Return: the number of bytes that has been successfully read cb082bfab59a224 Jing Zhang 2021-06-18 51 */ cb082bfab59a224 Jing Zhang 2021-06-18 52 ssize_t kvm_stats_read(char *id, const struct kvm_stats_header *header, cb082bfab59a224 Jing Zhang 2021-06-18 53 const struct _kvm_stats_desc *desc, cb082bfab59a224 Jing Zhang 2021-06-18 54 void *stats, size_t size_stats, cb082bfab59a224 Jing Zhang 2021-06-18 55 char __user *user_buffer, size_t size, loff_t *offset) cb082bfab59a224 Jing Zhang 2021-06-18 56 { cb082bfab59a224 Jing Zhang 2021-06-18 57 ssize_t len; cb082bfab59a224 Jing Zhang 2021-06-18 58 ssize_t copylen; cb082bfab59a224 Jing Zhang 2021-06-18 59 ssize_t remain = size; cb082bfab59a224 Jing Zhang 2021-06-18 60 size_t size_desc; cb082bfab59a224 Jing Zhang 2021-06-18 61 size_t size_header; cb082bfab59a224 Jing Zhang 2021-06-18 62 void *src; cb082bfab59a224 Jing Zhang 2021-06-18 63 loff_t pos = *offset; cb082bfab59a224 Jing Zhang 2021-06-18 64 char __user *dest = user_buffer; cb082bfab59a224 Jing Zhang 2021-06-18 65 cb082bfab59a224 Jing Zhang 2021-06-18 66 size_header = sizeof(*header); cb082bfab59a224 Jing Zhang 2021-06-18 67 size_desc = header->num_desc * sizeof(*desc); cb082bfab59a224 Jing Zhang 2021-06-18 68 cb082bfab59a224 Jing Zhang 2021-06-18 69 len = KVM_STATS_NAME_SIZE + size_header + size_desc + size_stats - pos; cb082bfab59a224 Jing Zhang 2021-06-18 70 len = min(len, remain); cb082bfab59a224 Jing Zhang 2021-06-18 71 if (len <= 0) cb082bfab59a224 Jing Zhang 2021-06-18 72 return 0; cb082bfab59a224 Jing Zhang 2021-06-18 73 remain = len; cb082bfab59a224 Jing Zhang 2021-06-18 74 cb082bfab59a224 Jing Zhang 2021-06-18 75 /* cb082bfab59a224 Jing Zhang 2021-06-18 76 * Copy kvm stats header. cb082bfab59a224 Jing Zhang 2021-06-18 77 * The header is the first block of content userspace usually read out. cb082bfab59a224 Jing Zhang 2021-06-18 78 * The pos is 0 and the copylen and remain would be the size of header. cb082bfab59a224 Jing Zhang 2021-06-18 79 * The copy of the header would be skipped if offset is larger than the cb082bfab59a224 Jing Zhang 2021-06-18 80 * size of header. That usually happens when userspace reads stats cb082bfab59a224 Jing Zhang 2021-06-18 81 * descriptors and stats data. cb082bfab59a224 Jing Zhang 2021-06-18 82 */ cb082bfab59a224 Jing Zhang 2021-06-18 83 copylen = size_header - pos; cb082bfab59a224 Jing Zhang 2021-06-18 84 copylen = min(copylen, remain); cb082bfab59a224 Jing Zhang 2021-06-18 85 if (copylen > 0) { cb082bfab59a224 Jing Zhang 2021-06-18 86 src = (void *)header + pos; cb082bfab59a224 Jing Zhang 2021-06-18 87 if (copy_to_user(dest, src, copylen)) cb082bfab59a224 Jing Zhang 2021-06-18 88 return -EFAULT; cb082bfab59a224 Jing Zhang 2021-06-18 89 remain -= copylen; cb082bfab59a224 Jing Zhang 2021-06-18 90 pos += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 91 dest += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 92 } cb082bfab59a224 Jing Zhang 2021-06-18 93 cb082bfab59a224 Jing Zhang 2021-06-18 94 /* cb082bfab59a224 Jing Zhang 2021-06-18 95 * Copy kvm stats header id string. cb082bfab59a224 Jing Zhang 2021-06-18 96 * The id string is unique for every vm/vcpu, which is stored in kvm cb082bfab59a224 Jing Zhang 2021-06-18 97 * and kvm_vcpu structure. cb082bfab59a224 Jing Zhang 2021-06-18 98 * The id string is part of the stat header from the perspective of cb082bfab59a224 Jing Zhang 2021-06-18 99 * userspace, it is usually read out together with previous constant cb082bfab59a224 Jing Zhang 2021-06-18 100 * header part and could be skipped for later descriptors and stats cb082bfab59a224 Jing Zhang 2021-06-18 101 * data readings. cb082bfab59a224 Jing Zhang 2021-06-18 102 */ cb082bfab59a224 Jing Zhang 2021-06-18 103 copylen = header->id_offset + KVM_STATS_NAME_SIZE - pos; cb082bfab59a224 Jing Zhang 2021-06-18 104 copylen = min(copylen, remain); cb082bfab59a224 Jing Zhang 2021-06-18 105 if (copylen > 0) { cb082bfab59a224 Jing Zhang 2021-06-18 106 src = id + pos - header->id_offset; cb082bfab59a224 Jing Zhang 2021-06-18 107 if (copy_to_user(dest, src, copylen)) cb082bfab59a224 Jing Zhang 2021-06-18 108 return -EFAULT; cb082bfab59a224 Jing Zhang 2021-06-18 109 remain -= copylen; cb082bfab59a224 Jing Zhang 2021-06-18 110 pos += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 111 dest += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 112 } cb082bfab59a224 Jing Zhang 2021-06-18 113 cb082bfab59a224 Jing Zhang 2021-06-18 114 /* cb082bfab59a224 Jing Zhang 2021-06-18 115 * Copy kvm stats descriptors. cb082bfab59a224 Jing Zhang 2021-06-18 116 * The descriptors copy would be skipped in the typical case that cb082bfab59a224 Jing Zhang 2021-06-18 117 * userspace periodically read stats data, since the pos would be cb082bfab59a224 Jing Zhang 2021-06-18 118 * greater than the end address of descriptors cb082bfab59a224 Jing Zhang 2021-06-18 119 * (header->header.desc_offset + size_desc) causing copylen <= 0. cb082bfab59a224 Jing Zhang 2021-06-18 120 */ cb082bfab59a224 Jing Zhang 2021-06-18 121 copylen = header->desc_offset + size_desc - pos; cb082bfab59a224 Jing Zhang 2021-06-18 122 copylen = min(copylen, remain); cb082bfab59a224 Jing Zhang 2021-06-18 123 if (copylen > 0) { cb082bfab59a224 Jing Zhang 2021-06-18 124 src = (void *)desc + pos - header->desc_offset; cb082bfab59a224 Jing Zhang 2021-06-18 125 if (copy_to_user(dest, src, copylen)) cb082bfab59a224 Jing Zhang 2021-06-18 126 return -EFAULT; cb082bfab59a224 Jing Zhang 2021-06-18 127 remain -= copylen; cb082bfab59a224 Jing Zhang 2021-06-18 128 pos += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 129 dest += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 130 } cb082bfab59a224 Jing Zhang 2021-06-18 131 cb082bfab59a224 Jing Zhang 2021-06-18 132 /* Copy kvm stats values */ cb082bfab59a224 Jing Zhang 2021-06-18 133 copylen = header->data_offset + size_stats - pos; cb082bfab59a224 Jing Zhang 2021-06-18 134 copylen = min(copylen, remain); cb082bfab59a224 Jing Zhang 2021-06-18 135 if (copylen > 0) { cb082bfab59a224 Jing Zhang 2021-06-18 136 src = stats + pos - header->data_offset; cb082bfab59a224 Jing Zhang 2021-06-18 137 if (copy_to_user(dest, src, copylen)) cb082bfab59a224 Jing Zhang 2021-06-18 138 return -EFAULT; cb082bfab59a224 Jing Zhang 2021-06-18 @139 remain -= copylen; cb082bfab59a224 Jing Zhang 2021-06-18 140 pos += copylen; cb082bfab59a224 Jing Zhang 2021-06-18 @141 dest += copylen; --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org