SEV内存加密位linux内核设置过程
1. KVM_MEMORY_ENCRYPT_OP初始化
main() // QEMU 入口函数qemu_init() // 初始化虚拟机configure_acceleratorskvm_initsev_guest_initKVM_SEV_INITsev_launch_startKVM_SEV_LAUNCH_STARTram_block_notifier_add(&sev_ram_notifier); //sev_ram_block_added KVM_MEMORY_ENCRYPT_REG_REGIONkvm_state->memcrypt_encrypt_data = sev_encrypt_data;kvm_arch_initkvm_vm_enable_capkvm_memory_listener_registermemory_listener_registercpus_register_accelmachine_run_board_init() //pc_init_isapc_init1() pc_memory_initpc_system_firmware_initpc_system_flash_mapkvm_memcrypt_encrypt_datakvm_state->memcrypt_encrypt_data
1.1、代码逻辑解析
此代码段属于 KVM 对 KVM_MEMORY_ENCRYPT_OP ioctl 的处理核心逻辑,其作用是为内存加密操作提供统一的入口,但实际功能由架构相关代码(如 AMD SVM)实现。以下为逐行分析:
case KVM_MEMORY_ENCRYPT_OP: {r = -ENOTTY; // 默认返回“不支持该操作”if (kvm_x86_ops->mem_enc_op) // 检查架构是否实现内存加密操作r = kvm_x86_ops->mem_enc_op(kvm, argp); // 调用具体实现(如 AMD SEV)break;
}
1.2、关键行为解读
1. 兼容性控制机制
-
-ENOTTY的深层含义:表示当前内核或硬件不支持内存加密功能,可能原因包括:- 未启用
CONFIG_KVM_AMD_SEV内核编译选项 - 硬件无 SEV 支持(如非 AMD EPYC CPU)
- 内核版本过旧(<4.16)或过新(≥5.10,此接口已废弃)
- 未启用
-
kvm_x86_ops->mem_enc_op的动态绑定:- AMD 实现:指向
svm_mem_enc_op()(定义于arch/x86/kvm/svm/sev.c) - Intel 实现:始终为
NULL(Intel 无等效 SEV 功能)
- AMD 实现:指向
2. 参数传递流程
// 用户态(QEMU)调用示例:
struct kvm_sev_cmd cmd = {.id = KVM_SEV_INIT, // 子命令类型.data = (unsigned long)&init_params // 具体参数结构体
};
ioctl(kvm_fd, KVM_MEMORY_ENCRYPT_OP, &cmd);// 内核态处理(svm_mem_enc_op):
static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
{struct kvm_sev_cmd cmd;copy_from_user(&cmd, argp, sizeof(cmd)); // 从用户空间复制命令return sev_handle_cmd(kvm, cmd.id, cmd.data); // 分发到 SEV 子处理函数
}
1.3、与新版接口的差异
旧版(KVM_MEMORY_ENCRYPT_OP) vs 新版(KVM_SEV_*)
| 特性 | 旧版接口 | 新版接口(≥5.10) |
|---|---|---|
| 命令结构 | 统一入口 + 子命令 ID | 独立 ioctl 命令(如 KVM_SEV_INIT) |
| 可维护性 | 参数解析耦合度高 | 类型安全,减少错误传递 |
| 功能扩展性 | 需修改共用结构体 | 独立命令互不影响 |
| 典型调用栈 | ioctl(KVM_MEMORY_ENCRYPT_OP) → svm_mem_enc_op() → sev_handle_cmd() | ioctl(KVM_SEV_INIT) → sev_guest_init() |
淘汰原因分析(内核 ≥5.10)
- 安全性:旧接口允许任意
cmd.id传递,存在非法命令注入风险 - 性能:新版省去多层间接跳转,调用路径更短
- 代码清晰度:每个 SEV 操作有独立入口,便于维护
1.4、实际应用场景验证
若在 5.4 内核 中执行以下 QEMU 命令:
qemu-system-x86_64 -machine confidential-guest-support=sev0...
内核日志将出现:
kvm_amd: SEV supported: 255 ASIDs
kvm_amd: SEV-ES supported: 255 ASIDs
svm_mem_enc_op: handling command KVM_SEV_INIT
此时旧接口仍有效,但 5.10+ 内核会拒绝此调用,需改用 KVM_SEV_INIT。
1.5、调试技巧
-
动态追踪调用路径:
echo 'p:svm_mem_enc_op arch/x86/kvm/svm/sev.c:1800 cmd_id=+0(%dx):u32' > /sys/kernel/debug/tracing/kprobe_events echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable可捕获所有经过
svm_mem_enc_op的命令 ID。 -
错误码解读:
-ENOTTY→ 检查硬件/Kconfig/内核版本-EINVAL→ 参数结构体不匹配(如 32/64 位模式混合)
1.6、迁移到新接口的代码示例
// 旧版(废弃):
struct kvm_sev_cmd cmd = {.id = KVM_SEV_INIT};
ioctl(kvm_fd, KVM_MEMORY_ENCRYPT_OP, &cmd);// 新版(推荐):
ioctl(kvm_fd, KVM_SEV_INIT, &launch_params); // 直接使用独立命令
该代码段是 KVM 内存加密功能演进的历史产物,理解其工作原理有助于调试旧版本兼容性问题,但在新开发中应遵循 AMD 官方推荐使用 KVM_SEV_* 系列专用命令。
2 qemu中设置逻辑
kvm_initkvm_memory_listener_registermemory_listener_register listener_add_address_spacekvm_region_add (kml->listener.region_add = kvm_region_add;)kvm_set_phys_mem
3 KVM_SET_USER_MEMORY_REGION
3.1、函数调用链路解析
1. 内存槽操作核心流程
2. 关键函数映射关系
| 用户预期名称 | 内核实际名称/行为 | 所属文件 |
|---|---|---|
memslot_region_add | kvm_set_memslot | virt/kvm/kvm_main.c |
__kvm_set_memory_region | virt/kvm/kvm_main.c | |
sev_mem_enc_region_add | arch/x86/kvm/svm/sev.c |
3.2、调试与验证方法
1. 动态追踪技术验证
# 使用 ftrace 跟踪内存槽添加操作
echo 'p:kvm_set_memslot kvm_set_memslot' > /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable# 观察输出示例:
# qemu-system-x86-3248 [002] ...1 5678.901234: kvm_set_memslot: (kvm_set_memslot+0x0/0x3c0)
2. 代码交叉引用检查
- 在
sev.c中搜索region_add的引用:git grep -n "region_add" arch/x86/kvm/svm/sev.c # 输出:sev.c:1873: .region_add = sev_mem_enc_region_add, - 确认
sev_mem_enc_region_add的实现细节:static int sev_mem_enc_region_add(struct kvm *kvm, u64 addr, u64 size) {// 具体实现:遍历 PFN 设置 C-bitfor (pfn = addr >> PAGE_SHIFT; pfn < (addr + size) >> PAGE_SHIFT; pfn++)set_page_encryption_mask(pfn); }
3.3、版本兼容性说明
| 内核版本 | 关键变化点 | 影响分析 |
|---|---|---|
| Linux 4.19 | 使用 kvm_set_memory_region 旧接口 | 直接操作 kvm_memory_slot |
| Linux 5.4+ | 引入 kvm_set_memslot 统一接口 | 抽象化内存槽操作 |
| Linux 5.15 | 加密回调通过 kvm_memory_encrypted_ops | 明确分离加密相关操作 |
3.4、开发者操作建议
-
正确跟踪回调函数:
// 在 sev.c 中添加调试输出 static int sev_mem_enc_region_add(struct kvm *kvm, u64 addr, u64 size) {pr_info("SEV: Encrypting memory region 0x%llx-0x%llx\n", addr, addr + size);// ...原有代码... }通过
dmesg观察加密区域触发情况。 -
API 变更应对策略:
// 兼容多版本内核的代码示例 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0)ret = kvm_set_memslot(kvm, &old, &new, KVM_MR_MOVE); #elseret = kvm_set_memory_region(kvm, &mem); #endif -
文档查阅指引:
- 官方内核文档:
Documentation/virt/kvm/api.rst(搜索KVM_SET_USER_MEMORY_REGION) - AMD SEV 白皮书:AMD Secure Encrypted Virtualization API 第 4.2 节 “Memory Encryption”
- 官方内核文档:
4 KVM_MEMORY_ENCRYPT_REG_REGION
memory_region_init_ram_from_fileqemu_ram_alloc_from_filemr->ram_block = qemu_ram_alloc_from_fd (qemu)qemu_ram_alloc_from_fd (qemu)qemu_ram_alloc_internal (qemu)ram_block_add (qemu)ram_block_notify_add (qemu)ram_block_added = sev_ram_block_added (qemu)sev_ram_block_added (qemu)kvm_arch_vm_ioctl (KVM_MEMORY_ENCRYPT_REG_REGION)svm_x86_ops->mem_enc_reg_region svm_register_enc_region
qemu_ram_alloc_internal 函数解析
qemu_ram_alloc_internal 是 QEMU 内存管理子系统中的核心内部函数,负责为虚拟机分配物理内存块(RAM Block)。它是 QEMU 内存初始化和动态扩展的关键环节,直接关联虚拟机的内存布局与性能优化。以下是其详细说明:
4.1. 函数定义与参数
函数原型
RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, // 需要分配的内存大小(字节)ram_addr_t max_size, // 最大可扩展大小(用于动态内存扩展)void (*resized)(const char*, uint64_t, void*), // 内存大小调整回调函数void *resized_opaque, // 回调函数的用户参数uint32_t flags, // 内存属性标志(如共享、只读等)const char *name, // 内存块名称(调试用)Error **errp // 错误处理指针
);
参数解析
size
初始分配的物理内存大小(例如 4GB 的虚拟机内存)。max_size
允许动态扩展的最大内存大小。若无需扩展,通常与size相同。resized回调
当内存块大小调整时触发(例如通过 balloon 驱动收缩内存)。flags
内存属性标志,常见值包括:RAM_SHARED: 内存可共享(用于多进程或热迁移)。RAM_PREALLOC: 预分配物理内存(避免惰性分配)。RAM_NORESERVE: 不预留宿主内存(允许 overcommit)。
name
唯一标识符,如"pc.ram"或"virtio-mmio.region"。
4.2. 核心功能
内存分配流程
-
创建 RAMBlock 结构体
初始化RAMBlock对象,记录内存块的元数据(大小、宿主指针、映射关系等)。RAMBlock *block = g_new0(RAMBlock, 1); block->used_length = size; block->max_length = max_size; block->flags = flags; block->idstr = g_strdup(name); -
宿主内存分配
调用宿主系统的内存分配接口(如mmap或memfd),根据flags选择策略:- 私有匿名映射(默认):
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - 大页内存(若启用):
ptr = qemu_memfd_alloc(name, size, F_SEAL_GROW | F_SEAL_SHRINK, errp); - 共享内存(
RAM_SHARED):ptr = shm_open(name, O_CREAT | O_RDWR, 0666); ftruncate(fd, size);
- 私有匿名映射(默认):
-
注册到全局链表
将新分配的RAMBlock添加到 QEMU 的全局 RAM 列表ram_list,供地址空间映射使用:QLIST_INSERT_HEAD_RCU(&ram_list.blocks, block, next); -
通知内存监听器
触发MEMORY_DEVICE_PREPLUG事件,通知设备模型(如 VGA、virtio-balloon)内存已更新。
4.3. 调用场景
场景 1:虚拟机启动初始化
在 QEMU 启动参数 -m 4G 时,主函数调用链为:
main() → qemu_init() → pc_memory_init() → memory_region_allocate_system_memory()→ qemu_ram_alloc_internal()
- 作用:分配虚拟机的主内存(
pc.ram)。
场景 2:热插拔内存设备
通过 QMP 命令 memory-device-add 动态添加 DIMM:
qmp_memory_device_add() → pc_dimm_plug() → pc_dimm_memory_plug()→ qemu_ram_alloc_internal()
- 作用:为热插拔的内存条分配新的 RAMBlock。
场景 3:内存动态调整
virtio-balloon 驱动收缩内存时:
virtio_balloon_handle_output() → qemu_balloon() → ram_block_discard_range()→ 触发 resized 回调
- 作用:释放部分内存并更新
RAMBlock的used_length。
4.4. 关键数据结构
RAMBlock 结构(部分)
struct RAMBlock {struct rcu_head rcu; // RCU 同步保护ram_addr_t offset; // 在全局地址空间中的偏移ram_addr_t used_length; // 当前使用的内存大小ram_addr_t max_length; // 允许的最大内存大小void *host; // 宿主内存指针uint32_t flags; // 内存属性标志char idstr[256]; // 唯一标识名称QLIST_ENTRY(RAMBlock) next; // 全局链表指针// ...(其他字段省略)
};
ram_list 全局变量
RAMList ram_list = {.blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks),.mru_block = NULL,
};
4.5. 性能优化机制
-
内存预分配(
RAM_PREALLOC)
避免宿主系统的惰性分配(lazy allocation),减少虚拟机运行时缺页中断的开销。 -
透明大页对齐
若宿主支持 THP(Transparent Huge Pages),qemu_ram_alloc_internal会确保分配的内存按大页对齐(如 2MB),提升 TLB 命中率。 -
内存锁(mlock)
在实时性要求高的场景(如 vhost-user),调用mlock锁定物理内存,防止被换出。
4.6. 错误处理
- 内存不足:返回
NULL并通过error_setg(errp, "Cannot allocate memory")设置错误信息。 - 重复名称:若
name已存在,触发assert(调试模式)或忽略(生产环境可能不同)。
4.7. 代码示例(简化版)
// 分配 1GB 内存,允许扩展到 2GB
RAMBlock *ram = qemu_ram_alloc_internal(1 * GiB,2 * GiB,NULL, // 无需 resized 回调NULL,RAM_SHARED, // 共享内存"guest.ram",&error_fatal
);// 将 RAMBlock 映射到地址空间
MemoryRegion *mr = g_new(MemoryRegion, 1);
memory_region_init_ram_ptr(mr, NULL, "sysmem", ram->max_length, ram->host);
address_space_add_memory(&address_space_memory, mr, 0);
小结
qemu_ram_alloc_internal 是 QEMU 内存管理的底层基石,负责:
- 物理内存分配:对接宿主系统的内存分配机制。
- 元数据管理:维护
RAMBlock的全局状态。 - 扩展性支持:为热插拔、动态调整提供基础设施。
5. KVM_MEMORY_ENCRYPT_OP和KVM_MEMORY_ENCRYPT_REG_REGION区别
5. 1、 KVM_MEMORY_ENCRYPT_OP
功能目标
- 通用加密操作:执行与内存加密相关的全局性操作,例如初始化加密上下文、密钥管理(如生成/注入密钥)、加密状态控制等。
- 示例:
- AMD SEV 中的
KVM_SEV_INIT(初始化安全加密虚拟化环境) KVM_SEV_LAUNCH_START(启动虚拟机加密流程)
- AMD SEV 中的
参数处理
- 直接传递指针:通过
argp直接传递操作类型和参数(通常是架构定义的联合体或结构体)。 - 无显式数据拷贝:依赖底层实现解析
argp指针,操作可能直接修改内核或硬件状态。
操作层级
- 架构相关实现:通过
kvm_x86_ops->mem_enc_op调用具体硬件(如 AMD SEV 或 Intel TDX)的加密操作接口。 - 影响范围:通常作用于整个虚拟机或加密会话。
5.2、 KVM_MEMORY_ENCRYPT_REG_REGION
功能目标
- 内存区域注册:将特定内存区域标记为加密/受保护区域,或从加密状态中解除注册。
- 示例:
- AMD SEV 的
KVM_SEV_LAUNCH_UPDATE_DATA(标记某块内存需加密) - 解除内存区域的加密保护(如迁移完成后)。
- AMD SEV 的
参数处理
- 结构化数据拷贝:从用户空间复制
kvm_enc_region结构体,明确包含内存区域的物理地址和长度。struct kvm_enc_region {__u64 addr; // 内存区域起始地址__u64 size; // 内存区域大小 }; - 安全性检查:通过
copy_from_user验证用户空间数据的合法性,避免非法内存访问。
操作层级
- 内存粒度操作:通过
kvm_x86_ops->mem_enc_reg_region针对特定物理地址范围进行加密配置。 - 影响范围:仅作用于单个内存区域,用于精细化管理。
关键差异总结
| 维度 | KVM_MEMORY_ENCRYPT_OP | KVM_MEMORY_ENCRYPT_REG_REGION |
|---|---|---|
| 操作类型 | 全局性加密控制(如初始化、密钥管理) | 内存区域级加密配置(注册/解注册) |
| 参数形式 | 可能为复合结构体(通过 argp 直接解析) | 固定结构体(明确地址和大小) |
| 数据传递 | 无显式用户空间拷贝 | 需从用户空间拷贝 kvm_enc_region |
| 影响范围 | 虚拟机级别或加密会话级别 | 特定物理内存区域 |
典型应用场景
-
虚拟机启动加密:
- 调用
KVM_MEMORY_ENCRYPT_OP初始化 SEV 环境。 - 多次调用
KVM_MEMORY_ENCRYPT_REG_REGION逐块注册内存到加密区域。
- 调用
-
热迁移保护:
- 迁移前通过
KVM_MEMORY_ENCRYPT_OP导出加密密钥。 - 迁移后通过
KVM_MEMORY_ENCRYPT_REG_REGION重新绑定内存区域。
- 迁移前通过
-
动态内存加密:
- 运行时按需加密敏感内存区域(如 GPU 显存),通过
KVM_MEMORY_ENCRYPT_REG_REGION动态注册。
- 运行时按需加密敏感内存区域(如 GPU 显存),通过
底层实现依赖
- 硬件支持:两者最终通过
kvm_x86_ops调用具体实现(如 AMD 的sev_mem_enc_op和sev_mem_enc_reg_region)。 - 安全性约束:内存加密操作通常需要 Hypervisor 与安全处理器(如 AMD PSP)协同完成,确保密钥不泄露。
此设计体现了 KVM 对内存加密的灵活支持:既提供全局控制接口,又允许细粒度内存管理,适配不同硬件加密方案。
相关文章:
SEV内存加密位linux内核设置过程
1. KVM_MEMORY_ENCRYPT_OP初始化 main() // QEMU 入口函数qemu_init() // 初始化虚拟机configure_acceleratorskvm_initsev_guest_initKVM_SEV_INITsev_launch_startKVM_SEV_LAUNCH_STARTram_block_notifier_add(&sev_ram_notifier); …...
强化学习(赵世钰版)-学习笔记(8.值函数方法)
本章是算法与方法的第四章,是TD算法的拓展,本质上是将状态值与行为值的表征方式,从离散的表格形式,拓展到了连续的函数形式。 表格形式的优点是直观,便于分析,缺点是数据量较大或者连续性状态或者行为空间时…...
C++编译汇编八股总结
汇编的四个阶段? 预编译(预处理): 预编译是源代码在编译之前进行的一些处理,主要包括宏定义展开、条件编译指令处理和头文件展开等。 编译: 编译器根据源代码的语法和语义规则,将源代码进行词法…...
STM32F4与串口屏通信
淘晶池串口屏操作指令集 那我们就来谈一谈串口屏与STM32F4嵌入式板子的通信 第一,串口屏传输数据给F4板子 这时,我们就该来谈一谈prints函数和printh函数的用法 prints att,length att:变量名称 length:长度(0为自动长度) printh hex hex:需要发送的…...
车载以太网网络测试-20【传输层-DOIP协议-3】
1 摘要 本文继续对ISO 13400-2定义的节点管理报文进行介绍,主要对路由激活请求/响应报文以及在线检查请求/响应报文的作用、帧结构以及示例进行介绍。 上文回顾: 车载以太网网络测试-19【传输层-DOIP协议-2】 在进行详细介绍之前,还是先回顾…...
`chromadb` 是什么
chromadb 是什么 chromadb 是一个开源的向量数据库,它专门用于存储、索引和查询向量数据。在处理自然语言处理(NLP)、计算机视觉等领域的任务时,通常会将文本、图像等数据转换为向量表示,而 chromadb 可以高效地管理这些向量,帮助开发者快速找到与查询向量最相似的向量数…...
基于深度学习的运动想象脑电信号分类研究
标题:基于深度学习的运动想象脑电信号分类研究 内容:1.摘要 背景:运动想象脑电信号分类在康复医学、人机交互等领域具有重要应用价值,但传统方法在处理复杂脑电信号时存在一定局限性。目的:本研究旨在探索基于深度学习的方法对运动想象脑电信…...
HTML5 Video标签详细教程
HTML5 Video标签详细教程 简介 HTML5引入的<video>标签为网页提供了原生视频播放功能,无需依赖Flash等第三方插件。它使得在网页中嵌入和控制视频内容变得简单而强大。本教程将详细介绍<video>标签的使用方法、属性、事件以及相关技术。 基本用法 最…...
【Hbase】查看所有表
在 HBase 中,查看所有表时,通常不需要指定命名空间,除非有特殊需求或配置。以下是一些具体情况: 默认情况下 • HBase Shell:使用list命令时,默认会列出所有命名空间中的所有表,而不仅仅是默认…...
Java 分布式高并发重试方案及实现
文章目录 Java 分布式高并发重试方案及实现一、重试机制的背景和意义二、基于 Spring Boot 的重试方案实现1. 使用 Spring Retry 实现重试机制添加依赖开启重试功能定义重试逻辑使用重试服务 2. 使用 Fast-Retry 实现高性能重试引入依赖编程式重试注解式重试 三、重试机制的注意…...
Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例)
Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例) 前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Spring Boot 观察定时任务执行5. Quartz Cron 表达式详解6. 结论 前言 在 Spring Boot 项目中,我们经常…...
关于“碰一碰发视频”系统的技术开发文档框架
以下是关于“碰一碰发视频”系统的技术开发文档框架,涵盖核心功能、技术选型、开发流程和关键模块设计,帮助您快速搭建一站式解决方案 --- 随着短视频平台的兴起,用户的创作与分享需求日益增长。而如何让视频分享更加便捷、有趣,…...
vue3之写一个aichat---已聊天组件部分功能
渲染聊天数据 这个不必多说,直接从stores/chat中取出聊天列表数据渲染就好,因为前面添加的消息都是按照用户消息、AI助手消息这样添加的,效果如图 但是需要注意每条助手消息的状态,需要根据状态显示不同的图标或不显示图标&…...
ffmpeg+ubuntu编译库(完整版本)
个人使用环境: ubuntu desktop 16.04 + ffmpeg 4.2.1创建目录在home目录下创建 ffmpeg_sources:用于下载源文件 ffmpeg_build: 存储编译后的库文件 bin:存储二进制文件(ffmpeg,ffplay,ffprobe,X264,X265等) mkdir ffmpeg_sources ffmpeg_build bin安装依赖 先执行…...
基于STC89C51的太阳自动跟踪系统的设计与实现—单片机控制步进电机实现太阳跟踪控制(仿真+程序+原理图+PCB+文档)
摘 要 随着我国经济的飞速发展,促使各种能源使用入不敷出,尤其是最主要的能源,煤炭石油资源不断消耗与短缺,因此人类寻找其他替代能源的脚步正在加快。而太阳能则具有无污染﹑可再生﹑储量大等优点,且分布范围广&…...
第五: redis 安装 / find 查找目录
redis 安装的 两种方式: mac上安装redis的两种方法_如何在mac上安装redis-CSDN博客 首先可以先看一下brew的常用命令如下: brew search ** //查找某个软件包 brew list //列出已经安装的软件的包 brew install ** //安装某个软件包,默认安装的是…...
c++--vector
1.定义vector vector的定义分为四种 (1)vector() ——————无参构造 (2)vector(size_t n,const value_type& val value_type()) ——————构造并初始化n个val (3)vector(const vector& v1) ———————拷贝构造 (4)vector(inputiterator first,inpu…...
Springboot 项目如何输出优雅的日志
我们先看效果图: 我个人比较喜欢这种格式的日志输出,对其完整; 这种格式其实就是默认的,不需要大家配置任何的 logback-spring 文件和xml中配置日志level 没有做任何多余的配置;...
Linux——进程(5)进程地址空间
先看一个程序和现象 预期现象是,子进程和父进程相互独立,子进程的gval是100,101,102....而父进程一直都是100. 结果我们并不意外,只是我们发现,父子进程的gval的地址是一样的,这有点颠覆我们的认…...
代码随想录_动态规划
代码随想录 动态规划 509.斐波那契数 509. 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n…...
c库、POSIX库、C++库、boost库之间的区别和联系
文章目录 一、区别1. 定义和来源2. 功能范围3. 可移植性4. 语言支持5. 维护和更新 二、联系1. 相互补充2. 部分功能重叠3. 共同促进编程发展4. 代码兼容性 三、总结 一、区别 1. 定义和来源 C 库函数:由 ANSI C 和 ISO C 标准定义,是 C 语言编程的基础…...
Maven常见问题汇总
Maven刷新,本地仓库无法更新 现象 This failure was cached in the local repository and resolution is not reattempted until the update interval of aliyunmaven has elapsed or updates are forced原因 因为上一次尝试下载,发现对应的仓库没有这个maven配置…...
星越L_陡坡缓降使用讲解
目录 1.陡坡缓降 1.陡坡缓降 中控屏下滑-点击陡坡缓降功能 35km/h以下时生效。35km/h-60km/h该功能暂停 60km/h以上该功能关闭...
XSS跨站脚本攻击漏洞(Cross Site Scripting)
前提概要 本文章主要用于分享XSS跨站脚本攻击漏洞基础学习,以下是对XSS跨站脚本攻击漏洞的一些个人解析,请大家结合参考其他文章中的相关信息进行归纳和补充。 XSS跨站脚本攻击漏洞描述 跨站脚本攻击(XSS)漏洞是一种常见且危害较…...
html5基于Canvas的经典打砖块游戏开发实践
基于Canvas的经典打砖块游戏开发实践 这里写目录标题 基于Canvas的经典打砖块游戏开发实践项目介绍技术栈核心功能实现1. 游戏初始化2. 游戏对象设计3. 碰撞检测系统4. 动画系统5. 用户界面设计 性能优化1. 渲染优化2. 内存管理 项目亮点技术难点突破项目总结 项目介绍 在这个…...
企业信息化的“双螺旋”——IT治理和数据治理
企业信息化的“双螺旋”——IT治理和数据治理 一、核心定义二、关键差异三、内在联系四、实践挑战与融合路径五、行业案例参考六、结论数据治理(Data Governance)和IT治理(IT Governance)是现代企业数字化转型中的关键概念,二者既有紧密关联又各有侧重。以下从定义、核心内…...
设计模式之工厂模式的优缺点
工厂模式是一种创建对象的设计模式,它将对象的创建和使用分离。以下是工厂模式的优缺点: 优点 - 解耦对象的创建和使用:使得代码的依赖关系更加清晰,使用者不需要了解对象的具体创建过程,只需要关心如何使用对象&a…...
CCBCISCN复盘
AWDP – ccfrum 自己搭了一下环境, 复现一下这道题目, 之前比赛的时候完全没想到这个漏洞要怎么打, 修也不知道要怎么修, 就仅仅是对用户名的账号和密码进行了一下过滤, 完全没起到作用, 唉, 实在太菜 如果想要尝试复现的话可以尝试拉取这个镜像, 我打完之后就直接把这个容器给…...
糊涂人寄信——递推
思路分析:当有n封信,n个信封时。第k封信没有装在第k个信封里(k从1~n),就算所有的信封都装错了。我们可以得知的是,当有1封信,时,装错类别数为0。当有两封信时,装错类别为1。 当有三…...
OpenHarmony子系统开发 - 电源管理(一)
OpenHarmony子系统开发 - 电源管理(一) 一、电源模式定制开发指导 概述 简介 OpenHarmony默认提供了电源模式(如正常模式、性能模式、省电模式、超级省电模式)的特性。但由于不同产品的部件存在差异,导致在同样场景…...
