[tip:tools/kvm] kvm tools, bios: Make sure IRQ handlers segment is properly set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  2034e060f55432ac13b2ea77b8d4cd107bdba98a
Gitweb:     http://git.kernel.org/tip/2034e060f55432ac13b2ea77b8d4cd107bdba98a
Author:     Cyrill Gorcunov <gorcunov@xxxxxxxxx>
AuthorDate: Mon, 11 Jul 2011 01:52:53 +0400
Committer:  Pekka Enberg <penberg@xxxxxxxxxx>
CommitDate: Tue, 12 Jul 2011 17:40:14 +0300

kvm tools, bios: Make sure IRQ handlers segment is properly set

The mini bios is copied at predefined place and should have
constant segment address.

Without this patch cs value varies depending on which code
is compiled and how big bios is, it's kinda flowing error
which is not triggered yet by a pure luck.

Signed-off-by: Cyrill Gorcunov <gorcunov@xxxxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx>
---
 tools/kvm/bios.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/tools/kvm/bios.c b/tools/kvm/bios.c
index 94e914c..6aefd1b 100644
--- a/tools/kvm/bios.c
+++ b/tools/kvm/bios.c
@@ -16,14 +16,14 @@ struct irq_handler {
 	size_t			size;
 };
 
-#define BIOS_IRQ_ADDR(name) (MB_BIOS_BEGIN + BIOS_OFFSET__##name)
-#define BIOS_IRQ_FUNC(name) ((char *)&bios_rom[BIOS_OFFSET__##name])
-#define BIOS_IRQ_SIZE(name) (BIOS_ENTRY_SIZE(BIOS_OFFSET__##name))
+#define BIOS_IRQ_PA_ADDR(name)	(MB_BIOS_BEGIN + BIOS_OFFSET__##name)
+#define BIOS_IRQ_FUNC(name)	((char *)&bios_rom[BIOS_OFFSET__##name])
+#define BIOS_IRQ_SIZE(name)	(BIOS_ENTRY_SIZE(BIOS_OFFSET__##name))
 
 #define DEFINE_BIOS_IRQ_HANDLER(_irq, _handler)			\
 	{							\
 		.irq		= _irq,				\
-		.address	= BIOS_IRQ_ADDR(_handler),	\
+		.address	= BIOS_IRQ_PA_ADDR(_handler),	\
 		.handler	= BIOS_IRQ_FUNC(_handler),	\
 		.size		= BIOS_IRQ_SIZE(_handler),	\
 	}
@@ -42,10 +42,12 @@ static void setup_irq_handler(struct kvm *kvm, struct irq_handler *handler)
 	memcpy(p, handler->handler, handler->size);
 
 	intr_desc = (struct real_intr_desc) {
-		.segment	= REAL_SEGMENT(handler->address),
-		.offset		= REAL_OFFSET(handler->address),
+		.segment	= REAL_SEGMENT(MB_BIOS_BEGIN),
+		.offset		= handler->address - MB_BIOS_BEGIN,
 	};
 
+	DIE_IF((handler->address - MB_BIOS_BEGIN) > (unsigned long)0xffff);
+
 	interrupt_table__set(&kvm->interrupt_table, &intr_desc, handler->irq);
 }
 
@@ -139,10 +141,10 @@ void setup_bios(struct kvm *kvm)
 	 * Setup a *fake* real mode vector table, it has only
 	 * one real hadler which does just iret
 	 */
-	address = BIOS_IRQ_ADDR(bios_intfake);
+	address = BIOS_IRQ_PA_ADDR(bios_intfake);
 	intr_desc = (struct real_intr_desc) {
-		.segment	= REAL_SEGMENT(address),
-		.offset		= REAL_OFFSET(address),
+		.segment	= REAL_SEGMENT(MB_BIOS_BEGIN),
+		.offset		= address - MB_BIOS_BEGIN,
 	};
 	interrupt_table__setup(&kvm->interrupt_table, &intr_desc);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux