From: Pekka Enberg Date: Fri, 30 Sep 2011 15:53:48 +0000 (+0300) Subject: kvm tools, bios: Fix BIOS to kernel memory copy X-Git-Tag: next-20111025~3^2~6 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=15a0bb5ccae93c061c0345a6ce1fe6157628663c;p=karo-tx-linux.git kvm tools, bios: Fix BIOS to kernel memory copy This patch implements memcpy16() function that copies memory areas in 16-bit real mode and converts bios/int10.c to use it instead of relying on GCC struct memcpy to do the right thing. Acked-by: Cyrill Gorcunov Cc: Asias He Cc: Ingo Molnar Cc: Sasha Levin Signed-off-by: Pekka Enberg --- diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 3939c1164294..8387e2f9dbc1 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -219,6 +219,8 @@ BIOS_CFLAGS += -mregparm=3 bios.o: bios/bios.bin bios/bios-rom.h bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S + $(E) " CC bios/memcpy.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o $(E) " CC bios/e820.o" $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o $(E) " CC bios/int10.o" @@ -228,7 +230,7 @@ bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.l $(E) " CC bios/entry.o" $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o $(E) " LD " $@ - $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/entry.o bios/e820.o bios/int10.o bios/int15.o + $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o bios/bios.bin: bios/bios.bin.elf $(E) " OBJCOPY " $@ diff --git a/tools/kvm/bios/entry.S b/tools/kvm/bios/entry.S index 2ee21a9116d6..85056e9816c4 100644 --- a/tools/kvm/bios/entry.S +++ b/tools/kvm/bios/entry.S @@ -16,6 +16,7 @@ .macro SAVE_BIOSREGS pushl %fs pushl %es + pushl %ds pushl %edi pushl %esi pushl %ebp @@ -35,6 +36,7 @@ popl %ebp popl %esi popl %edi + popl %ds popl %es popl %fs .endm diff --git a/tools/kvm/bios/int10.c b/tools/kvm/bios/int10.c index 22da9fa0f928..6387ca8b15eb 100644 --- a/tools/kvm/bios/int10.c +++ b/tools/kvm/bios/int10.c @@ -2,6 +2,9 @@ #include "kvm/bios.h" #include "kvm/util.h" #include "kvm/vesa.h" + +#include "bios/memcpy.h" + #include #define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) @@ -99,18 +102,21 @@ static void vbe_get_mode(struct biosregs *args) static void vbe_get_info(struct biosregs *args) { - struct vesa_general_info *info = (struct vesa_general_info *) args->edi; + struct vesa_general_info *infop = (struct vesa_general_info *) args->edi; + struct vesa_general_info info; - *info = (struct vesa_general_info) { + info = (struct vesa_general_info) { .signature = VESA_MAGIC, .version = 0x102, - .vendor_string = &info->oem_string, + .vendor_string = &infop->oem_string, .capabilities = 0x10, - .video_mode_ptr = &info->modes, + .video_mode_ptr = &infop->modes, .total_memory = (4 * VESA_WIDTH * VESA_HEIGHT) / 0x10000, .oem_string = "KVM VESA", .modes = { 0x0112, 0xffff }, }; + + memcpy16(args->es, infop, args->ds, &info, sizeof(info)); } #define VBE_STATUS_OK 0x004F diff --git a/tools/kvm/bios/memcpy.c b/tools/kvm/bios/memcpy.c new file mode 100644 index 000000000000..40b9b65fa9e4 --- /dev/null +++ b/tools/kvm/bios/memcpy.c @@ -0,0 +1,23 @@ +#include "bios/memcpy.h" + +/* + * Copy memory area in 16-bit real mode. + */ +void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len) +{ + __asm__ __volatile__ ( + "pushw %%ds \n" + "pushw %%es \n" + "movw %[src_seg], %%ds \n" + "movw %[dst_seg], %%es \n" + "rep movsb %%ds:(%%si), %%es:(%%di) \n" + "popw %%es \n" + "popw %%ds \n" + : + : "S"(src), + "D"(dst), + "c"(len), + [src_seg] "r"(src_seg), + [dst_seg] "r"(dst_seg) + : "cc", "memory"); +} diff --git a/tools/kvm/include/bios/memcpy.h b/tools/kvm/include/bios/memcpy.h new file mode 100644 index 000000000000..e0210449e80f --- /dev/null +++ b/tools/kvm/include/bios/memcpy.h @@ -0,0 +1,9 @@ +#ifndef KVM_BIOS_MEMCPY_H +#define KVM_BIOS_MEMCPY_H + +#include +#include + +void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len); + +#endif /* KVM_BIOS_MEMCPY_H */ diff --git a/tools/kvm/include/kvm/bios.h b/tools/kvm/include/kvm/bios.h index 469576ecaaa4..39cc972e9cc3 100644 --- a/tools/kvm/include/kvm/bios.h +++ b/tools/kvm/include/kvm/bios.h @@ -69,6 +69,7 @@ struct biosregs { u32 ebp; u32 esi; u32 edi; + u32 ds; u32 es; u32 fs; u32 eip;