On Sun, Jun 5, 2011 at 2:36 PM, Avi Kivity <avi@xxxxxxxxxx> wrote: > On 06/03/2011 06:03 PM, Christoffer Dall wrote: >> >> Targets KVM support for Cortex A-15 processors. >> >> Contains no real functionality but all the framework components, >> make files, header files and some tracing functionality. >> >> + >> +struct kvm_regs { >> + __u32 regs0_7[8]; /* Unbanked regs. (r0 - r7) */ >> + __u32 fiq_regs8_12[5]; /* Banked fiq regs. (r8 - r12) */ >> + __u32 usr_regs8_12[5]; /* Banked usr registers (r8 - r12) */ >> + __u32 reg13[6]; /* Banked r13, indexed by MODE_ */ >> + __u32 reg14[6]; /* Banked r13, indexed by MODE_ */ >> + __u32 reg15; >> + __u32 cpsr; >> + __u32 spsr[5]; /* Banked SPSR, indexed by MODE_ */ >> + struct { >> + __u32 c2_base0; >> + __u32 c2_base1; >> + __u32 c3_dacr; >> + } cp15; >> + >> +}; >> + >> +struct kvm_sregs { >> +}; >> + >> +struct kvm_fpu { >> +}; >> + >> +struct kvm_guest_debug_arch { >> +}; >> + >> +struct kvm_debug_exit_arch { >> +}; > > Presumably, to be filled in later? > I simply didn't look at these yet and didn't need them yet. I will look into this later on. >> + >> +/* Get vcpu register for current mode */ >> +#define vcpu_reg(_vcpu, _reg_num) \ >> + (*kvm_vcpu_reg((_vcpu), _reg_num, vcpu_mode(_vcpu))) >> + >> +/* Get vcpu register for specific mode */ >> +#define vcpu_reg_m(_vcpu, _reg_num, _mode) \ >> + (*kvm_vcpu_reg(_vcpu, _reg_num, _mode)) >> + >> +#define vcpu_cpsr(_vcpu) \ >> + (_vcpu->arch.regs.cpsr) >> + >> +/* Get vcpu SPSR for current mode */ >> +#define vcpu_spsr(_vcpu) \ >> + kvm_vcpu_spsr(_vcpu, vcpu_mode(_vcpu)) >> + >> +/* Get vcpu SPSR for specific mode */ >> +#define vcpu_spsr_m(_vcpu, _mode) \ >> + kvm_vcpu_spsr(_vcpu, _mode) >> + >> +#define MODE_HAS_SPSR(_vcpu) \ >> + ((vcpu_mode(_vcpu))< MODE_USR) >> + >> +#define VCPU_MODE_PRIV(_vcpu) \ >> + (((vcpu_mode(_vcpu)) == MODE_USR) ? 0 : 1) > > Please use static inlines. Yes, you'll need more helpers to set registers, > but it's worth it, especially as some macros evaluate an argument multiple > times. ok. > >> +if VIRTUALIZATION >> + >> +config KVM >> + bool "Kernel-based Virtual Machine (KVM) support" >> + select PREEMPT_NOTIFIERS >> + select ANON_INODES >> + select KVM_ARM_HOST >> + select KVM_MMIO >> + ---help--- >> + Support hosting virtualized guest machines. You will also >> + need to select one or more of the processor modules below. >> + >> + This module provides access to the hardware capabilities through >> + a character device node named /dev/kvm. >> + >> + If unsure, say N. > > I see you can't support a modular build, which is a pity. > My concern is that I map in code that needs to be in place for running in Hyp mode. Of course I just need to pin these, so it should be possible. I'll look into this as well. >> + >> +static int k_show(struct seq_file *m, void *v) >> +{ >> + print_kvm_debug_info(&seq_printf, m); >> + return 0; >> +} >> + >> +static void *k_start(struct seq_file *m, loff_t *pos) >> +{ >> + return *pos< 1 ? (void *)1 : NULL; >> +} >> + >> +static void *k_next(struct seq_file *m, void *v, loff_t *pos) >> +{ >> + ++*pos; >> + return NULL; >> +} >> + >> +static void k_stop(struct seq_file *m, void *v) >> +{ >> +} >> + >> +static const struct seq_operations kvmproc_op = { >> + .start = k_start, >> + .next = k_next, >> + .stop = k_stop, >> + .show = k_show >> +}; >> + >> +static int kvm_open(struct inode *inode, struct file *file) >> +{ >> + return seq_open(file,&kvmproc_op); >> +} >> + >> +static const struct file_operations proc_kvm_operations = { >> + .open = kvm_open, >> + .read = seq_read, >> + .llseek = seq_lseek, >> + .release = seq_release, >> +}; >> + >> +static int arm_init(void) >> +{ >> + int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); >> + if (rc == 0) >> + proc_create("kvm", 0, NULL,&proc_kvm_operations); >> + return rc; >> +} > > /proc is frowned upon these days. Is there no better place for this?+ >> Yeah, this is actually quite legacy and probably shouldn't have been included. I will give this a thorough overhaul before next patch series. >> +/* >> + * Return a pointer to the register number valid in the specified mode of >> + * the virtual CPU. >> + */ >> +u32* kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode) >> +{ >> + struct kvm_vcpu_regs *regs; >> + u8 reg_idx; >> + BUG_ON(reg_num> 15); >> + >> + regs =&vcpu->arch.regs; >> + >> + /* The PC is trivial */ >> + if (reg_num == 15) >> + return&(regs->pc); >> + >> + /* Non-banked registers */ >> + if (reg_num< 8) >> + return&(regs->usr_regs[reg_num]); >> + >> + /* Banked registers r13 and r14 */ >> + if (reg_num>= 13) { >> + reg_idx = reg_num - 13; /* 0=r13 and 1=r14 */ >> + switch (mode) { >> + case MODE_FIQ: >> + return&(regs->fiq_regs[reg_idx + 5]); >> + case MODE_IRQ: >> + return&(regs->irq_regs[reg_idx]); >> + case MODE_SVC: >> + return&(regs->svc_regs[reg_idx]); >> + case MODE_ABT: >> + return&(regs->abt_regs[reg_idx]); >> + case MODE_UND: >> + return&(regs->und_regs[reg_idx]); >> + case MODE_USR: >> + case MODE_SYS: >> + return&(regs->usr_regs[reg_idx]); >> + } >> + } >> + >> + /* Banked FIQ registers r8-r12 */ >> + if (reg_num>= 8&& reg_num<= 12) { >> + if (mode == MODE_FIQ) { >> + reg_idx = reg_num - 8; /* 0=r8, ..., 4=r12 */ >> + return&(regs->fiq_regs[reg_idx]); >> + } else >> + return&(regs->usr_regs[reg_num]); >> + } > > You could have a static 2D array indexed by mode and register number, > returning an offsetof() into the vcpu structure. You think it's simpler or faster? I don't quite see the incentive. It's not going to be called a whole lot given the Virt. Extensions. > >> + >> + BUG(); >> + return NULL; >> +} >> >> diff --git a/arch/arm/kvm/trace.c b/arch/arm/kvm/trace.c >> new file mode 100644 >> index 0000000..8ea1155 [snip] >> + >> +void kvm_arm_count_event(unsigned int event) >> +{ >> + if (event>= KVM_EVENTC_ITEMS) >> + return; >> + >> + kvm_eventc_log[event].cnt++; >> +} > > We've switched to ftrace for this sort of thing. Simply add a tracepoint > for each interesting event, and the kernel can provide you with > > - a count of events ('perf stat') > - a log of events ('trace-cmd record/report'), possibly with other kernel > events interspersed > - a running histogram ('kvm_stat') > > with near-zero impact when disabled. > > See include/trace/events/kvm.h, arch/x86/kvm/trace.h. Will do, thanks. > > -- > error compiling committee.c: too many arguments to function > > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html