From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: linux-kernel@vger.kernel.org, xen-devel@lists.xensource.com,
jbeulich@suse.com
Cc: Jan Beulich <jbeulich@suse.com>
Subject: Re: [PATCH 1/2] xen/hypercall: fix hypercall fallback code for very old hypervisors
Date: Tue, 30 Oct 2012 11:44:50 -0400 [thread overview]
Message-ID: <20121030154450.GA3000@phenom.dumpdata.com> (raw)
In-Reply-To: <1351519698-11069-2-git-send-email-konrad.wilk@oracle.com>
On Mon, Oct 29, 2012 at 10:08:17AM -0400, Konrad Rzeszutek Wilk wrote:
> From: Jan Beulich <jbeulich@suse.com>
>
> While copying the argument structures in HYPERVISOR_event_channel_op()
> and HYPERVISOR_physdev_op() into the local variable is sufficiently
> safe even if the actual structure is smaller than the container one,
> copying back eventual output values the same way isn't: This may
> collide with on-stack variables (particularly "rc") which may change
> between the first and second memcpy() (i.e. the second memcpy() could
> discard that change).
>
> Move the fallback code into out-of-line functions, and handle all of
> the operations known by this old a hypervisor individually: Some don't
> require copying back anything at all, and for the rest use the
> individual argument structures' sizes rather than the container's.
>
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> [v2: Reduce #define/#undef usage in HYPERVISOR_physdev_op_compat().]
> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
And it looks like I get
ERROR: "HYPERVISOR_event_channel_op_compat" [drivers/xen/xen-evtchn.ko] undefined!
when I build xen-evtchn as module. Jan did you encounter this issue on 2.6.18?
> ---
> arch/x86/include/asm/xen/hypercall.h | 21 +++------
> drivers/xen/Makefile | 2 +-
> drivers/xen/fallback.c | 78 ++++++++++++++++++++++++++++++++++
> 3 files changed, 86 insertions(+), 15 deletions(-)
> create mode 100644 drivers/xen/fallback.c
>
> diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
> index 59c226d..c812360 100644
> --- a/arch/x86/include/asm/xen/hypercall.h
> +++ b/arch/x86/include/asm/xen/hypercall.h
> @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
> return _hypercall4(int, update_va_mapping, va,
> new_val.pte, new_val.pte >> 32, flags);
> }
> +int __must_check HYPERVISOR_event_channel_op_compat(int, void *);
>
> static inline int
> HYPERVISOR_event_channel_op(int cmd, void *arg)
> {
> int rc = _hypercall2(int, event_channel_op, cmd, arg);
> - if (unlikely(rc == -ENOSYS)) {
> - struct evtchn_op op;
> - op.cmd = cmd;
> - memcpy(&op.u, arg, sizeof(op.u));
> - rc = _hypercall1(int, event_channel_op_compat, &op);
> - memcpy(arg, &op.u, sizeof(op.u));
> - }
> + if (unlikely(rc == -ENOSYS))
> + rc = HYPERVISOR_event_channel_op_compat(cmd, arg);
> return rc;
> }
>
> @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
> return _hypercall3(int, console_io, cmd, count, str);
> }
>
> +int __must_check HYPERVISOR_physdev_op_compat(int, void *);
> +
> static inline int
> HYPERVISOR_physdev_op(int cmd, void *arg)
> {
> int rc = _hypercall2(int, physdev_op, cmd, arg);
> - if (unlikely(rc == -ENOSYS)) {
> - struct physdev_op op;
> - op.cmd = cmd;
> - memcpy(&op.u, arg, sizeof(op.u));
> - rc = _hypercall1(int, physdev_op_compat, &op);
> - memcpy(arg, &op.u, sizeof(op.u));
> - }
> + if (unlikely(rc == -ENOSYS))
> + rc = HYPERVISOR_physdev_op_compat(cmd, arg);
> return rc;
> }
>
> diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
> index 0e863703..46de6cd 100644
> --- a/drivers/xen/Makefile
> +++ b/drivers/xen/Makefile
> @@ -2,7 +2,7 @@ ifneq ($(CONFIG_ARM),y)
> obj-y += manage.o balloon.o
> obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
> endif
> -obj-y += grant-table.o features.o events.o
> +obj-y += grant-table.o features.o events.o fallback.o
> obj-y += xenbus/
>
> nostackp := $(call cc-option, -fno-stack-protector)
> diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
> new file mode 100644
> index 0000000..0bdc468
> --- /dev/null
> +++ b/drivers/xen/fallback.c
> @@ -0,0 +1,78 @@
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/bug.h>
> +#include <asm/hypervisor.h>
> +#include <asm/xen/hypercall.h>
> +
> +int HYPERVISOR_event_channel_op_compat(int cmd, void *arg)
> +{
> + struct evtchn_op op;
> + int rc;
> +
> + op.cmd = cmd;
> + memcpy(&op.u, arg, sizeof(op.u));
> + rc = _hypercall1(int, event_channel_op_compat, &op);
> +
> + switch (cmd) {
> + case EVTCHNOP_close:
> + case EVTCHNOP_send:
> + case EVTCHNOP_bind_vcpu:
> + case EVTCHNOP_unmask:
> + /* no output */
> + break;
> +
> +#define COPY_BACK(eop) \
> + case EVTCHNOP_##eop: \
> + memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \
> + break
> +
> + COPY_BACK(bind_interdomain);
> + COPY_BACK(bind_virq);
> + COPY_BACK(bind_pirq);
> + COPY_BACK(status);
> + COPY_BACK(alloc_unbound);
> + COPY_BACK(bind_ipi);
> +#undef COPY_BACK
> +
> + default:
> + WARN_ON(rc != -ENOSYS);
> + break;
> + }
> +
> + return rc;
> +}
> +
> +int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
> +{
> + struct physdev_op op;
> + int rc;
> +
> + op.cmd = cmd;
> + memcpy(&op.u, arg, sizeof(op.u));
> + rc = _hypercall1(int, physdev_op_compat, &op);
> +
> + switch (cmd) {
> + case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
> + case PHYSDEVOP_set_iopl:
> + case PHYSDEVOP_set_iobitmap:
> + case PHYSDEVOP_apic_write:
> + /* no output */
> + break;
> +
> +#define COPY_BACK(pop, fld) \
> + case PHYSDEVOP_##pop: \
> + memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \
> + break
> +
> + COPY_BACK(irq_status_query, irq_status_query);
> + COPY_BACK(apic_read, apic_op);
> + COPY_BACK(ASSIGN_VECTOR, irq_op);
> +#undef COPY_BACK
> +
> + default:
> + WARN_ON(rc != -ENOSYS);
> + break;
> + }
> +
> + return rc;
> +}
> --
> 1.7.7.6
WARNING: multiple messages have this Message-ID (diff)
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: linux-kernel@vger.kernel.org, xen-devel@lists.xensource.com
Cc: Jan Beulich <jbeulich@suse.com>
Subject: Re: [PATCH 1/2] xen/hypercall: fix hypercall fallback code for very old hypervisors
Date: Tue, 30 Oct 2012 11:44:50 -0400 [thread overview]
Message-ID: <20121030154450.GA3000@phenom.dumpdata.com> (raw)
In-Reply-To: <1351519698-11069-2-git-send-email-konrad.wilk@oracle.com>
On Mon, Oct 29, 2012 at 10:08:17AM -0400, Konrad Rzeszutek Wilk wrote:
> From: Jan Beulich <jbeulich@suse.com>
>
> While copying the argument structures in HYPERVISOR_event_channel_op()
> and HYPERVISOR_physdev_op() into the local variable is sufficiently
> safe even if the actual structure is smaller than the container one,
> copying back eventual output values the same way isn't: This may
> collide with on-stack variables (particularly "rc") which may change
> between the first and second memcpy() (i.e. the second memcpy() could
> discard that change).
>
> Move the fallback code into out-of-line functions, and handle all of
> the operations known by this old a hypervisor individually: Some don't
> require copying back anything at all, and for the rest use the
> individual argument structures' sizes rather than the container's.
>
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> [v2: Reduce #define/#undef usage in HYPERVISOR_physdev_op_compat().]
> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
And it looks like I get
ERROR: "HYPERVISOR_event_channel_op_compat" [drivers/xen/xen-evtchn.ko] undefined!
when I build xen-evtchn as module. Jan did you encounter this issue on 2.6.18?
> ---
> arch/x86/include/asm/xen/hypercall.h | 21 +++------
> drivers/xen/Makefile | 2 +-
> drivers/xen/fallback.c | 78 ++++++++++++++++++++++++++++++++++
> 3 files changed, 86 insertions(+), 15 deletions(-)
> create mode 100644 drivers/xen/fallback.c
>
> diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
> index 59c226d..c812360 100644
> --- a/arch/x86/include/asm/xen/hypercall.h
> +++ b/arch/x86/include/asm/xen/hypercall.h
> @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
> return _hypercall4(int, update_va_mapping, va,
> new_val.pte, new_val.pte >> 32, flags);
> }
> +int __must_check HYPERVISOR_event_channel_op_compat(int, void *);
>
> static inline int
> HYPERVISOR_event_channel_op(int cmd, void *arg)
> {
> int rc = _hypercall2(int, event_channel_op, cmd, arg);
> - if (unlikely(rc == -ENOSYS)) {
> - struct evtchn_op op;
> - op.cmd = cmd;
> - memcpy(&op.u, arg, sizeof(op.u));
> - rc = _hypercall1(int, event_channel_op_compat, &op);
> - memcpy(arg, &op.u, sizeof(op.u));
> - }
> + if (unlikely(rc == -ENOSYS))
> + rc = HYPERVISOR_event_channel_op_compat(cmd, arg);
> return rc;
> }
>
> @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
> return _hypercall3(int, console_io, cmd, count, str);
> }
>
> +int __must_check HYPERVISOR_physdev_op_compat(int, void *);
> +
> static inline int
> HYPERVISOR_physdev_op(int cmd, void *arg)
> {
> int rc = _hypercall2(int, physdev_op, cmd, arg);
> - if (unlikely(rc == -ENOSYS)) {
> - struct physdev_op op;
> - op.cmd = cmd;
> - memcpy(&op.u, arg, sizeof(op.u));
> - rc = _hypercall1(int, physdev_op_compat, &op);
> - memcpy(arg, &op.u, sizeof(op.u));
> - }
> + if (unlikely(rc == -ENOSYS))
> + rc = HYPERVISOR_physdev_op_compat(cmd, arg);
> return rc;
> }
>
> diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
> index 0e863703..46de6cd 100644
> --- a/drivers/xen/Makefile
> +++ b/drivers/xen/Makefile
> @@ -2,7 +2,7 @@ ifneq ($(CONFIG_ARM),y)
> obj-y += manage.o balloon.o
> obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
> endif
> -obj-y += grant-table.o features.o events.o
> +obj-y += grant-table.o features.o events.o fallback.o
> obj-y += xenbus/
>
> nostackp := $(call cc-option, -fno-stack-protector)
> diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
> new file mode 100644
> index 0000000..0bdc468
> --- /dev/null
> +++ b/drivers/xen/fallback.c
> @@ -0,0 +1,78 @@
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/bug.h>
> +#include <asm/hypervisor.h>
> +#include <asm/xen/hypercall.h>
> +
> +int HYPERVISOR_event_channel_op_compat(int cmd, void *arg)
> +{
> + struct evtchn_op op;
> + int rc;
> +
> + op.cmd = cmd;
> + memcpy(&op.u, arg, sizeof(op.u));
> + rc = _hypercall1(int, event_channel_op_compat, &op);
> +
> + switch (cmd) {
> + case EVTCHNOP_close:
> + case EVTCHNOP_send:
> + case EVTCHNOP_bind_vcpu:
> + case EVTCHNOP_unmask:
> + /* no output */
> + break;
> +
> +#define COPY_BACK(eop) \
> + case EVTCHNOP_##eop: \
> + memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \
> + break
> +
> + COPY_BACK(bind_interdomain);
> + COPY_BACK(bind_virq);
> + COPY_BACK(bind_pirq);
> + COPY_BACK(status);
> + COPY_BACK(alloc_unbound);
> + COPY_BACK(bind_ipi);
> +#undef COPY_BACK
> +
> + default:
> + WARN_ON(rc != -ENOSYS);
> + break;
> + }
> +
> + return rc;
> +}
> +
> +int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
> +{
> + struct physdev_op op;
> + int rc;
> +
> + op.cmd = cmd;
> + memcpy(&op.u, arg, sizeof(op.u));
> + rc = _hypercall1(int, physdev_op_compat, &op);
> +
> + switch (cmd) {
> + case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
> + case PHYSDEVOP_set_iopl:
> + case PHYSDEVOP_set_iobitmap:
> + case PHYSDEVOP_apic_write:
> + /* no output */
> + break;
> +
> +#define COPY_BACK(pop, fld) \
> + case PHYSDEVOP_##pop: \
> + memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \
> + break
> +
> + COPY_BACK(irq_status_query, irq_status_query);
> + COPY_BACK(apic_read, apic_op);
> + COPY_BACK(ASSIGN_VECTOR, irq_op);
> +#undef COPY_BACK
> +
> + default:
> + WARN_ON(rc != -ENOSYS);
> + break;
> + }
> +
> + return rc;
> +}
> --
> 1.7.7.6
next prev parent reply other threads:[~2012-10-30 17:37 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-29 14:08 [PATCH v1] Bug-fixes for v3.7 back-ported from Jan's postings Konrad Rzeszutek Wilk
2012-10-29 14:08 ` [PATCH 1/2] xen/hypercall: fix hypercall fallback code for very old hypervisors Konrad Rzeszutek Wilk
2012-10-30 15:44 ` Konrad Rzeszutek Wilk [this message]
2012-10-30 15:44 ` Konrad Rzeszutek Wilk
2012-10-31 8:55 ` Jan Beulich
2012-11-02 16:44 ` Konrad Rzeszutek Wilk
2012-11-02 16:57 ` Jan Beulich
2012-11-02 16:57 ` Jan Beulich
2012-11-02 16:44 ` Konrad Rzeszutek Wilk
2012-10-31 8:55 ` Jan Beulich
2012-10-29 14:08 ` [PATCH 2/2] xen/xenbus: fix overflow check in xenbus_file_write() Konrad Rzeszutek Wilk
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=20121030154450.GA3000@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=jbeulich@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=xen-devel@lists.xensource.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.