diff options
author | Andre Przywara <andre.przywara@amd.com> | 2009-06-25 06:36:49 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:33:03 -0400 |
commit | ed85c0685321a139cefd6622b21467643f0159e1 (patch) | |
tree | eb1470a8a736886fd563b02aecbc608b4dd16d54 | |
parent | 1fdbd48c242db996107f72ae4140ffe8163e26a8 (diff) |
KVM: introduce module parameter for ignoring unknown MSRs accesses
KVM will inject a #GP into the guest if that tries to access unhandled
MSRs. This will crash many guests. Although it would be the correct
way to actually handle these MSRs, we introduce a runtime switchable
module param called "ignore_msrs" (defaults to 0). If this is Y, unknown
MSR reads will return 0, while MSR writes are simply dropped. In both cases
we print a message to dmesg to inform the user about that.
You can change the behaviour at any time by saying:
# echo 1 > /sys/modules/kvm/parameters/ignore_msrs
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6aace61fdb62..0be75d53b7fd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -83,6 +83,9 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, | |||
83 | struct kvm_x86_ops *kvm_x86_ops; | 83 | struct kvm_x86_ops *kvm_x86_ops; |
84 | EXPORT_SYMBOL_GPL(kvm_x86_ops); | 84 | EXPORT_SYMBOL_GPL(kvm_x86_ops); |
85 | 85 | ||
86 | int ignore_msrs = 0; | ||
87 | module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR); | ||
88 | |||
86 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 89 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
87 | { "pf_fixed", VCPU_STAT(pf_fixed) }, | 90 | { "pf_fixed", VCPU_STAT(pf_fixed) }, |
88 | { "pf_guest", VCPU_STAT(pf_guest) }, | 91 | { "pf_guest", VCPU_STAT(pf_guest) }, |
@@ -930,8 +933,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
930 | "0x%x data 0x%llx\n", msr, data); | 933 | "0x%x data 0x%llx\n", msr, data); |
931 | break; | 934 | break; |
932 | default: | 935 | default: |
933 | pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data); | 936 | if (!ignore_msrs) { |
934 | return 1; | 937 | pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", |
938 | msr, data); | ||
939 | return 1; | ||
940 | } else { | ||
941 | pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", | ||
942 | msr, data); | ||
943 | break; | ||
944 | } | ||
935 | } | 945 | } |
936 | return 0; | 946 | return 0; |
937 | } | 947 | } |
@@ -1078,8 +1088,14 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
1078 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: | 1088 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: |
1079 | return get_msr_mce(vcpu, msr, pdata); | 1089 | return get_msr_mce(vcpu, msr, pdata); |
1080 | default: | 1090 | default: |
1081 | pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); | 1091 | if (!ignore_msrs) { |
1082 | return 1; | 1092 | pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); |
1093 | return 1; | ||
1094 | } else { | ||
1095 | pr_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr); | ||
1096 | data = 0; | ||
1097 | } | ||
1098 | break; | ||
1083 | } | 1099 | } |
1084 | *pdata = data; | 1100 | *pdata = data; |
1085 | return 0; | 1101 | return 0; |