/*H:126 i386-specific hypercall initialization: */ int lguest_arch_init_hypercalls(struct lg_cpu *cpu) { u32 tsc_speed; /* * The pointer to the Guest's "struct lguest_data" is the only argument. * We check that address now. */ if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1, sizeof(*cpu->lg->lguest_data))) return -EFAULT; /* * Having checked it, we simply set lg->lguest_data to point straight * into the Launcher's memory at the right place and then use * copy_to_user/from_user from now on, instead of lgread/write. I put * this in to show that I'm not immune to writing stupid * optimizations. */ cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1; /* * We insist that the Time Stamp Counter exist and doesn't change with * cpu frequency. Some devious chip manufacturers decided that TSC * changes could be handled in software. I decided that time going * backwards might be good for benchmarks, but it's bad for users. * * We also insist that the TSC be stable: the kernel detects unreliable * TSCs for its own purposes, and we use that here. */ if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable()) tsc_speed = tsc_khz; else tsc_speed = 0; if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz)) return -EFAULT; /* The interrupt code might not like the system call vector. */ if (!check_syscall_vector(cpu->lg)) kill_guest(cpu, "bad syscall vector"); return 0; }
int lguest_arch_init_hypercalls(struct lg_cpu *cpu) { u32 tsc_speed; if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1, sizeof(*cpu->lg->lguest_data))) return -EFAULT; cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1; if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable()) tsc_speed = tsc_khz; else tsc_speed = 0; if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz)) return -EFAULT; if (!check_syscall_vector(cpu->lg)) kill_guest(cpu, "bad syscall vector"); return 0; }