Friday, February 7, 2020

kvm_all.c - struct KVMState, CPUState, CPUX86State

KVMState结构包含QEMU中VM表示的重要文件描述符。例如fd, vmfd

struct KVMState
{
    AccelState parent_obj;

    int nr_slots;
    int fd;
    int vmfd;
    int coalesced_mmio;
    int coalesced_pio;
    struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
    bool coalesced_flush_in_progress;
……
};

QEMU维护一个CPUState结构,它位于include/hw/core/cpu.h,用于定义一个CPU内核/线程的状态。CPUState的结构含义如下:

cpu_index:CPU索引,这里面能获取到很多信息。
cluster_index:标识此CPU所在的群集。对于未定义集群的板卡或未分配给集群的“松散” CPU,将为UNASSIGNED_CLUSTER_INDEX;否则,它将与CPU对象的TYPE_CPU_CLUSTERQOM父级的cluster-id属性相同。
nr_cores:此CPU软件包中的内核数。
nr_threads:此CPU中的线程数。
running:如果CPU当前正在运行(无锁),则为true。
has_waiter:如果CPU当前正在等待cpu_exec_end,true。在cpu_list_lock下有效。
created:指示是否已成功创建CPU线程。
interrupt_request:表示一个未决的中断请求。
halted:如果CPU处于挂起状态,则为非零。
stop:表示待处理的停止请求。
stopped:表示CPU已被人为停止。
unplug:指示挂起的CPU拔出请求。
crash_occurred:表示操作系统报告了该CPU的紧急崩溃事件
singlestep_enabled:单步执行的标志。
icount_extra:直到下一个定时器事件的指令。
can_do_io:如果内存映射的IO安全,则为非零。确定性执行要求仅对TB的最后一条指令执行IO,以便中断立即生效。
cpu_ases:指向CPUAddressSpaces数组的指针(定义该CPU具有的AddressSpaces)
num_ases:@cpu_ases中的CPUAddressSpaces数
as:指向第一个地址空间的指针,以方便仅具有单个地址空间的目标
env_ptr:指向特定于子类的CPUArchState字段的指针。
icount_decr_ptr:指向子类中IcountDecr字段的指针。
gdb_regs:其他GDB寄存器。
gdb_num_regs:GDB可访问的寄存器总数。
gdb_num_g_regs:GDB’g'数据包中的寄存器数。
next_cpu:下一个CPU共享TB缓存。
opaque:用户数据。
mem_io_pc:访问内存的主机程序计数器。
kvm_fd:KVM的vCPU文件描述符。
work_mutex:锁定以防止多次访问queued_work_xxx。
queued_work_first:第一个异步工作挂起。
trace_dstate_delayed:延迟了对trace_dstate的更改(包括对trace_dstate的所有更改)。
trace_dstate:此vCPU的事件的动态跟踪状态(位掩码)。
plugin_mask:插件事件位图。仅通过异步工作进行修改。
ignore_memory_transaction_failures:具有相同名称的MachineState标志的缓存副本:允许开发板禁止调用CPU do_transaction_failed挂钩函数。

对于例如X86模式的CPU来说,QEMU会维护一个CPUX86State结构列表,每个虚拟CPU对应一个结构。它位于target/i386/cpu.h,通用寄存器(以及RSP和RIP)的内容是CPUX86State的一部分。由于定义太长,我删除了绝大多数内容。

typedef struct CPUX86State {
    /* standard registers */
    target_ulong regs[CPU_NB_REGS];
    target_ulong eip;
    target_ulong eflags; 
   ……
    target_ulong cr[5]; /* NOTE: cr1 is unused */
    int32_t a20_mask;
……
    ZMMReg xmm_regs[CPU_NB_REGS == 8 ? 8 : 32];
    ZMMReg xmm_t0;
    MMXReg mmx_t0;
……
    /* For KVM */
    uint32_t mp_state;
    int32_t exception_nr;
    int32_t interrupt_injected;
    uint8_t soft_interrupt;
    uint8_t exception_pending;
    uint8_t exception_injected;
……
} CPUX86State;