From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Jan Beulich" <JBeulich@suse.com>,
"Roger Pau Monné" <roger.pau@citrix.com>, "Wei Liu" <wl@xen.org>,
"Igor Druzhinin" <igor.druzhinin@citrix.com>
Subject: [PATCH] x86/hvm: Propagate real error information up through hvm_load()
Date: Mon, 19 Jul 2021 12:14:49 +0100 [thread overview]
Message-ID: <20210719111449.21337-1-andrew.cooper3@citrix.com> (raw)
hvm_load() is currently a mix of -errno and -1 style error handling, which
aliases -EPERM. This leads to the following confusing diagnostics:
From userspace:
xc: info: Restoring domain
xc: error: Unable to restore HVM context (1 = Operation not permitted): Internal error
xc: error: Restore failed (1 = Operation not permitted): Internal error
xc_domain_restore: [1] Restore failed (1 = Operation not permitted)
From Xen:
(XEN) HVM10.0 restore: inconsistent xsave state (feat=0x2ff accum=0x21f xcr0=0x7 bv=0x3 err=-22)
(XEN) HVM10 restore: failed to load entry 16/0
The actual error was a bad backport, but the -EINVAL got converted to -EPERM
on the way out of the hypercall.
The overwhelming majority of *_load() handlers already use -errno consistenty.
Fix up the rest to be consistent, and fix a few other errors noticed along the
way.
* Failures of hvm_load_entry() indicate a truncated record or other bad data
size. Use -ENODATA.
* Don't use {g,}dprintk(). Omitting diagnostics in release builds is rude,
and almost everything uses unconditional printk()'s.
* Switch some errors for more appropriate ones.
Reported-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Wei Liu <wl@xen.org>
CC: Igor Druzhinin <igor.druzhinin@citrix.com>
---
xen/arch/x86/cpu/mcheck/vmce.c | 6 +++---
xen/arch/x86/emul-i8254.c | 9 +++++----
xen/arch/x86/hvm/irq.c | 6 +++---
xen/arch/x86/hvm/save.c | 25 ++++++++++++++-----------
xen/arch/x86/hvm/vioapic.c | 5 ++++-
xen/arch/x86/hvm/vpic.c | 2 +-
6 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index b1df9e9efd66..eb6434a3ba20 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -82,11 +82,11 @@ int vmce_restore_vcpu(struct vcpu *v, const struct hvm_vmce_vcpu *ctxt)
if ( ctxt->caps & ~guest_mcg_cap & ~MCG_CAP_COUNT & ~MCG_CTL_P )
{
- dprintk(XENLOG_G_ERR, "%s restore: unsupported MCA capabilities"
- " %#" PRIx64 " for %pv (supported: %#Lx)\n",
+ printk(XENLOG_G_ERR
+ "%s restore: unsupported MCA capabilities %#"PRIx64" for %pv (supported: %#Lx)\n",
is_hvm_vcpu(v) ? "HVM" : "PV", ctxt->caps,
v, guest_mcg_cap & ~MCG_CAP_COUNT);
- return -EPERM;
+ return -EINVAL;
}
v->arch.vmce.mcg_cap = ctxt->caps;
diff --git a/xen/arch/x86/emul-i8254.c b/xen/arch/x86/emul-i8254.c
index 73be4188ad41..83d7156799c8 100644
--- a/xen/arch/x86/emul-i8254.c
+++ b/xen/arch/x86/emul-i8254.c
@@ -412,7 +412,7 @@ static int pit_save(struct vcpu *v, hvm_domain_context_t *h)
static int pit_load(struct domain *d, hvm_domain_context_t *h)
{
PITState *pit = domain_vpit(d);
- int i;
+ int i, rc = 0;
if ( !has_vpit(d) )
return -ENODEV;
@@ -421,8 +421,8 @@ static int pit_load(struct domain *d, hvm_domain_context_t *h)
if ( hvm_load_entry(PIT, h, &pit->hw) )
{
- spin_unlock(&pit->lock);
- return 1;
+ rc = -ENODEV;
+ goto out;
}
/*
@@ -434,9 +434,10 @@ static int pit_load(struct domain *d, hvm_domain_context_t *h)
for ( i = 0; i < 3; i++ )
pit_load_count(pit, i, pit->hw.channels[i].count);
+ out:
spin_unlock(&pit->lock);
- return 0;
+ return rc;
}
HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM);
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 38ac5fb6c7c2..52aae4565f0c 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -773,9 +773,9 @@ static int irq_load_link(struct domain *d, hvm_domain_context_t *h)
for ( link = 0; link < 4; link++ )
if ( hvm_irq->pci_link.route[link] > 15 )
{
- gdprintk(XENLOG_ERR,
- "HVM restore: PCI-ISA link %u out of range (%u)\n",
- link, hvm_irq->pci_link.route[link]);
+ printk(XENLOG_G_ERR
+ "HVM restore: PCI-ISA link %u out of range (%u)\n",
+ link, hvm_irq->pci_link.route[link]);
return -EINVAL;
}
diff --git a/xen/arch/x86/hvm/save.c b/xen/arch/x86/hvm/save.c
index 584620985bf5..86c82cbd7456 100644
--- a/xen/arch/x86/hvm/save.c
+++ b/xen/arch/x86/hvm/save.c
@@ -51,14 +51,14 @@ int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
{
printk(XENLOG_G_ERR "HVM%d restore: bad magic number %#"PRIx32"\n",
d->domain_id, hdr->magic);
- return -1;
+ return -EINVAL;
}
if ( hdr->version != HVM_FILE_VERSION )
{
printk(XENLOG_G_ERR "HVM%d restore: unsupported version %u\n",
d->domain_id, hdr->version);
- return -1;
+ return -EINVAL;
}
cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -294,16 +294,18 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h)
struct hvm_save_descriptor *desc;
hvm_load_handler handler;
struct vcpu *v;
+ int rc;
if ( d->is_dying )
return -EINVAL;
/* Read the save header, which must be first */
if ( hvm_load_entry(HEADER, h, &hdr) != 0 )
- return -1;
+ return -ENODATA;
- if ( arch_hvm_load(d, &hdr) )
- return -1;
+ rc = arch_hvm_load(d, &hdr);
+ if ( rc )
+ return rc;
/* Down all the vcpus: we only re-enable the ones that had state saved. */
for_each_vcpu(d, v)
@@ -318,7 +320,7 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h)
printk(XENLOG_G_ERR
"HVM%d restore: save did not end with a null entry\n",
d->domain_id);
- return -1;
+ return -ENODATA;
}
/* Read the typecode of the next entry and check for the end-marker */
@@ -332,17 +334,18 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h)
{
printk(XENLOG_G_ERR "HVM%d restore: unknown entry typecode %u\n",
d->domain_id, desc->typecode);
- return -1;
+ return -EINVAL;
}
/* Load the entry */
printk(XENLOG_G_INFO "HVM%d restore: %s %"PRIu16"\n", d->domain_id,
hvm_sr_handlers[desc->typecode].name, desc->instance);
- if ( handler(d, h) != 0 )
+ rc = handler(d, h);
+ if ( rc )
{
- printk(XENLOG_G_ERR "HVM%d restore: failed to load entry %u/%u\n",
- d->domain_id, desc->typecode, desc->instance);
- return -1;
+ printk(XENLOG_G_ERR "HVM%d restore: failed to load entry %u/%u rc %d\n",
+ d->domain_id, desc->typecode, desc->instance, rc);
+ return rc;
}
process_pending_softirqs();
}
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 87370dd4172b..553c0f76eff8 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -620,7 +620,10 @@ static int ioapic_load(struct domain *d, hvm_domain_context_t *h)
d->arch.hvm.nr_vioapics != 1 )
return -EOPNOTSUPP;
- return hvm_load_entry(IOAPIC, h, &s->domU);
+ if ( hvm_load_entry(IOAPIC, h, &s->domU) )
+ return -ENODATA;
+
+ return 0;
}
HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c
index f465b7f9979a..af988a868c8a 100644
--- a/xen/arch/x86/hvm/vpic.c
+++ b/xen/arch/x86/hvm/vpic.c
@@ -430,7 +430,7 @@ static int vpic_load(struct domain *d, hvm_domain_context_t *h)
/* Which PIC is this? */
if ( inst > 1 )
- return -EINVAL;
+ return -ENOENT;
s = &d->arch.hvm.vpic[inst];
/* Load the state */
--
2.11.0
next reply other threads:[~2021-07-19 11:15 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-19 11:14 Andrew Cooper [this message]
2021-07-19 12:46 ` [PATCH] x86/hvm: Propagate real error information up through hvm_load() Jan Beulich
2021-07-19 12:56 ` Andrew Cooper
2021-07-19 13:22 ` Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210719111449.21337-1-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=igor.druzhinin@citrix.com \
--cc=roger.pau@citrix.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).