提交 986563b1 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'qemu-kvm/uq/master' into staging

...@@ -322,7 +322,8 @@ int fcntl_setfl(int fd, int flag) ...@@ -322,7 +322,8 @@ int fcntl_setfl(int fd, int flag)
* value must be terminated by whitespace, ',' or '\0'. Return -1 on * value must be terminated by whitespace, ',' or '\0'. Return -1 on
* error. * error.
*/ */
int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) int64_t strtosz_suffix_unit(const char *nptr, char **end,
const char default_suffix, int64_t unit)
{ {
int64_t retval = -1; int64_t retval = -1;
char *endptr; char *endptr;
...@@ -362,20 +363,20 @@ int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) ...@@ -362,20 +363,20 @@ int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
} }
break; break;
case STRTOSZ_DEFSUFFIX_KB: case STRTOSZ_DEFSUFFIX_KB:
mul = 1 << 10; mul = unit;
break; break;
case 0: case 0:
if (mul_required) { if (mul_required) {
goto fail; goto fail;
} }
case STRTOSZ_DEFSUFFIX_MB: case STRTOSZ_DEFSUFFIX_MB:
mul = 1ULL << 20; mul = unit * unit;
break; break;
case STRTOSZ_DEFSUFFIX_GB: case STRTOSZ_DEFSUFFIX_GB:
mul = 1ULL << 30; mul = unit * unit * unit;
break; break;
case STRTOSZ_DEFSUFFIX_TB: case STRTOSZ_DEFSUFFIX_TB:
mul = 1ULL << 40; mul = unit * unit * unit * unit;
break; break;
default: default:
goto fail; goto fail;
...@@ -405,6 +406,11 @@ fail: ...@@ -405,6 +406,11 @@ fail:
return retval; return retval;
} }
int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
{
return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
}
int64_t strtosz(const char *nptr, char **end) int64_t strtosz(const char *nptr, char **end)
{ {
return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB); return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
......
...@@ -101,11 +101,8 @@ static SysBusDeviceInfo kvmclock_info = { ...@@ -101,11 +101,8 @@ static SysBusDeviceInfo kvmclock_info = {
void kvmclock_create(void) void kvmclock_create(void)
{ {
if (kvm_enabled() && if (kvm_enabled() &&
first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
#ifdef KVM_FEATURE_CLOCKSOURCE2 (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
|| (1ULL << KVM_FEATURE_CLOCKSOURCE2)
#endif
)) {
sysbus_create_simple("kvmclock", -1, NULL); sysbus_create_simple("kvmclock", -1, NULL);
} }
} }
......
...@@ -1328,7 +1328,6 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset) ...@@ -1328,7 +1328,6 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign) int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign)
{ {
#ifdef KVM_IOEVENTFD
int ret; int ret;
struct kvm_ioeventfd iofd; struct kvm_ioeventfd iofd;
...@@ -1353,14 +1352,10 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign ...@@ -1353,14 +1352,10 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign
} }
return 0; return 0;
#else
return -ENOSYS;
#endif
} }
int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
{ {
#ifdef KVM_IOEVENTFD
struct kvm_ioeventfd kick = { struct kvm_ioeventfd kick = {
.datamatch = val, .datamatch = val,
.addr = addr, .addr = addr,
...@@ -1380,9 +1375,6 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) ...@@ -1380,9 +1375,6 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
return r; return r;
} }
return 0; return 0;
#else
return -ENOSYS;
#endif
} }
int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
......
...@@ -157,6 +157,8 @@ int fcntl_setfl(int fd, int flag); ...@@ -157,6 +157,8 @@ int fcntl_setfl(int fd, int flag);
#define STRTOSZ_DEFSUFFIX_B 'B' #define STRTOSZ_DEFSUFFIX_B 'B'
int64_t strtosz(const char *nptr, char **end); int64_t strtosz(const char *nptr, char **end);
int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix); int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
int64_t strtosz_suffix_unit(const char *nptr, char **end,
const char default_suffix, int64_t unit);
/* path.c */ /* path.c */
void init_paths(const char *prefix); void init_paths(const char *prefix);
......
...@@ -743,6 +743,7 @@ typedef struct CPUX86State { ...@@ -743,6 +743,7 @@ typedef struct CPUX86State {
uint32_t cpuid_kvm_features; uint32_t cpuid_kvm_features;
uint32_t cpuid_svm_features; uint32_t cpuid_svm_features;
bool tsc_valid; bool tsc_valid;
int tsc_khz;
/* in order to simplify APIC support, we leave this pointer to the /* in order to simplify APIC support, we leave this pointer to the
user */ user */
......
...@@ -224,6 +224,7 @@ typedef struct x86_def_t { ...@@ -224,6 +224,7 @@ typedef struct x86_def_t {
int family; int family;
int model; int model;
int stepping; int stepping;
int tsc_khz;
uint32_t features, ext_features, ext2_features, ext3_features; uint32_t features, ext_features, ext2_features, ext3_features;
uint32_t kvm_features, svm_features; uint32_t kvm_features, svm_features;
uint32_t xlevel; uint32_t xlevel;
...@@ -704,6 +705,17 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) ...@@ -704,6 +705,17 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
} else if (!strcmp(featurestr, "model_id")) { } else if (!strcmp(featurestr, "model_id")) {
pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id), pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
val); val);
} else if (!strcmp(featurestr, "tsc_freq")) {
int64_t tsc_freq;
char *err;
tsc_freq = strtosz_suffix_unit(val, &err,
STRTOSZ_DEFSUFFIX_B, 1000);
if (!*val || *err) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
x86_cpu_def->tsc_khz = tsc_freq / 1000;
} else { } else {
fprintf(stderr, "unrecognized feature %s\n", featurestr); fprintf(stderr, "unrecognized feature %s\n", featurestr);
goto error; goto error;
...@@ -872,6 +884,7 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model) ...@@ -872,6 +884,7 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_svm_features = def->svm_features; env->cpuid_svm_features = def->svm_features;
env->cpuid_ext4_features = def->ext4_features; env->cpuid_ext4_features = def->ext4_features;
env->cpuid_xlevel2 = def->xlevel2; env->cpuid_xlevel2 = def->xlevel2;
env->tsc_khz = def->tsc_khz;
if (!kvm_enabled()) { if (!kvm_enabled()) {
env->cpuid_features &= TCG_FEATURES; env->cpuid_features &= TCG_FEATURES;
env->cpuid_ext_features &= TCG_EXT_FEATURES; env->cpuid_ext_features &= TCG_EXT_FEATURES;
......
...@@ -354,6 +354,7 @@ int kvm_arch_init_vcpu(CPUState *env) ...@@ -354,6 +354,7 @@ int kvm_arch_init_vcpu(CPUState *env)
uint32_t unused; uint32_t unused;
struct kvm_cpuid_entry2 *c; struct kvm_cpuid_entry2 *c;
uint32_t signature[3]; uint32_t signature[3];
int r;
env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
...@@ -499,7 +500,20 @@ int kvm_arch_init_vcpu(CPUState *env) ...@@ -499,7 +500,20 @@ int kvm_arch_init_vcpu(CPUState *env)
qemu_add_vm_change_state_handler(cpu_update_state, env); qemu_add_vm_change_state_handler(cpu_update_state, env);
return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data); r = kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
if (r)
return r;
r = kvm_check_extension(env->kvm_state, KVM_CAP_TSC_CONTROL);
if (r && env->tsc_khz) {
r = kvm_vcpu_ioctl(env, KVM_SET_TSC_KHZ, env->tsc_khz);
if (r < 0) {
fprintf(stderr, "KVM_SET_TSC_KHZ failed\n");
return r;
}
}
return 0;
} }
void kvm_arch_reset_vcpu(CPUState *env) void kvm_arch_reset_vcpu(CPUState *env)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册