Commit 472f95f32d5aa07eda96a6b2578b85d7b27c5110
Committed by
Greg Ungerer
1 parent
015feacf93
Exists in
smarct4x-processor-sdk-04.01.00.06
and in
1 other branch
binfmt_flat: allow compressed flat binary format to work on MMU systems
Let's take the simple and obvious approach by decompressing the binary into a kernel buffer and then copying it to user space. Those who are looking for top performance on an MMU system are unlikely to choose this executable format anyway. Signed-off-by: Nicolas Pitre <nico@linaro.org> Reviewed-by: Greg Ungerer <gerg@linux-m68k.org> Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
Showing 1 changed file with 42 additions and 2 deletions Side-by-side Diff
fs/binfmt_flat.c
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | #include <linux/init.h> |
35 | 35 | #include <linux/flat.h> |
36 | 36 | #include <linux/uaccess.h> |
37 | +#include <linux/vmalloc.h> | |
37 | 38 | |
38 | 39 | #include <asm/byteorder.h> |
39 | 40 | #include <asm/unaligned.h> |
... | ... | @@ -628,6 +629,7 @@ |
628 | 629 | * load it all in and treat it like a RAM load from now on |
629 | 630 | */ |
630 | 631 | if (flags & FLAT_FLAG_GZIP) { |
632 | +#ifndef CONFIG_MMU | |
631 | 633 | result = decompress_exec(bprm, sizeof(struct flat_hdr), |
632 | 634 | (((char *)textpos) + sizeof(struct flat_hdr)), |
633 | 635 | (text_len + full_data |
634 | 636 | |
635 | 637 | |
636 | 638 | |
... | ... | @@ -635,13 +637,51 @@ |
635 | 637 | 0); |
636 | 638 | memmove((void *) datapos, (void *) realdatastart, |
637 | 639 | full_data); |
640 | +#else | |
641 | + /* | |
642 | + * This is used on MMU systems mainly for testing. | |
643 | + * Let's use a kernel buffer to simplify things. | |
644 | + */ | |
645 | + long unz_text_len = text_len - sizeof(struct flat_hdr); | |
646 | + long unz_len = unz_text_len + full_data; | |
647 | + char *unz_data = vmalloc(unz_len); | |
648 | + if (!unz_data) { | |
649 | + result = -ENOMEM; | |
650 | + } else { | |
651 | + result = decompress_exec(bprm, sizeof(struct flat_hdr), | |
652 | + unz_data, unz_len, 0); | |
653 | + if (result == 0 && | |
654 | + (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr), | |
655 | + unz_data, unz_text_len) || | |
656 | + copy_to_user((void __user *)datapos, | |
657 | + unz_data + unz_text_len, full_data))) | |
658 | + result = -EFAULT; | |
659 | + vfree(unz_data); | |
660 | + } | |
661 | +#endif | |
638 | 662 | } else if (flags & FLAT_FLAG_GZDATA) { |
639 | 663 | result = read_code(bprm->file, textpos, 0, text_len); |
640 | - if (!IS_ERR_VALUE(result)) | |
664 | + if (!IS_ERR_VALUE(result)) { | |
665 | +#ifndef CONFIG_MMU | |
641 | 666 | result = decompress_exec(bprm, text_len, (char *) datapos, |
642 | 667 | full_data, 0); |
643 | - } else | |
668 | +#else | |
669 | + char *unz_data = vmalloc(full_data); | |
670 | + if (!unz_data) { | |
671 | + result = -ENOMEM; | |
672 | + } else { | |
673 | + result = decompress_exec(bprm, text_len, | |
674 | + unz_data, full_data, 0); | |
675 | + if (result == 0 && | |
676 | + copy_to_user((void __user *)datapos, | |
677 | + unz_data, full_data)) | |
678 | + result = -EFAULT; | |
679 | + vfree(unz_data); | |
680 | + } | |
644 | 681 | #endif |
682 | + } | |
683 | + } else | |
684 | +#endif /* CONFIG_BINFMT_ZFLAT */ | |
645 | 685 | { |
646 | 686 | result = read_code(bprm->file, textpos, 0, text_len); |
647 | 687 | if (!IS_ERR_VALUE(result)) |