[Core Change] Port HDD locking from XQEMU 1.x

This commit is contained in:
Matt Borgerson 2018-06-26 14:11:23 -07:00
parent 68b54a7cc9
commit 7ea10931d1
7 changed files with 54 additions and 1 deletions

View File

@ -776,6 +776,10 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "copy-on-read",
.type = QEMU_OPT_BOOL,
.help = "copy read data from backing file into image file",
},{
.name = "locked",
.type = QEMU_OPT_BOOL,
.help = "emulate a security locked drive",
},
{ /* end of list */ }
@ -804,6 +808,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
const char *deprecated[] = {
"serial", "trans", "secs", "heads", "cyls", "addr"
};
bool locked;
/* Change legacy command line options into QMP ones */
static const struct {
@ -1021,6 +1026,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
goto fail;
}
/* Locked */
locked = qemu_opt_get_bool(legacy_opts, "locked", false);
/* Serial number */
serial = qemu_opt_get(legacy_opts, "serial");
@ -1114,6 +1122,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
dinfo->unit = unit_id;
dinfo->devaddr = devaddr;
dinfo->serial = g_strdup(serial);
dinfo->locked = locked;
blk_set_legacy_dinfo(blk, dinfo);

View File

@ -15,6 +15,14 @@
#include "qapi/qapi-types-block.h"
#include "qemu/error-report.h"
void blkconf_locked(BlockConf *conf, bool *locked)
{
DriveInfo *dinfo;
dinfo = blk_legacy_dinfo(conf->blk);
*locked = dinfo->locked;
}
void blkconf_serial(BlockConf *conf, char **serial)
{
DriveInfo *dinfo;

View File

@ -76,6 +76,7 @@ static const char *IDE_DMA_CMD_str(enum ide_dma_cmd enval)
}
static void ide_dummy_transfer_stop(IDEState *s);
static void ide_security_cmd(IDEState *s);
static void padstr(char *str, const char *src, int len)
{
@ -213,6 +214,13 @@ static void ide_identify(IDEState *s)
put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */
}
/* 2: locked, 1: security enabled, 0: security supported */
if (dev && dev->locked) {
put_le16(p + 128, (1 << 2) | (1 << 1) | 1);
} else {
put_le16(p + 128, (1 << 0));
}
ide_identify_size(s);
s->identify_set = 1;
@ -1712,6 +1720,15 @@ static bool cmd_packet(IDEState *s, uint8_t cmd)
return false;
}
static bool cmd_security_unlock(IDEState *s, uint8_t cmd)
{
s->error = 0;
s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 512,
ide_security_cmd);
return false;
}
/*** CF-ATA commands ***/
@ -2046,6 +2063,7 @@ static const struct {
[IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
[CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
[WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
[WIN_SECURITY_UNLOCK] = { cmd_security_unlock, ALL_OK | SET_DSC },
};
static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
@ -2264,7 +2282,8 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
static bool ide_is_pio_out(IDEState *s)
{
if (s->end_transfer_func == ide_sector_write ||
s->end_transfer_func == ide_atapi_cmd) {
s->end_transfer_func == ide_atapi_cmd ||
s->end_transfer_func == ide_security_cmd) {
return false;
} else if (s->end_transfer_func == ide_sector_read ||
s->end_transfer_func == ide_transfer_stop ||
@ -2404,6 +2423,17 @@ static void ide_dummy_transfer_stop(IDEState *s)
s->io_buffer[3] = 0xff;
}
static void ide_security_cmd(IDEState *s)
{
/* XXX: Actually verify the password... */
put_le16((uint16_t *)s->identify_data + 128, (1 << 1) | 1);
s->error = 0;
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
}
void ide_bus_reset(IDEBus *bus)
{
bus->unit = 0;
@ -2724,6 +2754,7 @@ static EndTransferFunc* transfer_end_table[] = {
ide_atapi_cmd_reply_end,
ide_atapi_cmd,
ide_dummy_transfer_stop,
ide_security_cmd,
};
static int transfer_end_table_idx(EndTransferFunc *fn)

View File

@ -188,6 +188,8 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
return;
}
blkconf_locked(&dev->conf, &dev->locked);
blkconf_serial(&dev->conf, &dev->serial);
if (kind != IDE_CD) {
if (!blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255,

View File

@ -72,6 +72,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
/* Configuration helpers */
void blkconf_locked(BlockConf *conf, bool *locked);
void blkconf_serial(BlockConf *conf, char **serial);
bool blkconf_geometry(BlockConf *conf, int *trans,
unsigned cyls_max, unsigned heads_max, unsigned secs_max,

View File

@ -506,6 +506,7 @@ struct IDEDevice {
char *version;
char *serial;
char *model;
bool locked;
uint64_t wwn;
/*
* 0x0000 - rotation rate not reported

View File

@ -38,6 +38,7 @@ struct DriveInfo {
int cyls, heads, secs, trans;
QemuOpts *opts;
char *serial;
bool locked;
QTAILQ_ENTRY(DriveInfo) next;
};