导语:上一篇(论文 §1)留下两关:安全内存的两难、TEE-REE 的 NPU 分时。这一篇对应论文 §2——作者把地基摊开:这门生意威胁有多真实、TrustZone 手里有什么牌、两大挑战的实测数字长什么样、以及为什么现成的方案一个都不能用。
一、偷模型是一门划算的生意
论文先论证这条威胁有多真实。移动应用已经开始把用户数据自动拼进 LLM prompt,用来生成个性化响应;把推理跑在设备本地上的趋势也在增长——既省掉云端查询的网络延迟,也让用户隐私数据留在本机。代价则是:专有模型被送上了手机,而手机恰恰是最容易被越狱的设备。
原文:However, storing LLM parameters on mobile devices introduces the risk of leaking the proprietary model to untrusted users, as mobile devices are prone to jailbreaking attacks.
译:然而,把 LLM 参数存在移动设备上,引入了专有模型泄露给不可信用户的风险——移动设备很容易遭受越狱攻击。
原文:Model leakage can result in significant financial losses for the model provider, as the development of such models may cost millions of dollars [77].
译:模型泄露可能给模型提供商带来重大财务损失,因为此类模型的开发成本可达数百万美元。
现实情况有多糟?论文引用了一项实证调查 [77]:
原文:According to the prior study [77], most mobile applications leave their on-device models completely unprotected, while others only encrypt model files but still allow attackers to extract plaintext model parameters from memory.
译:根据先前的研究,大多数移动应用让它们的端侧模型处于完全无保护状态;其余的也仅加密模型文件,攻击者依然能从内存中提取明文模型参数。
精读——这份调查坐实了上一篇说的“锁着存、开着用”:
- “大多数完全裸奔”说明安全措施不是拖慢上线的问题,而是压根没人做——这是安全债的常态。
- “加密了文件也被偷”说明做了一半的保护约等于没做:文件加密只能保护 flash 上的静态字节,推理时参数必然以明文形式出现在内存里,越狱后的攻击者对着内存扫就行。
- 攻击的经济账极度不对称:模型开发要数百万美元,偷一次的边际成本却接近零,还能复制无限份。防护方必须堵住所有出口,攻击方只要找到一条缝就够。
📚 注解|越狱(jailbreak):指攻破 REE 侧操作系统、拿到 root 权限。对 TEE 工程师来说,这就是威胁模型的默认前提——REE 整体不可信,TrustZone 存在的意义正是给“系统已经沦陷”的世界留一块净土。对模型厂商来说,越狱也不是小众场景:越狱工具是现成的,甚至是一键式的。
二、TrustZone 的家底:能保护什么,保护不了什么
论文用一小节把 TrustZone 的硬件机制摆清楚。CPU 分为安全态和非安全态,切换要经过 EL3 的 security monitor(smc 指令);TEE 里跑极小的 TEE OS 和可信应用 TA,REE 里跑完整的 Linux 与不可信应用。
隔离依靠三件硬件:
- TZASC:划定安全内存区,非安全态 CPU 不可访问;
- TZPC:划定安全外设,非安全态 CPU 的 MMIO 访问被禁止;
- GIC 扩展:安全设备的中断直接送进 TEE OS。
原文:To enforce memory isolation, a TrustZone Address Space Controller (TZASC) protects eight contiguous physical memory regions as secure memory, which cannot be accessed by non-secure CPUs.
译:为了实施内存隔离,TrustZone 地址空间控制器(TZASC)将八个连续的物理内存区域保护为安全内存,非安全 CPU 无法访问。
然后是全章的题眼,一句话决定了后面所有麻烦:
原文:TrustZone can only protect contiguous physical memory, but contiguous memory allocation at runtime is challenging due to fragmentation [57]. Therefore, existing TEEs typically reserve secure memory at system boot.
译:TrustZone 只能保护连续物理内存,而运行时分配连续内存因碎片化而困难。因此,现有 TEE 通常在系统启动时预留安全内存。
精读——“只能连续”这四个字的分量:
- TZASC 的过滤粒度是地址区间,而不是页:硬件按“这段物理地址归安全世界”来拦截,便宜、可靠、连 DMA 都能挡(它同时管控每个设备的 DMA 权限)。这正是 TrustZone 比 S2PT 路线多一层硬件保证的原因。
- 代价是灵活性:区间必须连续。而 Linux 跑久了之后,物理内存会碎成一片,运行时想凑出一大块连续区域,就得把占着的页一页页搬走。
- 所以现有 TEE 的通行做法是开机静态预留:启动时内存还没碎,划好一小块安全内存,一辈子不动。对几十 MB 的 TA 来说没问题;对 8GB 级别的 LLM,静态预留等于宣判这台手机残废。两难的种子就埋在这里。
📚 注解|CMA 与 movable page:Linux 内核为“设备需要连续物理地址”准备的分配器。它预留一块物理连续区域,平时借给普通系统用,但只允许可迁移页(movable page,如文件缓存、匿名用户页)落在里面。要腾出来时,内核做五步:在 CMA 外分配新页 → 解除旧页映射 → 拷贝数据 → 更新页表指向新页 → 释放旧页给 CMA。一页四步动作,8GB 参数约 200 万页——这就是后面 4.2 秒的来历。
三、第一关实测:11.6 秒的账单
传统 TEE 在开机时静态划分内存;LLM 需要 8.4GB(参数、KV cache、激活值等),静态划这么大,REE 会直接内存饥荒。所以安全内存必须跟随推理开始/结束动态扩缩。但论文用 Figure 1 实测了“朴素冷启动工作流”的代价——重启 LLM TA,从头加载一切。账单如下(8-bit Llama-3-8B,512-token prompt):
| 冷启动步骤 |
耗时 |
内存 |
| llama.cpp 启动 |
59.4ms |
40.5MB |
| 模型元数据解析 |
447.1ms |
39.2MB |
| tokenizer 初始化 |
1.8s |
60.9MB |
| KV cache 分配(CMA) |
32.9ms |
64MB |
| 激活值分配(CMA) |
137.1ms |
266.5MB |
| 参数分配(CMA) |
4.2s |
8137MB |
| 参数读取(flash) |
4.1s |
— |
| 参数解密 |
0.9s |
— |
| 冷启动合计 |
11.6s |
总占用 8.4GB |
| (对照)CPU prefill 本体 |
164.6s |
— |
其中最贵的一笔:
原文:Due to the limitation of TZASC, it must allocate contiguous physical memory using Linux CMA, causing high memory migration overhead if the CMA region is occupied (up to 4.2s for 8GB parameters).
译:受 TZASC 的限制,系统必须用 Linux CMA 分配连续物理内存;当 CMA 区域被占用时,会产生很高的页迁移开销(8GB 参数最高 4.2s)。
原文:The total cold start overhead is 11.6s in Figure 1.
译:如图 1 所示,冷启动总开销为 11.6 秒。
精读——这张账单怎么读:
- 三笔大头的根因各异:参数分配 4.2s 慢在页迁移(CMA 被占时要搬约 200 万页);参数读取 4.1s 慢在模型本身有 8GB,盘再快也要这么久;解密 0.9s 是威胁模型的必然代价——文件系统对不可信的 REE 敞开,模型文件必须加密。根因不同,单点优化谁也救不了全局。
- 这三件事占着不同硬件:分配吃 CPU,读取吃 I/O,解密吃加密单元——本来可以并行,朴素工作流却把它们串成一条线,11.6 秒就是串行的和。
- 一个不起眼的意外:tokenizer 初始化 1.8s、词表文件 60.9MB。这部分跟安全毫无关系,不加密的系统照样要付——只是从来没人把账拆到这里。
📚 注解|KV cache 与激活值:KV cache 是 prefill 阶段存下的每个 token 的键值向量,decode 时反复读取、避免重算——512-token prompt 对应 64MB。激活值是各层计算的中间结果,266.5MB。加上 8137MB 参数,构成 8.4GB 总占用(参数占 94%)。
📚 注解|tokenizer 为什么有 60.9MB:tokenizer 负责文本和 token ID 的互转,初始化要加载完整词表。Llama-3 的词表约 12.8 万条,加上合并规则等数据,词表文件本身就有几十 MB——LLM 时代的“词表”早不是几千词的小字典了。
四、第二关实测:164 秒的 CPU,与 32 毫秒的切换
NPU 在手机上早就是标配——目标检测、OCR、照片优化都靠它,而这些应用都跑在 REE,所以 NPU 在开机时就被静态配置成非安全设备。TEE 里的 LLM 只能用 CPU。Figure 1 给出了代价:CPU 跑 prefill 要 164.6s(512-token prompt)——用户等将近三分钟才见到第一个字,产品上等于不可用。
原文:Our evaluation also shows that the Rockchip NPU provides 12.5× and 1.3× optimizations on the prefill and decoding speed of Llama-3-8B, respectively.
译:我们的评估还显示,Rockchip NPU 对 Llama-3-8B 的 prefill 和解码速度分别带来 12.5× 和 1.3× 的优化。
精读——12.5× 和 1.3× 为什么差了一个数量级:prefill 把整个 prompt 一次性并行算完,是大矩阵连乘,算力越强越快,正是 NPU 的强项;decode 逐 token 生成、batch 为 1,每生成一个字都要把全部参数从内存读一遍,瓶颈在内存带宽而不是算力——NPU 的数千 TOPS 帮不上忙。这个不对称意味着 NPU 对 LLM 的价值集中在 prefill:分时设计只要保住 prefill 的使用机会,decode 的损失就有限。
直觉上的分时方案是两个世界各放一个驱动,用 detach/attach 在两边切换 NPU。论文用两个实测数字否掉了它:
原文:The detach-attach of a Rockchip NPU with the Linux driver takes 32ms. The overhead mainly stems from control plane operations, including NPU power/frequency configuration and interaction with the Linux device framework.
译:使用 Linux 驱动对 Rockchip NPU 做 detach-attach 需要 32ms。开销主要来自控制面操作,包括 NPU 电源/频率配置以及与 Linux 设备框架的交互。
原文:The Linux driver for Rockchip NPU relies on several Linux subsystems, like device, memory, interrupt, and power management, and the total code base is estimated to be over 60K LoC.
译:Rockchip NPU 的 Linux 驱动依赖设备、内存、中断、电源管理等多个 Linux 子系统,总代码量估计超过 60K LoC。
精读——32ms 的归因是这段最重要的信息:切换慢不是 NPU 硬件的固有属性,而是驱动软件栈的手续费——上电、配频率、向设备框架重新注册,全是管理动作,不碰一次实际计算。换句话说,切换开销是可以设计掉的,前提是把“管理动作”和“干活动作”拆开。60K LoC 那一笔则是安全账:驱动带着对四大 Linux 子系统的全套依赖整体搬进 TEE,等于把 TCB 从一个极小可信核膨胀成半个驱动栈——攻击面和审计负担都不可接受。
五、现有方案为什么都不行
论文用 Table 1 把既有 TEE 模型保护方案摆上四个维度打分:性能(能否用加速器)、端到端安全、兼容性(免改模型、支持量化)、内存扩展能力。逐家看死因:
| 方案 |
思路 |
死因 |
| 整模型进 TEE [42,47,51,55,61,90] |
模型+框架全部进无加速器的 TEE |
端到端安全 ✔,但只能用 CPU,性能差 |
| 混淆式 TSLP [63,73,76,81,96] |
切一部分参数混淆后卸到 REE 加速器 |
与量化不兼容;可被利用公开预训练模型的窃取攻击攻破 [97] |
| TSQP [75] |
量化感知训练,让混淆路线支持量化 |
仍属混淆路线,同样被上述攻击覆盖 |
| TEESlice [97] |
隐私感知训练,只卸出与隐私无关的参数 |
要改模型;部分参数仍在 TEE 外;缺端到端保证 |
| StrongBox [33] |
TrustZone 上建 GPU TEE,REE 单驱动兼管安全/非安全 job |
静态预留安全内存,内存效率低;推理框架在 REE 无完整性保护 |
| SecDeep [66] |
加速器静态配成安全设备 |
限制 REE 功能;数据在安全/非安全内存间换入换出,频繁加解密 |
原文:In conclusion, existing TEE-based model protection systems fail to meet performance, security, and compatibility requirements simultaneously.
译:综上,现有的基于 TEE 的模型保护系统无法同时满足性能、安全与兼容性需求。
精读——Table 1 的读法:这不是“每家有各自的小毛病”,而是两个结构性缺口决定了所有方案都会撞墙——要么缺 REE-TEE 加速器分时(整模型 TEE、SecDeep),要么缺动态安全内存扩展(StrongBox),混淆路线则干脆放弃了端到端安全。TZ-LLM 的定位就是同时补这两个洞,这也是它在表格里唯一四项全 ✔ 的原因。
📚 注解|量化(quantization):把 FP16/FP32 参数压成 8-bit/4-bit 整数,内存直接省一半以上——上一篇里 8GB 的 Llama-3-8B 就是 8-bit 量化的结果,端侧部署几乎没有不量化的。它跟“逐元素混淆参数”天生冲突:混淆对参数值做数学变换,破坏了量化所依赖的数值分布,所以 TSQP 才需要“量化感知训练”这种重训手段——而“要重新训练”对模型厂商往往就意味着“不兼容”。
六、一个诱人的替代方案,被预实验否掉
挑战一的根源是“安全内存必须连续”。有个方案看起来能绕开它:S2PT(Stage-2 页表)——把不可信 OS 和应用跑在虚拟机里,用 hypervisor 的二阶段页表把安全内存页从 REE 的地址空间里 unmap 掉。页粒度、无需连续分配、想扩就扩。
论文没有拍脑袋否决,而是在测试台上做了预实验,给出三条否决理由。
理由一:S2PT 是持续税,CMA 是一次性税。
原文:S2PT incurs continuous overhead on REE applications, while the overhead of CMA allocation is transient.
译:S2PT 给 REE 应用带来持续性开销,而 CMA 分配的开销是瞬态的。
开了 S2PT,REE 的 CPU 每次 TLB miss 都要多走一维页表。用 2MB/1GB 大页可以摊薄,但给 LLM 分配完 8GB 内存后,碎片化让多数映射退回 4KB 粒度。实测(Figure 2,Geekbench):最高 9.8%,平均 2.0%——而且是 LLM 空闲时也要一直付的常驻税。想躲?关掉二阶段转换就得撤销保护、清洗全部安全内存,连缓存参数的好处一起丢掉。
理由二:CMA 的开销藏得进 I/O 延迟。
原文:Under high memory pressure, the CMA allocation throughput is 1.9GB/s, which is similar to the I/O throughput of sequential reads on our platform (2GB/s).
译:在高内存压力下,CMA 分配吞吐为 1.9GB/s,与本平台顺序读的 I/O 吞吐(2GB/s)相当。
分配 8GB(1.9GB/s)和读模型文件(2GB/s)吞吐同量级——两件事并行跑,分配时间就能整个藏进读文件的时间里。多线程还能更快:4 线程 CMA 达到 3.8GB/s。也就是说,CMA 这笔“一次性税”本身就有被流水线吞掉的潜质。
理由三:S2PT 挡不住 DMA。
原文:S2PT does not control DMA permissions.
译:S2PT 不控制 DMA 权限。
页表只管 CPU 侧的地址翻译;外设走 DMA 直接访问物理内存,根本不经过 S2PT。想堵这个口子,要么让 EL3 monitor 拦截每一次 IOMMU 配置、把安全内存从 I/O 页表里摘掉 [48],要么拦截每一次 MMIO、校验其中的 DMA 地址 [46]——两条路都要在 REE 的热路径上加监控开销,还把 EL3 这个最高特权层塞进 TCB。而 TZASC 在硬件层面天然管控每个设备的 DMA 权限,这条路从一开始就不用付。
精读——三条理由合起来是一个决策框架:选内存保护机制时问三个问题——税是持续的还是一次性的?一次性税能不能藏进别的必付开销里?机制管得住 CPU 之外的主访存通道(DMA)吗?S2PT 三问全输,CMA 三问全过(瞬态、可藏、TZASC 补 DMA)。论文选 CMA + TZASC 不是偏好,而是被预实验逼出来的结论。
📚 注解|S2PT 与 TLB:Arm 虚拟化有两阶段地址翻译——Stage 1 是客户机 OS 自己的页表,Stage 2 是 hypervisor 控制的“物理再映射”。把安全页从 Stage 2 unmap,客户机就看不见它们。TLB 是页表翻译结果的缓存,miss 时 CPU 必须去内存里走页表——多一维就多一串内存访问,这就是那个 2.0% 的来源。
📚 注解|DMA 与 IOMMU:DMA(直接内存访问)让设备绕过 CPU 自己读写内存——摄像头出图、NPU 取参数都靠它。IOMMU 是设备侧的页表,限制设备能访问哪些物理地址。CPU 页表对 DMA 完全无约束力,这就是“S2PT 挡不住 DMA”的机理。
收束
这一章论文做了两件事:把两大挑战钉死在实测数字上(11.6s 的账单、164.6s 的 CPU、32ms 的切换、60K LoC 的依赖),把方案空间清扫干净(六类既有方案各有结构性缺口,S2PT 这条捷径被三个预实验否决)。地基验完,下一章进入正题:威胁模型与系统架构。
论文:TZ-LLM: Protecting On-Device Large Language Models with Arm TrustZone
作者:Xunjie Wang、Jiacheng Shi、Zihan Zhao、Yang Yu、Zhichao Hua、Jinyu Gu(上海交通大学 IPADS)
发表于 EuroSys '26 · arXiv:2511.13717