* [PATCH 1/5] xen: Enable console tty by default in domU if it's not a dummy
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
@ 2008-05-21 8:38 ` Markus Armbruster
2008-05-22 0:26 ` Andrew Morton
2008-05-21 8:39 ` [PATCH 2/5] xen pvfb: Pointer z-axis (mouse wheel) support Markus Armbruster
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 8:38 UTC (permalink / raw)
To: linux-kernel
Cc: virtualization, Jeremy Fitzhardinge, xen-devel, linux-fbdev-devel,
adaplas, linux-input, dmitry.torokhov, mingo, akpm, Pat Campbell
Without console= arguments on the kernel command line, the first
console to register becomes enabled and the preferred console (the one
behind /dev/console). This is normally tty (assuming
CONFIG_VT_CONSOLE is enabled, which it commonly is).
This is okay as long tty is a useful console. But unless we have the
PV framebuffer, and it is enabled for this domain, tty0 in domU is
merely a dummy. In that case, we want the preferred console to be the
Xen console hvc0, and we want it without having to fiddle with the
kernel command line. Commit b8c2d3dfbc117dff26058fbac316b8acfc2cb5f7
did that for us.
Since we now have the PV framebuffer, we want to enable and prefer tty
again, but only when PVFB is enabled. But even then we still want to
enable the Xen console as well.
Problem: when tty registers, we can't yet know whether the PVFB is
enabled. By the time we can know (xenstore is up), the console setup
game is over.
Solution: enable console tty by default, but keep hvc as the preferred
console. Change the preferred console to tty when PVFB probes
successfully, unless we've been given console kernel parameters.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
arch/x86/xen/enlighten.c | 4 +++-
drivers/video/xen-fbfront.c | 25 +++++++++++++++++++++++++
include/linux/console.h | 2 ++
kernel/printk.c | 3 +++
4 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c8a56e4..a9f8d6a 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1242,8 +1242,10 @@ asmlinkage void __init xen_start_kernel(void)
? __pa(xen_start_info->mod_start) : 0;
boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
- if (!is_initial_xendomain())
+ if (!is_initial_xendomain()) {
+ add_preferred_console("tty", 0, NULL);
add_preferred_console("hvc", 0, NULL);
+ }
/* Start the world */
start_kernel();
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 619a6f8..4e10876 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -18,6 +18,7 @@
* frame buffer.
*/
+#include <linux/console.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fb.h>
@@ -48,6 +49,7 @@ struct xenfb_info {
static u32 xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
+static void xenfb_make_preferred_console(void);
static int xenfb_remove(struct xenbus_device *);
static void xenfb_init_shared_page(struct xenfb_info *);
static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
@@ -348,6 +350,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
if (ret < 0)
goto error;
+ xenfb_make_preferred_console();
return 0;
error_nomem:
@@ -358,6 +361,28 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
return ret;
}
+static __devinit void
+xenfb_make_preferred_console(void)
+{
+ struct console *c;
+
+ if (console_set_on_cmdline)
+ return;
+
+ acquire_console_sem();
+ for (c = console_drivers; c; c = c->next) {
+ if (!strcmp(c->name, "tty") && c->index == 0)
+ break;
+ }
+ release_console_sem();
+ if (c) {
+ unregister_console(c);
+ c->flags |= CON_CONSDEV;
+ c->flags &= ~CON_PRINTBUFFER; /* don't print again */
+ register_console(c);
+ }
+}
+
static int xenfb_resume(struct xenbus_device *dev)
{
struct xenfb_info *info = dev->dev.driver_data;
diff --git a/include/linux/console.h b/include/linux/console.h
index a4f27fb..248e6e3 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -108,6 +108,8 @@ struct console {
struct console *next;
};
+extern int console_set_on_cmdline;
+
extern int add_preferred_console(char *name, int idx, char *options);
extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
extern void register_console(struct console *);
diff --git a/kernel/printk.c b/kernel/printk.c
index 8fb01c3..028ed75 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -121,6 +121,8 @@ struct console_cmdline
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
static int selected_console = -1;
static int preferred_console = -1;
+int console_set_on_cmdline;
+EXPORT_SYMBOL(console_set_on_cmdline);
/* Flag: console code may call schedule() */
static int console_may_schedule;
@@ -890,6 +892,7 @@ static int __init console_setup(char *str)
*s = 0;
__add_preferred_console(buf, idx, options, brl_options);
+ console_set_on_cmdline = 1;
return 1;
}
__setup("console=", console_setup);
--
1.5.3.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/5] xen: Enable console tty by default in domU if it's not a dummy
2008-05-21 8:38 ` [PATCH 1/5] xen: Enable console tty by default in domU if it's not a dummy Markus Armbruster
@ 2008-05-22 0:26 ` Andrew Morton
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Morton @ 2008-05-22 0:26 UTC (permalink / raw)
To: Markus Armbruster
Cc: jeremy, xen-devel, linux-fbdev-devel, adaplas, dmitry.torokhov,
linux-kernel, virtualization, mingo, plc, linux-input
On Wed, 21 May 2008 10:38:50 +0200
Markus Armbruster <armbru@redhat.com> wrote:
> Without console= arguments on the kernel command line, the first
> console to register becomes enabled and the preferred console (the one
> behind /dev/console). This is normally tty (assuming
> CONFIG_VT_CONSOLE is enabled, which it commonly is).
>
> This is okay as long tty is a useful console. But unless we have the
> PV framebuffer, and it is enabled for this domain, tty0 in domU is
> merely a dummy. In that case, we want the preferred console to be the
> Xen console hvc0, and we want it without having to fiddle with the
> kernel command line. Commit b8c2d3dfbc117dff26058fbac316b8acfc2cb5f7
> did that for us.
>
> Since we now have the PV framebuffer, we want to enable and prefer tty
> again, but only when PVFB is enabled. But even then we still want to
> enable the Xen console as well.
>
> Problem: when tty registers, we can't yet know whether the PVFB is
> enabled. By the time we can know (xenstore is up), the console setup
> game is over.
>
> Solution: enable console tty by default, but keep hvc as the preferred
> console. Change the preferred console to tty when PVFB probes
> successfully, unless we've been given console kernel parameters.
What a stunningly good changelog - I'd buy the tee-shirt.
Ack on the non-xen bits.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] xen pvfb: Pointer z-axis (mouse wheel) support
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
2008-05-21 8:38 ` [PATCH 1/5] xen: Enable console tty by default in domU if it's not a dummy Markus Armbruster
@ 2008-05-21 8:39 ` Markus Armbruster
2008-05-21 8:40 ` [PATCH 3/5] xen pvfb: Module aliases to support module autoloading Markus Armbruster
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 8:39 UTC (permalink / raw)
To: linux-kernel
Cc: Jeremy Fitzhardinge, xen-devel, linux-fbdev-devel, adaplas,
dmitry.torokhov, virtualization, mingo, Pat Campbell, linux-input,
akpm
Add z-axis motion to pointer events. Backward compatible, because
there's space for the z-axis in union xenkbd_in_event, and old
backends zero it.
Derived from
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/57dfe0098000
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/1edfea26a2a9
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/c3ff0b26f664
Signed-off-by: Pat Campbell <plc@novell.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
drivers/input/xen-kbdfront.c | 8 +++++++-
include/xen/interface/io/kbdif.h | 2 ++
2 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index 0f47f46..9da4452 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -66,6 +66,9 @@ static irqreturn_t input_handler(int rq, void *dev_id)
case XENKBD_TYPE_MOTION:
input_report_rel(dev, REL_X, event->motion.rel_x);
input_report_rel(dev, REL_Y, event->motion.rel_y);
+ if (event->motion.rel_z)
+ input_report_rel(dev, REL_WHEEL,
+ -event->motion.rel_z);
break;
case XENKBD_TYPE_KEY:
dev = NULL;
@@ -84,6 +87,9 @@ static irqreturn_t input_handler(int rq, void *dev_id)
case XENKBD_TYPE_POS:
input_report_abs(dev, ABS_X, event->pos.abs_x);
input_report_abs(dev, ABS_Y, event->pos.abs_y);
+ if (event->pos.rel_z)
+ input_report_rel(dev, REL_WHEEL,
+ -event->pos.rel_z);
break;
}
if (dev)
@@ -152,7 +158,7 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
for (i = BTN_LEFT; i <= BTN_TASK; i++)
set_bit(i, ptr->keybit);
- ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
diff --git a/include/xen/interface/io/kbdif.h b/include/xen/interface/io/kbdif.h
index fb97f42..8066c78 100644
--- a/include/xen/interface/io/kbdif.h
+++ b/include/xen/interface/io/kbdif.h
@@ -49,6 +49,7 @@ struct xenkbd_motion {
uint8_t type; /* XENKBD_TYPE_MOTION */
int32_t rel_x; /* relative X motion */
int32_t rel_y; /* relative Y motion */
+ int32_t rel_z; /* relative Z motion (wheel) */
};
struct xenkbd_key {
@@ -61,6 +62,7 @@ struct xenkbd_position {
uint8_t type; /* XENKBD_TYPE_POS */
int32_t abs_x; /* absolute X position (in FB pixels) */
int32_t abs_y; /* absolute Y position (in FB pixels) */
+ int32_t rel_z; /* relative Z motion (wheel) */
};
#define XENKBD_IN_EVENT_SIZE 40
--
1.5.3.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/5] xen pvfb: Module aliases to support module autoloading
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
2008-05-21 8:38 ` [PATCH 1/5] xen: Enable console tty by default in domU if it's not a dummy Markus Armbruster
2008-05-21 8:39 ` [PATCH 2/5] xen pvfb: Pointer z-axis (mouse wheel) support Markus Armbruster
@ 2008-05-21 8:40 ` Markus Armbruster
2008-05-21 8:40 ` [PATCH 4/5] xen pvfb: Zero unused bytes in events sent to backend Markus Armbruster
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 8:40 UTC (permalink / raw)
To: linux-kernel
Cc: Jeremy Fitzhardinge, xen-devel, linux-fbdev-devel, adaplas,
dmitry.torokhov, virtualization, mingo, Pat Campbell, linux-input,
akpm
These are mostly for completeness and consistency with the other
frontends, as PVFB is typically compiled in rather than a module.
Derived from
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/5e294e29a43e
While there, add module descriptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
drivers/input/xen-kbdfront.c | 2 ++
drivers/video/xen-fbfront.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index 9da4452..eaf69cf 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -343,4 +343,6 @@ static void __exit xenkbd_cleanup(void)
module_init(xenkbd_init);
module_exit(xenkbd_cleanup);
+MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:vkbd");
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 4e10876..5553e51 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -572,4 +572,6 @@ static void __exit xenfb_cleanup(void)
module_init(xenfb_init);
module_exit(xenfb_cleanup);
+MODULE_DESCRIPTION("Xen virtual framebuffer device frontend");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:vfb");
--
1.5.3.3
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/5] xen pvfb: Zero unused bytes in events sent to backend
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
` (2 preceding siblings ...)
2008-05-21 8:40 ` [PATCH 3/5] xen pvfb: Module aliases to support module autoloading Markus Armbruster
@ 2008-05-21 8:40 ` Markus Armbruster
2008-05-21 8:40 ` [PATCH 5/5] xen pvfb: Dynamic mode support (screen resizing) Markus Armbruster
2008-05-21 9:09 ` [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Jeremy Fitzhardinge
5 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 8:40 UTC (permalink / raw)
To: linux-kernel
Cc: Jeremy Fitzhardinge, xen-devel, linux-fbdev-devel, adaplas,
dmitry.torokhov, virtualization, mingo, Pat Campbell, linux-input,
akpm
This isn't a security flaw (the backend can see all our memory
anyway). But it's the right thing to do all the same.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
drivers/video/xen-fbfront.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 5553e51..291eef6 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -61,6 +61,7 @@ static void xenfb_do_update(struct xenfb_info *info,
union xenfb_out_event event;
u32 prod;
+ memset(&event, 0, sizeof(event));
event.type = XENFB_TYPE_UPDATE;
event.update.x = x;
event.update.y = y;
--
1.5.3.3
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/5] xen pvfb: Dynamic mode support (screen resizing)
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
` (3 preceding siblings ...)
2008-05-21 8:40 ` [PATCH 4/5] xen pvfb: Zero unused bytes in events sent to backend Markus Armbruster
@ 2008-05-21 8:40 ` Markus Armbruster
2008-05-21 9:09 ` [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Jeremy Fitzhardinge
5 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 8:40 UTC (permalink / raw)
To: linux-kernel
Cc: Jeremy Fitzhardinge, xen-devel, linux-fbdev-devel, adaplas,
dmitry.torokhov, virtualization, mingo, Pat Campbell, linux-input,
akpm
The pvfb backend indicates dynamic mode support by creating node
feature_resize with a non-zero value in its xenstore directory.
xen-fbfront sends a resize notification event on mode change. Fully
backwards compatible both ways.
Framebuffer size and initial resolution can be controlled through
kernel parameter xen_fbfront.video. The backend enforces a separate
size limit, which it advertises in node videoram in its xenstore
directory.
xen-kbdfront gets the maximum screen resolution from nodes width and
height in the backend's xenstore directory instead of hardcoding it.
Additional goodie: support for larger framebuffers (512M on a 64-bit
system with 4K pages).
Changing the number of bits per pixels dynamically is not supported,
yet.
Ported from
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/92f7b3144f41
http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/bfc040135633
Signed-off-by: Pat Campbell <plc@novell.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
drivers/input/xen-kbdfront.c | 10 ++
drivers/video/xen-fbfront.c | 183 ++++++++++++++++++++++++++++++++------
include/xen/interface/io/fbif.h | 29 +++++-
3 files changed, 188 insertions(+), 34 deletions(-)
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index eaf69cf..9ce3b3b 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -300,6 +300,16 @@ InitWait:
*/
if (dev->state != XenbusStateConnected)
goto InitWait; /* no InitWait seen yet, fudge it */
+
+ /* Set input abs params to match backend screen res */
+ if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+ "width", "%d", &val) > 0)
+ input_set_abs_params(info->ptr, ABS_X, 0, val, 0, 0);
+
+ if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+ "height", "%d", &val) > 0)
+ input_set_abs_params(info->ptr, ABS_Y, 0, val, 0, 0);
+
break;
case XenbusStateClosing:
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 291eef6..47ed39b 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -43,23 +43,47 @@ struct xenfb_info {
struct xenfb_page *page;
unsigned long *mfns;
int update_wanted; /* XENFB_TYPE_UPDATE wanted */
+ int feature_resize; /* XENFB_TYPE_RESIZE ok */
+ struct xenfb_resize resize; /* protected by resize_lock */
+ int resize_dpy; /* ditto */
+ spinlock_t resize_lock;
struct xenbus_device *xbdev;
};
-static u32 xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
+#define XENFB_DEFAULT_FB_LEN (XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8)
+
+enum { KPARAM_MEM, KPARAM_WIDTH, KPARAM_HEIGHT, KPARAM_CNT };
+static int video[KPARAM_CNT] = { 2, XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(video, int, NULL, 0);
+MODULE_PARM_DESC(video,
+ "Video memory size in MB, width, height in pixels (default 2,800,600)");
static void xenfb_make_preferred_console(void);
static int xenfb_remove(struct xenbus_device *);
-static void xenfb_init_shared_page(struct xenfb_info *);
+static void xenfb_init_shared_page(struct xenfb_info *, struct fb_info *);
static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
static void xenfb_disconnect_backend(struct xenfb_info *);
+static void xenfb_send_event(struct xenfb_info *info,
+ union xenfb_out_event *event)
+{
+ u32 prod;
+
+ prod = info->page->out_prod;
+ /* caller ensures !xenfb_queue_full() */
+ mb(); /* ensure ring space available */
+ XENFB_OUT_RING_REF(info->page, prod) = *event;
+ wmb(); /* ensure ring contents visible */
+ info->page->out_prod = prod + 1;
+
+ notify_remote_via_irq(info->irq);
+}
+
static void xenfb_do_update(struct xenfb_info *info,
int x, int y, int w, int h)
{
union xenfb_out_event event;
- u32 prod;
memset(&event, 0, sizeof(event));
event.type = XENFB_TYPE_UPDATE;
@@ -68,14 +92,19 @@ static void xenfb_do_update(struct xenfb_info *info,
event.update.width = w;
event.update.height = h;
- prod = info->page->out_prod;
/* caller ensures !xenfb_queue_full() */
- mb(); /* ensure ring space available */
- XENFB_OUT_RING_REF(info->page, prod) = event;
- wmb(); /* ensure ring contents visible */
- info->page->out_prod = prod + 1;
+ xenfb_send_event(info, &event);
+}
- notify_remote_via_irq(info->irq);
+static void xenfb_do_resize(struct xenfb_info *info)
+{
+ union xenfb_out_event event;
+
+ memset(&event, 0, sizeof(event));
+ event.resize = info->resize;
+
+ /* caller ensures !xenfb_queue_full() */
+ xenfb_send_event(info, &event);
}
static int xenfb_queue_full(struct xenfb_info *info)
@@ -87,12 +116,28 @@ static int xenfb_queue_full(struct xenfb_info *info)
return prod - cons == XENFB_OUT_RING_LEN;
}
+static void xenfb_handle_resize_dpy(struct xenfb_info *info)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&info->resize_lock, flags);
+ if (info->resize_dpy) {
+ if (!xenfb_queue_full(info)) {
+ info->resize_dpy = 0;
+ xenfb_do_resize(info);
+ }
+ }
+ spin_unlock_irqrestore(&info->resize_lock, flags);
+}
+
static void xenfb_refresh(struct xenfb_info *info,
int x1, int y1, int w, int h)
{
unsigned long flags;
- int y2 = y1 + h - 1;
int x2 = x1 + w - 1;
+ int y2 = y1 + h - 1;
+
+ xenfb_handle_resize_dpy(info);
if (!info->update_wanted)
return;
@@ -225,6 +270,57 @@ static ssize_t xenfb_write(struct fb_info *p, const char __user *buf,
return res;
}
+static int
+xenfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct xenfb_info *xenfb_info;
+ int required_mem_len;
+
+ xenfb_info = info->par;
+
+ if (!xenfb_info->feature_resize) {
+ if (var->xres == video[KPARAM_WIDTH] &&
+ var->yres == video[KPARAM_HEIGHT] &&
+ var->bits_per_pixel == xenfb_info->page->depth) {
+ return 0;
+ }
+ return -EINVAL;
+ }
+
+ /* Can't resize past initial width and height */
+ if (var->xres > video[KPARAM_WIDTH] || var->yres > video[KPARAM_HEIGHT])
+ return -EINVAL;
+
+ required_mem_len = var->xres * var->yres * xenfb_info->page->depth / 8;
+ if (var->bits_per_pixel == xenfb_info->page->depth &&
+ var->xres <= info->fix.line_length / (XENFB_DEPTH / 8) &&
+ required_mem_len <= info->fix.smem_len) {
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int xenfb_set_par(struct fb_info *info)
+{
+ struct xenfb_info *xenfb_info;
+ unsigned long flags;
+
+ xenfb_info = info->par;
+
+ spin_lock_irqsave(&xenfb_info->resize_lock, flags);
+ xenfb_info->resize.type = XENFB_TYPE_RESIZE;
+ xenfb_info->resize.width = info->var.xres;
+ xenfb_info->resize.height = info->var.yres;
+ xenfb_info->resize.stride = info->fix.line_length;
+ xenfb_info->resize.depth = info->var.bits_per_pixel;
+ xenfb_info->resize.offset = 0;
+ xenfb_info->resize_dpy = 1;
+ spin_unlock_irqrestore(&xenfb_info->resize_lock, flags);
+ return 0;
+}
+
static struct fb_ops xenfb_fb_ops = {
.owner = THIS_MODULE,
.fb_read = fb_sys_read,
@@ -233,6 +329,8 @@ static struct fb_ops xenfb_fb_ops = {
.fb_fillrect = xenfb_fillrect,
.fb_copyarea = xenfb_copyarea,
.fb_imageblit = xenfb_imageblit,
+ .fb_check_var = xenfb_check_var,
+ .fb_set_par = xenfb_set_par,
};
static irqreturn_t xenfb_event_handler(int rq, void *dev_id)
@@ -261,6 +359,8 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
{
struct xenfb_info *info;
struct fb_info *fb_info;
+ int fb_size;
+ int val;
int ret;
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -268,18 +368,35 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
return -ENOMEM;
}
+
+ /* Limit kernel param videoram amount to what is in xenstore */
+ if (xenbus_scanf(XBT_NIL, dev->otherend, "videoram", "%d", &val) == 1) {
+ if (val < video[KPARAM_MEM])
+ video[KPARAM_MEM] = val;
+ }
+
+ /* If requested res does not fit in available memory, use default */
+ fb_size = video[KPARAM_MEM] * 1024 * 1024;
+ if (video[KPARAM_WIDTH] * video[KPARAM_HEIGHT] * XENFB_DEPTH / 8
+ > fb_size) {
+ video[KPARAM_WIDTH] = XENFB_WIDTH;
+ video[KPARAM_HEIGHT] = XENFB_HEIGHT;
+ fb_size = XENFB_DEFAULT_FB_LEN;
+ }
+
dev->dev.driver_data = info;
info->xbdev = dev;
info->irq = -1;
info->x1 = info->y1 = INT_MAX;
spin_lock_init(&info->dirty_lock);
+ spin_lock_init(&info->resize_lock);
- info->fb = vmalloc(xenfb_mem_len);
+ info->fb = vmalloc(fb_size);
if (info->fb == NULL)
goto error_nomem;
- memset(info->fb, 0, xenfb_mem_len);
+ memset(info->fb, 0, fb_size);
- info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages);
if (!info->mfns)
@@ -290,8 +407,6 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
if (!info->page)
goto error_nomem;
- xenfb_init_shared_page(info);
-
/* abusing framebuffer_alloc() to allocate pseudo_palette */
fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL);
if (fb_info == NULL)
@@ -304,9 +419,9 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
fb_info->screen_base = info->fb;
fb_info->fbops = &xenfb_fb_ops;
- fb_info->var.xres_virtual = fb_info->var.xres = info->page->width;
- fb_info->var.yres_virtual = fb_info->var.yres = info->page->height;
- fb_info->var.bits_per_pixel = info->page->depth;
+ fb_info->var.xres_virtual = fb_info->var.xres = video[KPARAM_WIDTH];
+ fb_info->var.yres_virtual = fb_info->var.yres = video[KPARAM_HEIGHT];
+ fb_info->var.bits_per_pixel = XENFB_DEPTH;
fb_info->var.red = (struct fb_bitfield){16, 8, 0};
fb_info->var.green = (struct fb_bitfield){8, 8, 0};
@@ -318,9 +433,9 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
fb_info->var.vmode = FB_VMODE_NONINTERLACED;
fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_info->fix.line_length = info->page->line_length;
+ fb_info->fix.line_length = fb_info->var.xres * XENFB_DEPTH / 8;
fb_info->fix.smem_start = 0;
- fb_info->fix.smem_len = xenfb_mem_len;
+ fb_info->fix.smem_len = fb_size;
strcpy(fb_info->fix.id, "xen");
fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
fb_info->fix.accel = FB_ACCEL_NONE;
@@ -337,6 +452,8 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
fb_info->fbdefio = &xenfb_defio;
fb_deferred_io_init(fb_info);
+ xenfb_init_shared_page(info, fb_info);
+
ret = register_framebuffer(fb_info);
if (ret) {
fb_deferred_io_cleanup(fb_info);
@@ -389,7 +506,7 @@ static int xenfb_resume(struct xenbus_device *dev)
struct xenfb_info *info = dev->dev.driver_data;
xenfb_disconnect_backend(info);
- xenfb_init_shared_page(info);
+ xenfb_init_shared_page(info, info->fb_info);
return xenfb_connect_backend(dev, info);
}
@@ -417,20 +534,23 @@ static unsigned long vmalloc_to_mfn(void *address)
return pfn_to_mfn(vmalloc_to_pfn(address));
}
-static void xenfb_init_shared_page(struct xenfb_info *info)
+static void xenfb_init_shared_page(struct xenfb_info *info,
+ struct fb_info *fb_info)
{
int i;
+ int epd = PAGE_SIZE / sizeof(info->mfns[0]);
for (i = 0; i < info->nr_pages; i++)
info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
- info->page->pd[0] = vmalloc_to_mfn(info->mfns);
- info->page->pd[1] = 0;
- info->page->width = XENFB_WIDTH;
- info->page->height = XENFB_HEIGHT;
- info->page->depth = XENFB_DEPTH;
- info->page->line_length = (info->page->depth / 8) * info->page->width;
- info->page->mem_length = xenfb_mem_len;
+ for (i = 0; i * epd < info->nr_pages; i++)
+ info->page->pd[i] = vmalloc_to_mfn(&info->mfns[i * epd]);
+
+ info->page->width = fb_info->var.xres;
+ info->page->height = fb_info->var.yres;
+ info->page->depth = fb_info->var.bits_per_pixel;
+ info->page->line_length = fb_info->fix.line_length;
+ info->page->mem_length = fb_info->fix.smem_len;
info->page->in_cons = info->page->in_prod = 0;
info->page->out_cons = info->page->out_prod = 0;
}
@@ -530,6 +650,11 @@ InitWait:
val = 0;
if (val)
info->update_wanted = 1;
+
+ if (xenbus_scanf(XBT_NIL, dev->otherend,
+ "feature-resize", "%d", &val) < 0)
+ val = 0;
+ info->feature_resize = val;
break;
case XenbusStateClosing:
diff --git a/include/xen/interface/io/fbif.h b/include/xen/interface/io/fbif.h
index 5a934dd..974a51e 100644
--- a/include/xen/interface/io/fbif.h
+++ b/include/xen/interface/io/fbif.h
@@ -49,11 +49,27 @@ struct xenfb_update {
int32_t height; /* rect height */
};
+/*
+ * Framebuffer resize notification event
+ * Capable backend sets feature-resize in xenstore.
+ */
+#define XENFB_TYPE_RESIZE 3
+
+struct xenfb_resize {
+ uint8_t type; /* XENFB_TYPE_RESIZE */
+ int32_t width; /* width in pixels */
+ int32_t height; /* height in pixels */
+ int32_t stride; /* stride in bytes */
+ int32_t depth; /* depth in bits */
+ int32_t offset; /* start offset within framebuffer */
+};
+
#define XENFB_OUT_EVENT_SIZE 40
union xenfb_out_event {
uint8_t type;
struct xenfb_update update;
+ struct xenfb_resize resize;
char pad[XENFB_OUT_EVENT_SIZE];
};
@@ -105,15 +121,18 @@ struct xenfb_page {
* Each directory page holds PAGE_SIZE / sizeof(*pd)
* framebuffer pages, and can thus map up to PAGE_SIZE *
* PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
- * sizeof(unsigned long) == 4, that's 4 Megs. Two directory
- * pages should be enough for a while.
+ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2
+ * Megs 64 bit. 256 directories give enough room for a 512
+ * Meg framebuffer with a max resolution of 12,800x10,240.
+ * Should be enough for a while with room leftover for
+ * expansion.
*/
- unsigned long pd[2];
+ unsigned long pd[256];
};
/*
- * Wart: xenkbd needs to know resolution. Put it here until a better
- * solution is found, but don't leak it to the backend.
+ * Wart: xenkbd needs to know default resolution. Put it here until a
+ * better solution is found, but don't leak it to the backend.
*/
#ifdef __KERNEL__
#define XENFB_WIDTH 800
--
1.5.3.3
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates
2008-05-21 8:37 [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Markus Armbruster
` (4 preceding siblings ...)
2008-05-21 8:40 ` [PATCH 5/5] xen pvfb: Dynamic mode support (screen resizing) Markus Armbruster
@ 2008-05-21 9:09 ` Jeremy Fitzhardinge
2008-05-21 9:54 ` Markus Armbruster
5 siblings, 1 reply; 9+ messages in thread
From: Jeremy Fitzhardinge @ 2008-05-21 9:09 UTC (permalink / raw)
To: Markus Armbruster
Cc: linux-kernel, virtualization, xen-devel, linux-fbdev-devel,
adaplas, linux-input, dmitry.torokhov, mingo, akpm, Pat Campbell
Markus Armbruster wrote:
> This is an update to the Linux part of the Xen PVFB. Linux Xen PVFB
> is a pair of Xen para-virtual frontend device drivers:
> drivers/video/xen-fbfront.c provides a framebuffer, and
> drivers/input/xen-kbdfront provides keyboard and mouse. Their
> backends run in dom0 user space.
>
> Parts in this patch series:
>
> 1. Enable Xen console by default in domU
> 2. Pointer z-axis (mouse wheel) support
> 3. Module aliases to support module autoloading
> 4. Zero unused bytes in events sent to backend
> 5. Dynamic mode support (screen resizing)
>
> To the best of my knowledge, these patches are independent. The last
> one needs a bit of trivial merging to apply without the first one. I
> tested only 1, 1+2, 1+2+3, 1+2+3+4, and the complete series. I'm
> happy to split this into different parts if that helps.
>
Thanks Markus,
This looks good. I'll stick it into my queue and feed it via Ingo when
I've given it a bit of a test.
Are we happy that the preferred console stuff is now the best solution?
Does it solve your installer issues?
J
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates
2008-05-21 9:09 ` [PATCH 0/5] xen pvfb: Para-virtual framebuffer, keyboard and pointer driver updates Jeremy Fitzhardinge
@ 2008-05-21 9:54 ` Markus Armbruster
0 siblings, 0 replies; 9+ messages in thread
From: Markus Armbruster @ 2008-05-21 9:54 UTC (permalink / raw)
To: Jeremy Fitzhardinge
Cc: xen-devel, linux-fbdev-devel, adaplas, dmitry.torokhov,
linux-kernel, virtualization, mingo, Pat Campbell, linux-input,
akpm
Jeremy Fitzhardinge <jeremy@goop.org> writes:
> Markus Armbruster wrote:
>> This is an update to the Linux part of the Xen PVFB. Linux Xen PVFB
>> is a pair of Xen para-virtual frontend device drivers:
>> drivers/video/xen-fbfront.c provides a framebuffer, and
>> drivers/input/xen-kbdfront provides keyboard and mouse. Their
>> backends run in dom0 user space.
>>
>> Parts in this patch series:
>>
>> 1. Enable Xen console by default in domU
>> 2. Pointer z-axis (mouse wheel) support
>> 3. Module aliases to support module autoloading
>> 4. Zero unused bytes in events sent to backend
>> 5. Dynamic mode support (screen resizing)
>>
>> To the best of my knowledge, these patches are independent. The last
>> one needs a bit of trivial merging to apply without the first one. I
>> tested only 1, 1+2, 1+2+3, 1+2+3+4, and the complete series. I'm
>> happy to split this into different parts if that helps.
>>
>
> Thanks Markus,
>
> This looks good. I'll stick it into my queue and feed it via Ingo
> when I've given it a bit of a test.
Thanks!
> Are we happy that the preferred console stuff is now the best
> solution? Does it solve your installer issues?
>
> J
Yes, the console stuff works nicely for me, and the installer is
happy.
Note that I went with the stupidest solution that could possibly work
there: have a global flag that gets set when the command line sets
consoles, and don't mess with the console then. Mark McLoughlin
suggested a somewhat less stupid way, namely to mark consoles selected
on the command line with a flag. Critical review invited!
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply [flat|nested] 9+ messages in thread