Commit 63dbc67c authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: SEV: remove ghcb variable declarations

To avoid possible time-of-check/time-of-use issues, the GHCB should
almost never be accessed outside dump_ghcb, sev_es_sync_to_ghcb
and sev_es_sync_from_ghcb.  The only legitimate uses are to set the
exitinfo fields and to find the address of the scratch area embedded
in the ghcb.  Accessing ghcb_usage also goes through svm->sev_es.ghcb
in sev_es_validate_vmgexit(), but that is because anyway the value is
not used.

Removing a shortcut variable that contains the value of svm->sev_es.ghcb
makes these cases a bit more verbose, but it limits the chance of someone
reading the ghcb by mistake.
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 7588dbce
...@@ -2454,12 +2454,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) ...@@ -2454,12 +2454,9 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
{ {
struct vmcb_control_area *control = &svm->vmcb->control; struct vmcb_control_area *control = &svm->vmcb->control;
struct kvm_vcpu *vcpu = &svm->vcpu; struct kvm_vcpu *vcpu = &svm->vcpu;
struct ghcb *ghcb;
u64 exit_code; u64 exit_code;
u64 reason; u64 reason;
ghcb = svm->sev_es.ghcb;
/* /*
* Retrieve the exit code now even though it may not be marked valid * Retrieve the exit code now even though it may not be marked valid
* as it could help with debugging. * as it could help with debugging.
...@@ -2467,7 +2464,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) ...@@ -2467,7 +2464,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
exit_code = kvm_ghcb_get_sw_exit_code(control); exit_code = kvm_ghcb_get_sw_exit_code(control);
/* Only GHCB Usage code 0 is supported */ /* Only GHCB Usage code 0 is supported */
if (ghcb->ghcb_usage) { if (svm->sev_es.ghcb->ghcb_usage) {
reason = GHCB_ERR_INVALID_USAGE; reason = GHCB_ERR_INVALID_USAGE;
goto vmgexit_err; goto vmgexit_err;
} }
...@@ -2561,7 +2558,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) ...@@ -2561,7 +2558,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
vmgexit_err: vmgexit_err:
if (reason == GHCB_ERR_INVALID_USAGE) { if (reason == GHCB_ERR_INVALID_USAGE) {
vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
ghcb->ghcb_usage); svm->sev_es.ghcb->ghcb_usage);
} else if (reason == GHCB_ERR_INVALID_EVENT) { } else if (reason == GHCB_ERR_INVALID_EVENT) {
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n", vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n",
exit_code); exit_code);
...@@ -2571,8 +2568,8 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) ...@@ -2571,8 +2568,8 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
dump_ghcb(svm); dump_ghcb(svm);
} }
ghcb_set_sw_exit_info_1(ghcb, 2); ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
ghcb_set_sw_exit_info_2(ghcb, reason); ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, reason);
/* Resume the guest to "return" the error code. */ /* Resume the guest to "return" the error code. */
return 1; return 1;
...@@ -2637,7 +2634,6 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) ...@@ -2637,7 +2634,6 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu)
static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
{ {
struct vmcb_control_area *control = &svm->vmcb->control; struct vmcb_control_area *control = &svm->vmcb->control;
struct ghcb *ghcb = svm->sev_es.ghcb;
u64 ghcb_scratch_beg, ghcb_scratch_end; u64 ghcb_scratch_beg, ghcb_scratch_end;
u64 scratch_gpa_beg, scratch_gpa_end; u64 scratch_gpa_beg, scratch_gpa_end;
void *scratch_va; void *scratch_va;
...@@ -2713,8 +2709,8 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) ...@@ -2713,8 +2709,8 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
return 0; return 0;
e_scratch: e_scratch:
ghcb_set_sw_exit_info_1(ghcb, 2); ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA); ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_SCRATCH_AREA);
return 1; return 1;
} }
...@@ -2827,7 +2823,6 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) ...@@ -2827,7 +2823,6 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb_control_area *control = &svm->vmcb->control; struct vmcb_control_area *control = &svm->vmcb->control;
u64 ghcb_gpa, exit_code; u64 ghcb_gpa, exit_code;
struct ghcb *ghcb;
int ret; int ret;
/* Validate the GHCB */ /* Validate the GHCB */
...@@ -2852,17 +2847,16 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) ...@@ -2852,17 +2847,16 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
} }
svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva; svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva;
ghcb = svm->sev_es.ghcb_map.hva;
trace_kvm_vmgexit_enter(vcpu->vcpu_id, ghcb); trace_kvm_vmgexit_enter(vcpu->vcpu_id, svm->sev_es.ghcb);
sev_es_sync_from_ghcb(svm); sev_es_sync_from_ghcb(svm);
ret = sev_es_validate_vmgexit(svm); ret = sev_es_validate_vmgexit(svm);
if (ret) if (ret)
return ret; return ret;
ghcb_set_sw_exit_info_1(ghcb, 0); ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 0);
ghcb_set_sw_exit_info_2(ghcb, 0); ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 0);
exit_code = kvm_ghcb_get_sw_exit_code(control); exit_code = kvm_ghcb_get_sw_exit_code(control);
switch (exit_code) { switch (exit_code) {
...@@ -2902,13 +2896,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) ...@@ -2902,13 +2896,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
break; break;
case 1: case 1:
/* Get AP jump table address */ /* Get AP jump table address */
ghcb_set_sw_exit_info_2(ghcb, sev->ap_jump_table); ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, sev->ap_jump_table);
break; break;
default: default:
pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
control->exit_info_1); control->exit_info_1);
ghcb_set_sw_exit_info_1(ghcb, 2); ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT); ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT);
} }
ret = 1; ret = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment