Zachary Amsden wrote: > If you move the CPUID code out of head.S into C, it gets a lot cleaner: > > /* CPUID is virtualized. Now get vendor info. */ > cpuid(0, &new_cpu_data.cpuid_level, > (int *)&new_cpu_data.x86_vendor_id[0], > (int *)&new_cpu_data.x86_vendor_id[8], > (int *)&new_cpu_data.x86_vendor_id[4]); > > /* Get feature bits. */ > cpuid(1, &eax, &ebx, &ecx, &edx); > > new_cpu_data.x86 = (eax >> 8) & 0xf; > new_cpu_data.x86_model = (eax >> 4) & 0xf; > new_cpu_data.x86_mask = eax & 0xf; > new_cpu_data.x86_capability[0] = edx; > new_cpu_data.hard_math = 1; I guess head.S needs to do some poking at the flags to determine whether cpuid exists at all, but after that it could use C. arch/i386/kernel/cpu/common.c already has code like this, which I'm using in the xen startup. > Why do you insist that Xen have a separate kernel entry point? Because if you're going to distinguish hypervisors by putting a magic value in a register, you get the best bang for the buck if the register is EIP. If you don't want a special entrypoint, point EIP at the common code. If you want to poke values into a couple of registers, do that then jump to common. If you need to do something complex and intricate in a restricted environment, you can do that without having to fit that into the common startup sequence. It's for the same reason that calling through a function pointer is nicer than having lots of switch statements around the place. I'm not saying that Xen specifically needs this. I'm saying that there is no standard ABI for hypervisor startup, and there's not much point in pretending there is one. Sure, we can have a preferred startup mechanism which we would like people to use, and certainly all the code paths are going to converge at some point on the normal Linux startup path. But I would like this discussion to result in a design which someone else, not involved but with a pre-existing hypervisor, can look at the result and be able to make use of it as easily as possible. J