Make uboot_devdesc properly alias disk_devdesc, so that parsing the u-boot

loaderdev variable works correctly.

The uboot_devdesc struct is variously cast back and forth between
uboot_devdesc and disk_devdesc as pointers are handed off through various
opaque interfaces.  uboot_devdesc attempted to mimic the layout of
disk_devdesc by having a devdesc struct, followed by a union of some
device-specific stuff that included a struct that contains the same fields
as a disk_devdesc.  However, one of those fields inside the struct is 64-bit
which causes the entire union to be 64-bit aligned -- 32 bits of padding
is added between the struct devdesc and the union, so the whole mess ends
up NOT properly mimicking a disk_devdesc after all.  (In disk_devdesc there
is also 32 bits of padding, but it shows up immediately before the d_offset
field, rather than before the whole collection of d_* fields.)

This fixes the problem by using an anonymous union to overlay the devdesc
field uboot network devices need with the disk_devdesc that uboot storage
devices need.  This is a different solution than the one contributed with
the PR (so if anything goes wrong, the blame goes to me), but 95% of the
credit for this fix goes to Pawel Worach and Manuel Stuhn who analyzed the
problem and proposed a fix.

PR:		233097
This commit is contained in:
Ian Lepore 2019-02-18 04:44:52 +00:00
parent c0347e182c
commit 5a75fc4b11
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344247
2 changed files with 13 additions and 17 deletions

View file

@ -310,13 +310,13 @@ print_disk_probe_info()
char slice[32];
char partition[32];
if (currdev.d_disk.slice > 0)
sprintf(slice, "%d", currdev.d_disk.slice);
if (currdev.d_disk.d_slice > 0)
sprintf(slice, "%d", currdev.d_disk.d_slice);
else
strcpy(slice, "<auto>");
if (currdev.d_disk.partition >= 0)
sprintf(partition, "%d", currdev.d_disk.partition);
if (currdev.d_disk.d_partition >= 0)
sprintf(partition, "%d", currdev.d_disk.d_partition);
else
strcpy(partition, "<auto>");
@ -332,8 +332,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice,
int open_result, unit;
struct open_file f;
currdev.d_disk.slice = load_slice;
currdev.d_disk.partition = load_partition;
currdev.d_disk.d_slice = load_slice;
currdev.d_disk.d_partition = load_partition;
f.f_devdata = &currdev;
open_result = -1;

View file

@ -27,18 +27,14 @@
* $FreeBSD$
*/
struct uboot_devdesc {
struct devdesc dd; /* Must be first. */
union {
struct {
int slice;
int partition;
off_t offset;
} disk;
} d_kind;
};
#include <disk.h>
#define d_disk d_kind.disk
struct uboot_devdesc {
union {
struct devdesc dd;
struct disk_devdesc d_disk;
};
};
/*
* Default network packet alignment in memory. On arm arches packets must be