Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185947
b: refs/heads/master
c: 2bf78fa
h: refs/heads/master
i:
  185945: 2ac8911
  185943: 06c468d
v: v3
  • Loading branch information
Sheng Yang authored and Marcelo Tosatti committed Mar 1, 2010
1 parent 80ae6a2 commit f4ee821
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8a7e3f01e692cd202fb7c042cf2be9ff8c599a1e
refs/heads/master: 2bf78fa7b9b0d2917fd6587eadb3c0f6bbaf1718
55 changes: 33 additions & 22 deletions trunk/arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,16 @@ module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);

struct kvm_shared_msrs_global {
int nr;
struct kvm_shared_msr {
u32 msr;
u64 value;
} msrs[KVM_NR_SHARED_MSRS];
u32 msrs[KVM_NR_SHARED_MSRS];
};

struct kvm_shared_msrs {
struct user_return_notifier urn;
bool registered;
u64 current_value[KVM_NR_SHARED_MSRS];
struct kvm_shared_msr_values {
u64 host;
u64 curr;
} values[KVM_NR_SHARED_MSRS];
};

static struct kvm_shared_msrs_global __read_mostly shared_msrs_global;
Expand Down Expand Up @@ -147,53 +147,64 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
static void kvm_on_user_return(struct user_return_notifier *urn)
{
unsigned slot;
struct kvm_shared_msr *global;
struct kvm_shared_msrs *locals
= container_of(urn, struct kvm_shared_msrs, urn);
struct kvm_shared_msr_values *values;

for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
global = &shared_msrs_global.msrs[slot];
if (global->value != locals->current_value[slot]) {
wrmsrl(global->msr, global->value);
locals->current_value[slot] = global->value;
values = &locals->values[slot];
if (values->host != values->curr) {
wrmsrl(shared_msrs_global.msrs[slot], values->host);
values->curr = values->host;
}
}
locals->registered = false;
user_return_notifier_unregister(urn);
}

void kvm_define_shared_msr(unsigned slot, u32 msr)
static void shared_msr_update(unsigned slot, u32 msr)
{
int cpu;
struct kvm_shared_msrs *smsr;
u64 value;

smsr = &__get_cpu_var(shared_msrs);
/* only read, and nobody should modify it at this time,
* so don't need lock */
if (slot >= shared_msrs_global.nr) {
printk(KERN_ERR "kvm: invalid MSR slot!");
return;
}
rdmsrl_safe(msr, &value);
smsr->values[slot].host = value;
smsr->values[slot].curr = value;
}

void kvm_define_shared_msr(unsigned slot, u32 msr)
{
if (slot >= shared_msrs_global.nr)
shared_msrs_global.nr = slot + 1;
shared_msrs_global.msrs[slot].msr = msr;
rdmsrl_safe(msr, &value);
shared_msrs_global.msrs[slot].value = value;
for_each_online_cpu(cpu)
per_cpu(shared_msrs, cpu).current_value[slot] = value;
shared_msrs_global.msrs[slot] = msr;
/* we need ensured the shared_msr_global have been updated */
smp_wmb();
}
EXPORT_SYMBOL_GPL(kvm_define_shared_msr);

static void kvm_shared_msr_cpu_online(void)
{
unsigned i;
struct kvm_shared_msrs *locals = &__get_cpu_var(shared_msrs);

for (i = 0; i < shared_msrs_global.nr; ++i)
locals->current_value[i] = shared_msrs_global.msrs[i].value;
shared_msr_update(i, shared_msrs_global.msrs[i]);
}

void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
{
struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);

if (((value ^ smsr->current_value[slot]) & mask) == 0)
if (((value ^ smsr->values[slot].curr) & mask) == 0)
return;
smsr->current_value[slot] = value;
wrmsrl(shared_msrs_global.msrs[slot].msr, value);
smsr->values[slot].curr = value;
wrmsrl(shared_msrs_global.msrs[slot], value);
if (!smsr->registered) {
smsr->urn.on_user_return = kvm_on_user_return;
user_return_notifier_register(&smsr->urn);
Expand Down

0 comments on commit f4ee821

Please sign in to comment.