Linux QEMU内存分配问题

Linux QEMU内存分配问题,linux,memory,x86-64,qemu,mmap,Linux,Memory,X86 64,Qemu,Mmap,我似乎遇到了qemu内存分配的问题 static void * x64_syscall_mmap(void *base_addr, u64 size, u32 memory_protection, u32 mapping_visibility, s32 fd, u64 fd_offset) { s64 result = 0; __asm__ __volatile__("mov r10, %5\n" "

我似乎遇到了qemu内存分配的问题

static void *
x64_syscall_mmap(void *base_addr, u64 size, u32 memory_protection, 
                u32 mapping_visibility, s32 fd, u64 fd_offset)
{
  s64 result = 0;
  __asm__ __volatile__("mov r10, %5\n"
             "mov r8, %6\n"
             "mov r9, %7\n"
             "syscall"
              : "=a" (result)
              : "a" (9), 
                "D" ((u64)base_addr),
                "S" (size),
                "d" ((u64)memory_protection),
                "r" ((u64)mapping_visibility),
                "r" ((u64)fd),
                "r" (fd_offset)
              : "r10", "r8", "r9", "r11", "rcx", "memory");

  void *sys_result = (void *)((u64)result);
  if ((u64)result >= (u64)(-MAX_ERRNO)) {
    breakpoint();
    sys_result = NULL;
  }

  return sys_result;
}


typedef struct {
  void* base;
  u64 size;
  u64 used;
} X64MemArena;

static X64MemArena platform_mem_arena = {0};

static s32
x64_mem_arena_init(X64MemArena *mem_arena, u64 size)
{
  mem_arena->base = x64_syscall_mmap(NULL, size, PROT_READ | PROT_WRITE,
          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (mem_arena->base == NULL) {
    breakpoint();
  }
  // I tried without this call, gives same result
  if (x64_syscall_mlock(mem_arena->base, mem_arena->size) < 0) {
    breakpoint();
  }

  mem_arena->used = 0;
  mem_arena->size = size;

  return 0;
}
// ...
// used here 
if (x64_mem_arena_init(&platform_mem_arena, 1024 * 1024 * 200) == -1) {
  breakpoint();
}
静态无效*
x64系统调用mmap(无效*基本地址、u64大小、u32内存保护、,
u32映射(可见性,s32 fd,u64 fd_偏移)
{
s64结果=0;
__asm\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
mov r8,%6\n
mov r9,%7\n
“系统调用”
:“=a”(结果)
:“a”(9),
“D”((u64)基本地址),
“S”(尺寸),
“d”((u64)内存保护),
“r”((u64)映射_可见性),
“r”((u64)fd),
“r”(fd_偏移量)
:“r10”、“r8”、“r9”、“r11”、“rcx”、“内存”);
无效*系统结果=(无效*)((u64)结果);
如果((u64)结果>=(u64)(-MAX\u ERRNO)){
断点();
sys_result=NULL;
}
返回系统结果;
}
类型定义结构{
空*基;
u64尺寸;
使用u64;
}X64MemArena;
静态X64MemArena平台_mem_arena={0};
静态s32
x64_mem_arena_init(X64MemArena*mem_arena,u64尺寸)
{
mem_arena->base=x64_syscall_mmap(NULL、size、PROT_READ、PROT_WRITE、,
MAP|u PRIVATE | MAP|u ANONYMOUS,-1,0);
if(mem_arena->base==NULL){
断点();
}
//我没有打这个电话就试过了,结果也一样
如果(x64系统调用锁(内存竞技场->基础,内存竞技场->大小)<0){
断点();
}
mem_arena->used=0;
mem_arena->size=size;
返回0;
}
// ...
//这里用
如果(x64内存竞技场初始化(&platform内存竞技场,1024*1024*200)=-1){
断点();
}
qemu-system-x86_64-启用kvm-m512m-s-s-drive format=raw,file=ker.img-kernel/boot/vmlinuz-5.8.0-50-generic-追加“root=/dev/sda init=/sbin/x64 ker nokaslr”

当我在调试器中检查
(u8*)platform\u mem\u arena.base
的内容时,我得到
0xd6ad000

在qemu窗口中,我得到一行:
x86/mm:Checked W+X映射:passed,找不到W+X页面
。这可能与此有关吗


在我的Ubuntu主机上运行,效果很好。内存有效且已归零。所以,这似乎是qemu的一个问题。

qemu下的Linux从
mmap
返回成功,我猜?这是一个总内存为512MB的VM中的200MB映射,但即使物理ram很紧,过度使用也会让它成功强制
“r”
拾取R10。此外,没有理由将参数强制转换为
u64
。内核可以安全地忽略完整64位寄存器中任何可能的高垃圾,因为其C函数使用相同的原型。另外,
9
可以是
\uu NR\u mmap
而不是编写自己的包装。
x86/mm:Checked W+X映射:已通过,未找到W+X页面。
听起来不错,只要检查是否有任何write+exec页面(如果有漏洞可以写入这些页面,则可能容易受到代码注入攻击)@彼得·科尔德有些不相关,但qemu的性情令人沮丧。我经常会遇到
内核恐慌:不同步无法使用sbin/x64 ker
,这似乎是因为我运气不好,只是重新启动
qemu
,直到它工作为止。我之所以提到这一点,是因为我觉得可能有一些不直接相关的东西在这里产生了影响。@penguin359你是对的,这是不正确的。但是,它不是致命的,因为结构已归零。我也删除了这个电话,但仍然收到同样的问题。